国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Threejs進(jìn)階之十:讓模型移動(dòng)到鼠標(biāo)點(diǎn)擊的指定位置

這篇具有很好參考價(jià)值的文章主要介紹了Threejs進(jìn)階之十:讓模型移動(dòng)到鼠標(biāo)點(diǎn)擊的指定位置。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

上一節(jié)中我們實(shí)現(xiàn)了物體沿指定軌跡移動(dòng)的動(dòng)畫效果,這一節(jié)我們來(lái)實(shí)現(xiàn)讓模型移動(dòng)到鼠標(biāo)點(diǎn)擊的制定位置的動(dòng)畫效果。
先看下實(shí)現(xiàn)后的最終效果
Threejs進(jìn)階之十:讓模型移動(dòng)到鼠標(biāo)點(diǎn)擊的指定位置
要實(shí)現(xiàn)上面的動(dòng)畫效果,我們需要通過(guò)以下步驟來(lái)實(shí)現(xiàn)

第一步,監(jiān)聽鼠標(biāo)事件

我們需要監(jiān)聽鼠標(biāo)的點(diǎn)擊事件,獲取鼠標(biāo)點(diǎn)擊點(diǎn)相對(duì)瀏覽器可視區(qū)域左上角的距離,通過(guò)監(jiān)聽“pointerdown”事件,獲取點(diǎn)擊點(diǎn)的clientX和clientY;clientX/Y獲取到的是點(diǎn)擊點(diǎn)相對(duì)瀏覽器可視區(qū)域左上角距離。

renderer.domElement.addEventListener('pointerdown',function(event) {
   
    event = event || window.event
    initPos = {
   
      x:event.clientX,
      y:event.clientY
    } 
})

第二步:獲取鼠標(biāo)點(diǎn)擊點(diǎn)的屏幕坐標(biāo)

通過(guò)Element.getBoundingClientRect()中的 top屬性獲取元素上邊距離頁(yè)面上邊的距離,
通過(guò)left屬性獲取元素左邊距離頁(yè)面左邊的距離,
通過(guò)計(jì)算 clientX 與domElement.getBoundingClientRect().left的差值,獲取x點(diǎn)坐標(biāo);
通過(guò)計(jì)算 clientY 與domElement.getBoundingClientRect().top的差值,獲取y點(diǎn)坐標(biāo);

  let x = event.clientX - renderer.domElement.getBoundingClientRect().left
  let y = event.clientY - renderer.domElement.getBoundingClientRect().top

第三步:獲取畫布的寬度和高度并歸一化

通過(guò)坐標(biāo)轉(zhuǎn)換,將x和y的坐標(biāo)歸一化,即將屏幕坐標(biāo)轉(zhuǎn)換為threejs的世界坐標(biāo)

 let canvasWidth = renderer.domElement.clientWidth 
 // clientWidth 返回元素的可視寬度,包括內(nèi)邊距,但不包括邊框、滾動(dòng)條或外邊距,以像素計(jì)
 // canvas畫布高度
 // clientHeight 返回元素的可視高度,包括內(nèi)邊距,但不包括邊框、滾動(dòng)條或外邊距,以像素計(jì)。
 let canvasHeight = renderer.domElement.clientHeight
 // offsetHeight 屬性返回元素的可視高度(以像素為單位),包括內(nèi)邊距、邊框和滾動(dòng)條,但不包括外邊距。
 // offsetWidth 屬性返回元素的可視寬度(以像素為單位),包括內(nèi)邊距、邊框和滾動(dòng)條,但不包括外邊距。
 // 坐標(biāo)轉(zhuǎn)換(歸一化的值) 
 const sx = -1 + (x / canvasWidth) * 2 
 const sy = 1 - (y / canvasHeight) * 2

第四步:創(chuàng)建光線投射器,并通過(guò)攝像機(jī)和鼠標(biāo)點(diǎn)擊的位置更新射線

// 光線投射器
const rayCaster = new THREE.Raycaster()
// 通過(guò)攝像機(jī)和鼠標(biāo)位置更新射線
rayCaster.setFromCamera(new THREE.Vector2(sx,sy),camera) 

第五步:通過(guò)rayCaster.intersectObjects()方法檢測(cè)射線與物體的交集

這里我們是點(diǎn)擊在水面上,因此,將water作為參數(shù)傳入,檢測(cè)射線與水面的交集,將結(jié)果返回給intersects

const intersects = rayCaster.intersectObjects([water]) 

第六步:判斷射線與物體是否有交集,如果有,獲取坐標(biāo)并處理邏輯

通過(guò)if語(yǔ)句判斷intersects.length是否大于零,如果大于零,說(shuō)明有交集,在if語(yǔ)句中處理如下邏輯:
1、通過(guò)intersects[0].point獲取鼠標(biāo)點(diǎn)擊時(shí)射線與water相交點(diǎn)的坐標(biāo)(新位置)存入newPos變量,
2、通過(guò)yacht.position.clone() 獲取模型當(dāng)前位置坐標(biāo)(老位置)存入originPos變量
3、通過(guò)camera.position.clone() 獲取相機(jī)當(dāng)前位置坐標(biāo)(老位置)存入cameraOriginPos 變量
4、通過(guò)向量減法獲取鼠標(biāo)點(diǎn)擊點(diǎn)的向量和向量長(zhǎng)度 存入vector 變量
5、創(chuàng)建一個(gè)四元數(shù)對(duì)象,通過(guò).setFromUnitVectors將該四元數(shù)設(shè)置為從方向向量new THREE.Vector3(0,0,-1)旋轉(zhuǎn)到方向向量 vector 單位向量 所需的旋轉(zhuǎn)角度。
6、創(chuàng)建一個(gè)Threejs的Clock()對(duì)象
7、創(chuàng)建一個(gè)speed常量為100,設(shè)置移動(dòng)速度
8、通過(guò)setInterval()方法啟動(dòng)定時(shí)器,通過(guò)speed和clock.getElapsedTime()失去時(shí)間的乘積,得到每次時(shí)間間隔移動(dòng)的長(zhǎng)度
9、通過(guò)每次時(shí)間間隔移動(dòng)的長(zhǎng)度除以向量總長(zhǎng)度,獲取每次間隔移動(dòng)的比值,將該比值與重點(diǎn)向量相乘,得到每次間隔移動(dòng)的向量坐標(biāo)
10、將上面得到的每次間隔移動(dòng)的向量坐標(biāo)與模型原始位置向量坐標(biāo)相加,得到模型每次時(shí)間間隔移動(dòng)的重點(diǎn)向量坐標(biāo)
11、將每次間隔移動(dòng)的終點(diǎn)坐標(biāo)復(fù)制給模型的position屬性
12、將每次間隔移動(dòng)的向量坐標(biāo)與相機(jī)原始坐標(biāo)相加得到每次時(shí)間間隔移動(dòng)的終點(diǎn)坐標(biāo),并將給坐標(biāo)復(fù)制給相機(jī)的position屬性
13、將每次時(shí)間間隔的終點(diǎn)坐標(biāo)movePos復(fù)制給控制器的target屬性,使其始終朝向movePos位置
14、執(zhí)行完成后清除定時(shí)器文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-484904.html

到了這里,關(guān)于Threejs進(jìn)階之十:讓模型移動(dòng)到鼠標(biāo)點(diǎn)擊的指定位置的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包