js如何实现单指拖拽和双指缩放旋转
dearweb 发布:2021-11-05 08:39:48阅读:目前在移动端开发时,大多数情况下需要使用到单指拖拽和双指操作,这个功能使用的也是相当的频繁,不知道各位小伙伴掌握的如何,小编今天给大家介绍一个这个功能的实现方法。
首先我们看下预览效果
通过上图你应该对这个效果有了一定的认识,下面我们一起来讨论下实现的方法吧。
实现主要用到了touchstart、touchmove以及touchend事件。
静态布局代码
<div style="height: 100vh; width: 100vw"> <img src="..." style="transform: translate({{translateX}}px, {{translateY}}px) scale({{scale}}) rotate({{rotate}}deg);" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" /> </div>
在data中设置以下变量
data(){ return{ translateX: 0, // 位移x坐标 单位px translateY: 0, // 位移y坐标 单位px distance: 0, // 双指接触点距离 scale: 1, // 缩放倍数 rotate: 0, // 旋转角度 oldRotate: 0, // 上一次旋转停止后的角度 startMove: { // 起始位移距离 x: 0, y: 0, }, startTouches: [] // 起始点touch数组 } }
单指拖拽方法的实现
单指拖拽比较简单,只需要记录移动的点坐标,然后减去起始点坐标,就可以求出针对页面的移动距离 touchstart 、touchmove
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(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、touchend
getAngle(p1, p2) { const x = p1.pageX - p2.pageX const y = p1.pageY- p2.pageY return Math.atan2(y, x) * 180 / Math.PI }, touchEnd() { // 保存当前旋转角度 this.data.oldRotate = this.data.rotate },
H5原理一致,只需改一下语法即可我这个只是基础版本,如果需要一些边界控制和还一些需求的限制,计算据边框距离即可,也可以用小程序的boundingClientRectAPI
小礼物走一波,支持作者
赏还没有人赞赏,支持一波吧