手写小程序缩放及拖拽功能(仿地图)

一开始用的小程序原生的标签后来发现不太行,只能从中心点放大不能在双指放大后手写缩放及拖拽功能。

记录问题

1.IOS在缩放或者拖拽过程中背景图会重新加载

将标签更换为image

2.touchmove触发有时候会卡顿,(仅限真机模拟过程中)

后来发现返回值时间就会有时候变长,将标签从bind更换为catch即可解决

单指操作为拖拽,双指操作为缩放,另附上JS代码

// ----------开始触摸
  onTouchstart(e) {
    console.log(e.touches, '手指开始触摸')
    // IOS适配更改CSS属性
    this.setData({
      mapCanvas: 'map-canvas-middle'
    })
    // 如果是单指触摸
    if (e.touches.length === 1) {
      this.setData({
        // 单指可拖拽
        canChange: true,
        // 拖拽的起始点
        dragDropX: e.touches[0].clientX,
        dragDropY: e.touches[0].clientY,
        // XY的移动距离
        moveX: e.touches[0].clientX - this.data.leftBg,
        moveY: e.touches[0].clientY - this.data.topBg
      })
    }
    // 如果是双指缩放
    if (e.touches.length === 2) {
      this.setData({
        // 不可拖拽状态
        canChange: false
      })
      // 当两根手指放上去的时候,将距离(distance)初始化。
      const xMove = e.touches[1].clientX - e.touches[0].clientX
      const yMove = e.touches[1].clientY - e.touches[0].clientY
      const historyX = (e.touches[1].clientX + e.touches[0].clientX) / 2
      const historyY = (e.touches[1].clientY + e.touches[0].clientY) / 2
      // 计算开始触发两个手指坐标的距离
      const xyDistance = Math.sqrt(xMove * xMove + yMove * yMove)
      this.setData({
        // 双指按下距离
        xyDistance: xyDistance,
        // 双指按下的历史点位中点
        historyX: historyX,
        historyY: historyY
      })
    }
  },
  // 手指开始移动
  onTouchmove(e) {
    console.log(e.touches, '手指开始移动')
    // 如果是单指触摸并且可更改状态
    if (e.touches.length === 1 && this.data.canChange) {
      let leftBg = e.touches[0].clientX - this.data.moveX
      let topBg = e.touches[0].clientY - this.data.moveY
      // 如果到了最右侧
      if (leftBg < 0 && this.data.canvasWidth - leftBg >= this.data.canvasWidth * this.data.scale) {
        leftBg = this.data.canvasWidth - this.data.canvasWidth * this.data.scale
      }
      // 如果到了最左侧
      if (leftBg > 0) {
        leftBg = 0
      }
      // 如果到了最下侧
      if (topBg < 0 && this.data.canvasHeight - topBg >= this.data.canvasHeight * this.data.scale) {
        topBg = this.data.canvasHeight - this.data.canvasHeight * this.data.scale
      }
      // 如果到了最上侧
      if (topBg > 0) {
        topBg = 0
      }
      this.setData({
        // 背景图左侧和上侧偏移量
        leftBg: leftBg,
        topBg: topBg
      })
    }
    // 如果是双指触摸
    if (e.touches.length === 2) {
      console.log(this.data.leftBg, this.data.topBg, this.data.scale, this.data.xyDistance)
      this.setData({
        // 双指状态禁止拖拽
        canChange: false
      })
      // 双手指运动 x移动后的坐标和y移动后的坐标
      const xMove = e.touches[1].clientX - e.touches[0].clientX
      const yMove = e.touches[1].clientY - e.touches[0].clientY
      const centerX = (e.touches[1].clientX + e.touches[0].clientX) / 2
      const centerY = (e.touches[1].clientY + e.touches[0].clientY) / 2
      // 双手指运动新的 ditance
      const xyDistance = Math.sqrt(xMove * xMove + yMove * yMove)
      // 计算移动的过程中实际移动了多少的距离
      let scale = xyDistance / this.data.xyDistance * this.data.scale
      let leftBg = centerX - this.data.historyX * scale
      let topBg = centerY - this.data.historyY * scale
      // 设置最小放大倍数为1
      if (scale <= 1) {
        scale = 1
      }
      // 如果到了最右侧
      if (leftBg < 0 && this.data.canvasWidth - leftBg >= this.data.canvasWidth * scale) {
        leftBg = this.data.canvasWidth - this.data.canvasWidth * scale
      }
      // 如果到了最左侧
      if (leftBg > 0) {
        leftBg = 0
      }
      // 如果到了最下侧
      if (topBg < 0 && this.data.canvasHeight - topBg >= this.data.canvasHeight * scale) {
        topBg = this.data.canvasHeight - this.data.canvasHeight * scale
      }
      // 如果到了最上侧
      if (topBg > 0) {
        topBg = 0
      }
      this.setData({
        // 中心点XY
        centerX: centerX,
        centerY: centerY,
        // 放大倍数
        scale: scale,
        // 上一次移动距离
        xyDistance: xyDistance,
        // 背景图定位的左和上
        leftBg: leftBg,
        topBg: topBg
      })
      console.log(this.data.leftBg, this.data.topBg, this.data.scale, this.data.xyDistance, '-----')
    }
  },
  // 触摸结束
  onTouchend() {
    this.setData({
      // 适配换回一开始的class
      mapCanvas: 'map-canvas'
    })
  },

猜你喜欢

转载自blog.csdn.net/weixin_51263829/article/details/130275707