关于实现在canvas里使用鼠标拖动图层进行旋转的思路

判断鼠标移动的方向

已知鼠标移动前后2个点的坐标和图层的中心点坐标,我们可以根据坐标点来确定2个向量,分别为:

let center = [cx, cy] // 图层中心点
let a = [x1, y1] // 鼠标点击的点
let b = [x2, y2] // 鼠标移动的点

// 向量1
let AO = [(x1 - cx), (y1 - cy)]

// 向量2
let BO = [(x2 - cx), (y2 - cy)]

利用平面向量的叉乘

a = (x1, y1)
b = (x2, y2)

a * b = x1*y2 - x2*y1

若结果为 —— 正:b在a的逆时针方向;负:b在a的顺时针方向;0:a与b共线

注:两向量之间的夹角以小于180度计算

 

向量的夹角计算 

空间向量的夹角公式:cosθ = (a*b) / (|a| * |b|)

a=(x1,y1,z1),b=(x2,y2,z2)。

a*b = x1x2 + y1y2 + z1z2

|a|=√(x1^2 + y1^2 + z1^2),|b|=√(x2^2 + y2^2 + z2^2)

转化为弧度值:θ = arccos( (a*b) / (|a| * |b|) )

平面向量的可以类推

关键代码

点击旋转按钮

    // 点击旋转图标
    oRotateStart(e, id) {
      // 找到点击的那个图片对象,激活可旋转的标识
      this.items[this.index].rMoveabled = true
      
      // 第一次点击的鼠标坐标
      this.mouse = {
        x: (e.pageX - this.toucheWrap.left) * this.sDpi,
        y: (e.pageY - this.toucheWrap.top) * this.sDpi
      }
    }

计算2个向量之间的夹角弧度值

    // 求向量之间的夹角(0-180),返回值是弧度
    // a,b是数组
    vectorAngle(a, b) {
      let mX = Math.sqrt(a.reduce((acc, n) => acc + Math.pow(n, 2), 0));
      let mY = Math.sqrt(b.reduce((acc, n) => acc + Math.pow(n, 2), 0));
      return Math.acos(a.reduce((acc, n, i) => acc + n * b[i], 0) / (mX * mY));
    },

移动旋转按钮

    // 移动旋转图标
    oRotateMove(e) {

      let { items, index } = this;

      if (!items[index].rMoveabled) {
        return
      }

      // 图层中心坐标
      let center = {
        x: items[index].x,
        y: items[index].y
      }

      // 当前鼠标坐标
      let move = {
        x: (e.pageX - this.toucheWrap.left) * this.sDpi,
        y: (e.pageY - this.toucheWrap.top) * this.sDpi
      }
      

      // 2个向量
      let a = [this.mouse.x - center.x, this.mouse.y - center.y]
      let b = [move.x - center.x, move.y - center.y]

      // 向量的叉乘(正:b在a的逆时针方向;负:b在a的顺时针方向;0:a与b共线)
      let xj = a[0]*b[1] - b[0]*a[1]

      // 夹角
      let deg = this.vectorAngle(a, b) / (Math.PI / 180)

      // 判断是顺时针还是逆时针
      if(xj > 0) {
        console.log('逆时针')    
      } 
      else if(xj < 0) {
        deg = -deg
        console.log('顺时针')
      } else {
        console.log('共线')
        return
      }

      // 更新赋值
      this.mouse = move

      // 旋转角度赋值
      items[index].rotate += deg *(0.05 / this.sDpi)
    

      this.items = JSON.parse(JSON.stringify([...items]));
    }

你可能感兴趣的:(计算机外设,javascript,前端)