微信小程序单指拖拽和双指缩放旋转
2023-06-13 09:15:37 时间
小程序单指拖拽和双指操作是一个比较常用的功能,效果如下图
- 实现这三个功能,主要用三个触摸事件
touchstart
、touchmove
、touchend
<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
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原理一致,只需改一下语法即可
- 我这个只是基础版本,如果需要一些边界控制和还一些需求的限制,计算据边框距离即可,也可以用小程序的
boundingClientRect
API
相关文章
- 微信转账后被删好友?教你一键追回!
- 有什么办法可以实时监控微信_微信被监控有什么特征
- 手把手教你springboot集成微信支付
- 【说站】仿网易云音乐的YY音乐微信小程序源码
- 【说站】微信天气预报小程序
- 微信小程序后端开发流程_微信小程序开发入门
- 【愚公系列】2022年09月 微信小程序-three.js绘制多维旋转正方体
- 【愚公系列】2022年09月 微信小程序-WebGL立体图形的绘制
- 微信公众号推广_小程序通知栏消息推送
- 微信小程序修改data数据的方法
- 微信小程序input框输入值获取
- 微信小程序事件对象currentTarget和target属性的区别
- 微信小程序网络请求-函数封装
- 微信小程序模板消息接口下线了,不用慌,调用统一服务消息接口来实现相同功能
- 微信小程序自定义底部弹出框功能
- ChatGPT API 接入微信公众号(服务号)的坑及实现 (Part I)
- 微信小程序图片显示方式详解手机开发
- “Linux 中国”微信矩阵
- 微信信用卡还款小程序抢滩首批上线、“白条闪付”与“花呗”的PK | AI金融评论周刊
- 利用SQLserver构建与微信对接的小程序系统(sqlserver与微信)