threejs中PC與手機操作的一些總結
阿新 • • 發佈:2019-02-07
在一些簡單的webgl專案中,我們經常碰到的操作就是兩指縮放,滑動旋轉,這兩種操作經常要進行PC和手機的適配,這裡總結一下我踩了的一些小小的坑吧~
1.手機與PC獲取螢幕對應點選位置的方法不同:
手機是觸控獲取位置,PC是點選滑鼠獲取位置兩者的程式碼略有不同,這與threejs構建的3D世界沒有關係,僅僅是將點選/觸控的位置轉換為窗體位置罷了,我在下面總結一下:
PC點選位置:
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = - ( event.clientY手機觸控位置:/ window.innerHeight ) * 2 + 1;
mouse.x = (event.touches[ 0 ].pageX / window.innerWidth) * 2 -1; mouse.y = -(event.touches[ 0 ].pageY / window.innerHeight) *2 +1;2.手機和電腦移動方式的不同:
大家都知道,滑鼠和觸控都分為點選/按下、移動/滑動、擡起這三個階段,這裡就有一個小坑了!點選擡起手機電腦的操作方式都是一樣的,但是移動這塊,電腦中滑鼠點選之後到下次點選滑鼠的移動會不斷觸發onDocumentMouseMove方法,也就是說滑鼠不可能點選(0,0)位置,突然下一次移動到(10,10)位置,因為期間還有一個滑鼠移動事件不斷地觸發。而手機則不同,這次你點選了(0,0)下次點選(10,10)就在正常不過了,我們也不需要手指在螢幕上進行滑動。那是這些有什麼用呢?
這裡就不得不提到我最近做的一個小的程式,用threejs實現3D地球展示,當手指滑動/滑鼠拖動時旋轉地球,我用的方法是,每次移動獲得x/y的值,減去上次移動的值,得到這次滑動的偏移量然後旋轉地球,這個效果在PC上沒有任何問題,可是到了手機上,每次滑動完螢幕,下次滑動時地球又嗖的一下跳回去了,然後我想了半天才發現是這個原因,手機在滑動完成之後,下一次滑動點選位置不同,x/y的差值太大了,所以需要在每次點選時就先儲存到上次移動的值~下面是程式碼
function onDocumentMouseDown( event ) { is_click = true; is_move = false先總結這兩個坑~大家在開發中遇到什麼問題也可以在評論中指出,多交流,多學習才有助於提高嘛~; //適配手機 if(event.touches){ mouse.x = (event.touches[ 0 ].pageX / window.innerWidth) * 2 -1; mouse.y = -(event.touches[ 0 ].pageY / window.innerHeight) *2 +1; pre_mouse.x = mouse.x; pre_mouse.y = mouse.y; } } function onDocumentMouseMove( event ) { is_move = true; mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; if(is_click){ if(earth && earth_cloud){ earth.rotation.set(earth.rotation.x - (mouse.y - pre_mouse.y), earth.rotation.y + (mouse.x - pre_mouse.x), earth.rotation.z); earth_cloud.rotation.set(earth_cloud.rotation.x - (mouse.y - pre_mouse.y), earth_cloud.rotation.y + (mouse.x - pre_mouse.x), earth_cloud.rotation.z); } } pre_mouse.x = mouse.x; pre_mouse.y = mouse.y; } function onDocumentTouchMove() { is_move = true; mouse.x = (event.touches[ 0 ].pageX / window.innerWidth) * 2 -1; mouse.y = -(event.touches[ 0 ].pageY / window.innerHeight) *2 +1; if(is_click){ if(earth && earth_cloud){ earth.rotation.set(earth.rotation.x - (mouse.y - pre_mouse.y), earth.rotation.y + (mouse.x - pre_mouse.x), earth.rotation.z); earth_cloud.rotation.set(earth_cloud.rotation.x - (mouse.y - pre_mouse.y), earth_cloud.rotation.y + (mouse.x - pre_mouse.x), earth_cloud.rotation.z); } } pre_mouse.x = mouse.x; pre_mouse.y = mouse.y; }