移动端图片单指移动,双指放大缩小实现//touchmove的时候不让body滚动

思路1:移动放大缩小操作都直接放到图片上面

  1. 图片的放大缩小使用transform的scale属性操作,移动使用transform的translate属性操作,也可以使用matrix属性做2D转换,这个有六个值,14表示xy轴的放大倍数,56表示xy轴的偏移量,23表示度数,这里不操作旋转可以写成默认的0
  2. 根据touches获取当前触摸位置,touches是一个数组,表示当前有几个手指触摸屏幕,可以判断一下,是单指的时候在ontouchstart时记录手指触摸的位置,然后在ontouchmove时计算现在手指的移动位置,计算两者的偏移量,在图片上使用transform属性的matrix或translate控制图片做出移动(可以在ontouchend的时候判断一下要不要移动回原位置,或者在放大一倍的时候就让回原位置,或者在ontouchmove的时候限制一下图片的移动范围)
  3. 根据touches有两个值的时候做出判断,让图片根据手势放大缩小.在ontouchstart的时候进行根据两个手指的位置计算出来现在两个手指的距离(勾股定理)记录下来,在ontouchmove的时候计算当前手指的距离,拿这个距离和之前start时记录的距离相除,根据这个值来确定当前放大倍数.然后在图片上面做出操作,控制放大缩小程度.(这里会有个几个坑)
    3.1 因为将放大和移动都放到图片dom上,所以两个属性之间会有一些相互影响,这个需要处理下
    3.2 在放大的时候需要确定放大的中心,这时候有两种确定中心的情况,第一种:在ontouchstart的时候计算双指的中心位置,把这个确定为transform-origin,第二种是在ontouchmove的时候动态计算双指之间的位置在原始图片上的坐标,这里计算复杂一些,需要考虑到图片放大倍数和偏移量,需要通过记录下来的图片位置,和当前放大缩小的倍数计算当前我们看到的展示图片,和原始图片倍数是1,偏移量是0的时候的对应坐标,这里计算好对应的坐标才好计算下一步
    3.3 在确定对应坐标的情况下,因为transform-origin改变在放大倍数不为1的时候会导致图片发生移动,这里需要做一下处理,因为要保证图片在移动的时候不能跳跃式移动,在修改transform-origin的时候我们需要根据当前放大倍数和现在transform-origin-原始transform-origin之间的偏移量来计算这个图片是会上下左右移动多少位置,需要在修改transform-origin的时候同步修改一下translate偏移量,让图片不会因为origin修改而发生位置改变
    3.4 在确定中心之后就只需要通过计算双指之间的距离计算放大缩小倍数了
    ps:这里也可以使用position来确定移动位置,不过同样需要计算

思路2:因为在scale为1的时候修改transform-origin不会导致图片的偏移,所以可以将放大的操作放到ing的父元素上面,让父元素占满屏幕,让图片只做位置移动

  1. 同样的三个方法:ontouchstart/ontouchmove/ontouchend这三个,在单指触摸的时候通过css控制图片dom移动,在放大的时候控制图片父元素放大,这样就可以保证放大的不影响图片,而且不怎么用计算当前放大的中心在哪
  2. 和上面相同的需要在start记录位置,然后在move的时候记录移动的大小,计算移动的大小,修改位置
  3. 双指放大缩小也是一样

下面是根据方法二写的例子,在react项目中的,其他项目也可以只要事件能挂上去就可以,怕覆盖原先事件可以使用监听,不过一般有这个事件的都有这个功能了,都不做这些了
看项目需求
这里的例子可以去闲鱼里搜闪回有品官方店里面的验货报告里面查看

// 在移动端如果想要在touchmove的时候不让body也滚动,在弹窗的最外层阻止事件冒泡就可以了const box: any = document.getElementsByClassName('ant-image-preview-wrap')box[0].ontouchmove = (e: any) => {e.preventDefault()e.stopPropagation()return false}
useEffect(() => {if (visible) {//  这里将触摸事件绑定到图片的父元素上面const imgBoxDom: any = document.getElementsByClassName('ant-image-preview-img-wrapper')// 记录move前的图片位置,在ontouchesstart和ontouchesmove有使用到let dingwei: { x: number; y: number } = { x: 0, y: 0 }// 计算双指之间的距离const getDistance = (start: { x: number; y: number }, stop: { x: number; y: number }) => {return Math.sqrt(Math.pow(stop.x - start.x, 2) + Math.pow(stop.y - start.y, 2))}const distance = { start: 1, stop: 1 }// 默认的放大倍数(即时)let scaleXY = 1// 默认放大倍数(双指操作结束)let scale = 1// 图片开始移动位置let trans: any// 是不是单个手指触摸(判断防止因为在触发双指时,两个手指都移动导致weizhi字段记录的坐标和双指不同时离开屏幕导致有触发单指的情况,这种情况导致的图片位置跳动)let isOne = trueimgBoxDom[0].ontouchstart = (e: any) => {e.preventDefault()if (e.touches.length == 1) {// 是单指触摸,保存一下现在的位置isOne = truedingwei = { x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY }trans = e.target.style.transformif (trans.indexOf('matrix') == 0) {trans = trans.split('(')trans = trans[1].split(',')} else {trans = [1, 0, 0, 1, 0, 0]}} else if (e.touches.length == 2) {// 双指就保存一下现在的双指距离isOne = falsedistance.start = getDistance({x: e.touches[0].screenX,y: e.touches[0].screenY,},{x: e.touches[1].screenX,y: e.touches[1].screenY,})}}imgBoxDom[0].ontouchmove = (e: any) => {e.preventDefault()e.stopPropagation()if (e.touches.length == 1) {// 开始移动,防止双指放大之后离开一指导致图片跳动,更新一下图片位置if (!isOne) {isOne = truedingwei = { x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY }}// 计算现在的单指移动位置const moveX = e.changedTouches[0].pageX - dingwei.xconst moveY = e.changedTouches[0].pageY - dingwei.y// 使用scaleXY是因为有可能父元素已经被放大缩小过,这时候移动的大小就不是显示的大小了,需要计算一下实际距离const style = `transform:matrix(1,0,0,1,${parseFloat(trans[4]) + moveX / scaleXY},${parseFloat(trans[5]) + moveY / scaleXY});transition:transform 0s;`e.target.style = style} else if (e.touches.length == 2) {// 计算一下现在放大倍数distance.stop = getDistance({x: e.touches[0].screenX,y: e.touches[0].screenY,},{x: e.touches[1].screenX,y: e.touches[1].screenY,})const big = distance.stop / distance.start// 最大三倍,最小1倍,只需要修改倍数,位移是不需要修改的,不过在放大的时候图片是可以以双指中心为origin放大的,很迷scaleXY = big - 1 + scalescaleXY = scaleXY < 1 ? 1 : scaleXYscaleXY = scaleXY > 3 ? 3 : scaleXYconst style = `transform:matrix(${scaleXY},0,0,${scaleXY},0,0);transition:transform 0s;`imgBoxDom[0].style = style}}imgBoxDom[0].ontouchend = (e: any) => {e.preventDefault()e.stopPropagation()scale = scaleXY}// 底下这里可以不做判断,这里是因为之前使用的antd的组件,直接在切换图片上面添加一个事件,切换图片让图片大小位置还原const btnDomLeft: any = document.getElementsByClassName('ant-image-preview-switch-left')const btnDomImg: any = document.getElementsByClassName('ant-image-preview-img')btnDomLeft[0].addEventListener('click', () => {btnDomImg[0].style = 'transform:matrix(1,0,0,1,0,0);transition:transform 0s;'imgBoxDom[0].style = `transform:matrix(1,0,0,1,0,0);transition:transform 0s;`})const btnDomRight: any = document.getElementsByClassName('ant-image-preview-switch-right')btnDomRight[0].addEventListener('click', () => {btnDomImg[0].style = 'transform:matrix(1,0,0,1,0,0);transition:transform 0s;'imgBoxDom[0].style = `transform:matrix(1,0,0,1,0,0);transition:transform 0s;`})}}, [visible])

移动端图片单指移动,双指放大缩小实现//touchmove的时候不让body滚动相关推荐

  1. Unity触控——单指、双指、Windows大屏多人触控

    前段时间做了个Windows系统的大屏触控程序,最多同时支持十点触控,并且在各自的小窗口中要分别处理,即每个小窗口中的触点为一个处理组,判断其单点或多点操作.按以往移动端程序的触屏事件Input.Ge ...

  2. Android Image单指滑动双指缩放功能

    在android app开发过程中,对于单指滑动,双指缩放功能的实现,也是常用的功能 在对ImageView的处理中,可以自定义ImageView在onTouch事件中对单指和双指缩放处理,也可以 注 ...

  3. uni-app图片如何设置双指放大缩小

    图片设置双指放大缩小这个功能相对来说比较简单的,是用于官方文档的路径(组件->视图容器->movable-area),movable-area可以做双指放大缩小,并且放大的同时可以左右移动 ...

  4. uni-app图片 设置浏览功能 实现双指放大缩小 拖动移动

    首先,点击触发图片浏览界面 在浏览界面去实现图片移动和放缩 图片设置双指放大缩小这个功能相对来说比较简单的,是用于官方文档的路径(组件->视图容器->movable-area),movab ...

  5. 百度地图api不支持windows平板 双指放大缩小解决方案

    百度地图api不支持windows平板 双指放大缩小解决方案 (1)​保存百度使用API返回的脚本,这个接口 http://api.map.baidu.com/getscript?v=2.0, 命名为 ...

  6. javascript实现对图片的随意拖拽,放大缩小

    [JS]基于javascript实现对图片的随意拖拽,放大缩小 最近写项目的过程中需要对图片进行一个操作,点击之后弹出图片,在可定div范围内对图片进行任意拖拽位置和鼠标滚动时对其放大缩小,双击图片恢 ...

  7. css鼠标图片hover移入移出缓慢放大缩小

    css鼠标图片hover移入移出缓慢放大缩小 /* transition 别放hover里,放到img里,这样移入移出一样缓慢,不然只对hover移上去有缓慢效果 */.image{width: 10 ...

  8. 【Unity开发小技巧】模型单指旋转双指缩放功能代码(多种情况)

    欢迎加入Unity业内qq交流群:956187480 qq扫描二维码加群 1.pc端通过鼠标中键调整相机的FieldOfView属性的值(会发生形变不建议) void Update(){if (Inp ...

  9. android 自定义ImageView实现图片手势滑动 多点触摸放大缩小效果

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 转自:h ...

最新文章

  1. 如何解决VS2015编译C4996错误
  2. ITK:应用Exp负图像过滤器
  3. 【详细分析】1023 Have Fun with Numbers (20 分)_20行代码AC
  4. 人生应该记住的16句话
  5. git 应用 rebase
  6. QAQ来自弱鸡的嘲笑
  7. Python-print学习
  8. Otsu‘s Thresholding的工作原理
  9. Fragstats计算景观生态指数
  10. 取色器ColorPix
  11. 七、树莓派做Aria2下载机
  12. jQuery基础------图片加边框
  13. fabs linux头文件,fabs(c语言fabs函数用法求精度)
  14. C# ABP WebApi与Swagger UI的集成
  15. linux 命令:ping、fping、gping、hping3、tracert、traceroute
  16. python阴阳鱼绘制(使用turtle)
  17. 【bzoj4318】【OSU!】期望dp——维护多个期望值递推
  18. iOS客户端公共WIFI解决方案
  19. 计算机网络(第八版)谢希仁编著 笔记
  20. win10中谷歌浏览器输入任何字符导致浏览器崩溃的解决方法

热门文章

  1. 数学题还是计算机题啊
  2. 转自科学松鼠会------压缩感知的基础认识
  3. Elastic认证考试:备考环境完全指南
  4. 验证码研究入门必读(验证码是什么,有什么用,分类,设计,破解,未来发展)
  5. 出行者信息服务器,出行者信息服务系统解析.ppt
  6. 关于C#建立FLASH服务端的安全沙箱问题
  7. Nginx之父被抓!员工“接私活儿”到底合不合法?
  8. Linux搭建lnmp、nginx、mysql
  9. 解决insmod error inserting 'hello ko' -1 Invalid module form
  10. OSChina 周四乱弹 —— 如果你追到我,我就和你……