js计算滑动/旋转角度,滑动时长和滑动距离

651 阅读3分钟

计算滑动角度

touchend(e){
    // console.log(e)
    var that = this,

    scroll_top = that.data.scroll_top,
    
    down = that.data.down,    

    startX = that.data.startX,//开始X坐标
    
    startY = that.data.startY,//开始Y坐标
    
    touchMoveX = e.changedTouches[0].clientX,//滑动变化坐标
    
    touchMoveY = e.changedTouches[0].clientY,//滑动变化坐标
        
    //获取滑动角度
    
    angle = that.angle({ X: startX, Y: startY }, { X: touchMoveX, Y: touchMoveY });

}
/**
  
  * 计算滑动角度
  
  * @param {Object} start 起点坐标
  
  * @param {Object} end 终点坐标
  
  */
    
  angle: function (start, end) {
    
    var _X = end.X - start.X,
    
    _Y = end.Y - start.Y
    
    //返回角度 /Math.atan()返回数字的反正切值
    // console.log(360 * Math.atan(_Y / _X) / (2 * Math.PI))
    return 360 * Math.atan(_Y / _X) / (2 * Math.PI);
  },

js计算两点之间角度

通过手动旋转的方式,实现组件的360度无缝旋转。图示是实现结果的几个截图:

image.png

顺时针转到 66deg

image.png

逆时针转到 315deg

image.png

转到 180deg

image.png

实现分析

如图所示,实现难点在于计算出两点间连线的倾斜角 angle

image.png

这里需要掌握的几个知识点:

3.1 获取转动的角度

使用 Math.atan2() 函数可以非常高效的实现之,它是返回点与原点之间的倾斜角,如图所示,如果想计算出点 (x1,y1) 与 原点 (cx,cy) 与X轴的角度,只需要执行:

Math.atan2(y1 - cy, x1 - cx)
需要注意的是,它的取值范围是[-PI, PI]。  
当 (x1, y1) 在第一象限, 0 < θ < PI/2

当 (x1, y1) 在第二象限 PI/2 < θ≤PI

当 (x1, y1) 在第三象限, -PI < θ < -PI/2

当 (x1, y1) 在第四象限, -PI/2 < θ < 0

3.2 角度与弧度之间的转换

角度 = 弧度 * 180 / Math.PI;
弧度= 角度 * Math.PI / 180;

3.3 组件中心点位置计算

使用getBoundingClientRect() 的方法可以获取出容器的位置信息,用当前位置减去宽/高的一半,即可获取中心点位置。

image.png

//中心点 
cx = x + width / 2; 
cy = y + height / 2;

最终代码

/**
 * 获得旋转夹角
 * @param {*} x1 旋转点1
 * @param {*} y1 
 * @param {*} x2 旋转点2
 * @param {*} y2 
 */
function getAngle(x1, y1, x2, y2) {
  // 获取组件的位置信息
  let rect = document.getElementsByClassName('active-ele')[0].getBoundingClientRect();
  let {
    x,
    y,
    width,
    height
  } = rect;

  //中心点
  let cx = x + width / 2;
  let cy = y + height / 2;

  //2个点之间的角度获取
  let c1 = Math.atan2(y1 - cy, x1 - cx) * 180 / (Math.PI);
  let c2 = Math.atan2(y2 - cy, x2 - cx) * 180 / (Math.PI);
  let angle;
  c1 = c1 <= -90 ? (360 + c1) : c1;
  c2 = c2 <= -90 ? (360 + c2) : c2;

  //夹角获取
  angle = Math.floor(c2 - c1);
  angle = angle < 0 ? angle + 360 : angle;
  return angle;
}
    /**
     * 获得旋转夹角
     * @param startPos.x 指的是初始位置的x坐标
     * @param startPos.y 指的是初始位置的y坐标
     * @param startPos.r 指的是初始的旋转角度
     */
    let angle = getAngle(startPos.x, startPos.y, e.x, e.y);
    let startAngle = startPos.r;
    let deg;

    // 赋值的旋转角度
    let rotate;

    // 顺时针旋转
    if (e.x - startX > 0) {
      deg = startAngle + angle;
      rotate = deg > 360 ? deg - 360 : deg;
    } else {
    // 逆时针旋转
      angle = 360 - angle;
      deg = startAngle - angle;
      rotate = deg < 0 ? deg + 360 : deg;
    }

JS如何使用Math.atan2获取两点之间角度的实践案例

js 滑动 如何计算滑动速度滑动时常与滑动距离? - 知乎 (zhihu.com)

参考资料

微信小程序:使用拖动(touchstart、touchmove、touchend)以及 scroll-view 实现 下拉加载上一项导航,上拉加载下一导航功能;_微信下拉小程序拖拽感 叫什么-CSDN博客

javascript - 《每周一点canvas动画》——三角函数 - 每天一点canvas动画 - SegmentFault 思否

javascript - 《每周一点canvas动画》——波形运动 - 每天一点canvas动画 - SegmentFault 思否

javascript - 《每周一点canvas动画》——速度与加速度(2) - 每天一点canvas动画 - SegmentFault 思否

九.CANVAS Math.atan和Math.atan2的区别_canvas math.atan2-CSDN博客

# 反正切函数 Math.atan() 与 Math.atan2() 的区别

Math.atan与Math.atan2_math atan2-CSDN博客

Math.atan() - JavaScript | MDN (mozilla.org)

Math.atan2() - JavaScript | MDN (mozilla.org)