Three.js移动端双指触屏控制旋转和缩放

  1. 需求

在移动端通过双指来控制物体的选择和缩放。旋转通过双指旋转操作,而缩放通过双指距离实现。实现平台是小程序基于three.js的AR版。

  1. 实现思路

  1. 旋转:两个手指产生的两个点可以算出一个向量,那么我就通过程序前后两帧计算两个向量之间的夹角来判断旋转的角度信息。这里我通过Vector3.angleTo()去求得角度,这个是没有夹角方向的,所以后面我将两个向量进行叉乘,获得夹角的方向。

  1. 缩放:通过双指距离判断缩放的比例。

  1. 代码

1.小程序注册触碰的事件 .wxml文件

<canvas
        bindtouchstart="bindtouchStart"
        bindtouchmove="bindtouchMove"    
</canvas>

2.脚本上实现逻辑 .js文件

bindtouchStart(event)
  {
    //console.log("touchStart");
    if(event.touches.length===2)
    {
        //旋转的开始触碰参数,获取刚触碰时的两个点信息
        var client1X = event.touches[0].clientX;
        var client1Y = event.touches[0].clientY;
        this.start1X = client1X;
        this.start1Y = client1Y;
        var client2X = event.touches[1].clientX;
        var client2Y = event.touches[1].clientY;
        this.start2X = client2X;
        this.start2Y = client2Y;
        this.touchStartEvent = event.touches;

        //缩放的开始触碰参数
        var xMove = event.touches[1].clientX-event.touches[0].clientX;
        var yMove = event.touches[1].clientY-event.touches[0].clientY;
        //初始时双指距离.注:distance是全局变量,需要在前面声明出来,我没有贴这代码
        distance = Math.sqrt(xMove*xMove+yMove*yMove);
    }
  },
  bindtouchMove(event)
  {
    if(event.touches.length===2)
    {
        //旋转
        //获取刚开始触碰时生成的向量
        var v1=new THREE.Vector3(this.start2X-this.start1X,this.start2Y-this.start1Y,0);
        //获取实时的两点信息
        var client1X = event.touches[0].clientX;
        var client1Y = event.touches[0].clientY;
        var client2X = event.touches[1].clientX;
        var client2Y = event.touches[1].clientY;
        //获取实时两点生成的向量
        var v2 = new THREE.Vector3(client2X-client1X,client2Y-client1Y,0);
        //获取两个向量产生的夹角
        var angle = v2.angleTo(v1);
        //由于这个夹角只能是正的,所以要确定夹角的方向。使用叉乘来判断
        v1.cross(v2);
        if(v1.z>0){
            //角度是逆时针方向的,朝向屏幕外
            angle=-angle;
        }else{
           //角度是顺时针方向的

        }
        //传递给下一帧
        this.start1X = client1X;
        this.start1Y = client1Y;
        this.start2X = client2X;
        this.start2Y = client2Y;
        //执行旋转操作.获得角度信息后可自由发挥
        cameraBusiness.rotaClick(angle);

        //缩放
        var xMove = event.touches[1].clientX-event.touches[0].clientX;
        var yMove = event.touches[1].clientY-event.touches[0].clientY;
        var curDistance = Math.sqrt(xMove*xMove+yMove*yMove);
        var distanceDiff = curDistance-distance;
        //执行缩放操作.获得距离信息后可自由发挥
        cameraBusiness.scaleClick(distanceDiff);
        distance = curDistance;
    }
  },