在一些简单的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; }先总结这两个坑~大家在开发中遇到什么问题也可以在评论中指出,多交流,多学习才有助于提高嘛~