前言

小程序单指拖拽和双指操作是一个比拟罕用的性能,成果如下图

  • 实现这三个性能,次要用三个触摸事件touchstarttouchmovetouchend

    <view style="height: 100vh; width: 100vw">  <image    src="..."    style="transform: translate({{translateX}}px, {{translateY}}px) scale({{scale}}) rotate({{rotate}}deg);"    catch:touchstart="touchStart"    catch:touchmove="touchMove"    catch:touchend="touchEnd"  /></view>
  • 用了以下变量

    Page({  data: {    translateX: 0, // 位移x坐标 单位px    translateY: 0, // 位移y坐标 单位px    distance: 0, // 双指接触点间隔    scale: 1, // 缩放倍数    rotate: 0, // 旋转角度    oldRotate: 0, // 上一次旋转进行后的角度    startMove: { // 起始位移间隔      x: 0,      y: 0,    },    startTouches: [] // 起始点touch数组  },})

单指拖拽

  • 实现单指拖拽比较简单,只须要记录挪动的点坐标,而后减去起始点坐标,就能够求出绝对页面的挪动间隔
  • touchstart

    touchStart(e) {  const touches = e.touches  const { translateX, translateY } = this.data  const { pageX, pageY } = touches[0]  this.data.startMove = {    x: pageX - translateX,    y: pageY - translateY  }  this.data.startTouches = touches},
  • touchmove

    touchMove(e) {  const touches = e.touches  const { pageX: onePageX, pageY: onePageY } = touches[0]  const { startMove } = this.data  this.setData({    translateX: onePageX - startMove.x,    translateY: onePageY - startMove.y  })}

双指缩放

  • 双指缩放的原理是依据两点坐标求出间隔(勾股定理),而后在用挪动坐标的间隔比就能够求出缩放倍数
  • touchmove

    touchMove(e) {  const touches = e.touches  const { pageX: onePageX, pageY: onePageY } = touches[0]  const { startMove, scale, distance: oldDistance, startTouches } = this.data  if (touches.length === 2 && startTouches.length === 2) {    // 双指缩放    const { pageX: twoPageX, pageY: twoPageY } = touches[1]    // 求出以后双指间隔    const distance = Math.sqrt((twoPageX - onePageX) ** 2 + (twoPageY - onePageY) ** 2)    this.data.distance = distance    this.setData({      scale: scale * (distance / (oldDistance || distance))    })  } else if (startTouches.length !== 2) {    // 单指拖拽    this.setData({      translateX: onePageX - startMove.x,      translateY: onePageY - startMove.y    })  }}
  • startTouches.length !== 2这个判断的起因是避免图片跳动,因为如果你两个手指触摸,而后来到一个手指,我是禁止拖拽的,只有双指都来到后再次触摸能力单指拖拽

双指旋转

  • 双指旋转的原理是依据三角函数求出起始点的角度,而后再求出挪动坐标的角度,相减而后加上上一次旋转的角度就等于你以后所需的抉择角度
  • touchmove
touchMove(e) {  const touches = e.touches  const { pageX: onePageX, pageY: onePageY } = touches[0]  const { startMove, scale, distance: oldDistance, startTouches, oldRotate } = this.data  if (touches.length === 2 && startTouches.length === 2) {    const { pageX: twoPageX, pageY: twoPageY } = touches[1]    const distance = Math.sqrt((twoPageX - onePageX) ** 2 + (twoPageY - onePageY) ** 2)+   let rotate = this.getAngle(touches[0], touches[1]) - this.getAngle(startTouches[0], startTouches[1]) + oldRotate    // 如果大于360度,就减去360+   rotate = rotate > 360 ? rotate - 360 : rotate    this.data.distance = distance    this.setData({      scale: scale * (distance / (oldDistance || distance)),+     rotate    })  } else if (startTouches.length !== 2) {    this.setData({      translateX: onePageX - startMove.x,      translateY: onePageY - startMove.y    })  }},
  • getAngle

    getAngle(p1, p2) {  const x = p1.pageX - p2.pageX  const y = p1.pageY- p2.pageY  return Math.atan2(y, x) * 180 / Math.PI}
  • touchend

    touchEnd() {  // 保留以后旋转角度  this.data.oldRotate = this.data.rotate},

总结

  • 代码片段https://developers.weixin.qq.com/s/0nS1tImU7Rs5
  • H5原理统一,只需改一下语法即可