阅读 771

Pinch-Zoom 实现移动端手势放大+旋转

外部库的使用

pinchzoom.js
优势:这个库已经封装好了手势的放大,缩小,移动,等一系列功能
劣势:需要我们手动添加旋转和重置图片的功能

pinchzoom.js的使用

npm i pinch-zoom-js && yarn add pinch-zoom-js 复制代码

import PinchZoom from 'pinch-zoom-js' 复制代码

let el = document.querySelector('#my-id'); let pz = new PinchZoom(el, options); 复制代码

可配置项

属性说明默认值
tapZoomFactor双击缩放的倍数2
zoomOutFactor缩放低于这个值的时候调整为原始大小1.3
animationDuration动画持续时间(毫秒)300
maxZoom最大放大倍数4
minZoom最小缩小吧倍数0.5
draggableUnzoomed即使图像未缩放,也可以捕获拖动事件true
lockDragAxis将图元的平移锁定到单个轴false
setOffsetsOnce仅计算一次偏移(容器内的图像位置)false(使用'true'在连续的'load'和'resize'上保持偏移)
use2d空闲时返回到二维变换true
verticalPadding图像周围应用的垂直填充0
horizontalPadding图像周围应用的水平填充0
onZoomStart开始缩放的事件null
onZoomEnd停止缩放的事件null
onZoomUpdate更新缩放元素的回调null
onDragStart开始拖动元素null
onDragEnd结束拖动元素null
onDragUpdate更新拖动位置null
onDoubleTap双击图片null

事件

let pz = new PinchZoom(myElement); pz.enable(); // 启用所有手势捕捉(默认启用) pz.disable(); // 禁用所有手势捕捉(默认启用) 复制代码

回调示例

var myElement = document.getElementById("myElement"); var pz = new PinchZoom.default(myElement, {     draggableUnzoomed: false,     minZoom: 1,     onZoomStart: function(object, event){          },     onZoomEnd: function(object, event){          } }) 复制代码

添加旋转事件

第一步:我们先写一个方法,给图片元素dom设置一下transform属性,每次旋转90度

//this.vhtmlRotate用于记录旋转的角度默认是0 let vhtmlImage = document.getElementById('vhtmlImage'); let scale = vhtmlImage.offsetHeight / vhtmlImage.offsetWidth; if (this.vhtmlRotate % 180) {     scale = 1; } vhtmlImage.style.transform = `scale(${scale},${scale}) rotate(${this.vhtmlRotate +90}deg)` 复制代码

问题:每次旋转的时候图片都会变成原始大小,再被Pinch-Zoom设定缩放,会有一个图片闪烁的问题

解决方案:旋转之前先把图片变成透明,旋转后再放出来

vhtmlImage.style.opacity = `0`; ........ vhtmlImage.style.opacity = `1`; 复制代码

问题:放大图片后点击旋转,会出现图片位置错误,影响使用,由于Pinch-Zoom并没有重置组件的方法,如果使用v-if重新渲染和new组件,会导致产生多个pinch-zoom-container标签,导致拖动闪烁,具体原因未知
解决方案:在看了组件源码以后发现update方法,它可以更新给组件设置的参数,我们就在组件加载完成后记录图片位置和放大的尺寸(这里默认是1),旋转后手动设置,然后调用update的方法

this.PinchZoom.zoomFactor = 1; this.PinchZoom.offset = me.offset; this.PinchZoom.update(); 复制代码

问题:多次快速点击旋转,会导致页面报错,原因是组件并没有渲染完成,就进行了下一次渲染
解决方案:手动防抖事件

// 防止快速多次点击 if (!PinchZoomFinish) {     return; } PinchZoomFinish = false; ....... PinchZoomFinish = true;              复制代码

完整代码

<template>     <div class="car-recognition">         <div id="pinc_zoom_room">             <div id="image_room">                 <img id="vhtmlImage" src="https://assets.che300.com/feimg/m/banner/banner_weibao2.png" alt="" />             </div>         </div>         <div @click="resetImg" class="reset_img">旋转图片</div>     </div> </template> <script> import PinchZoom from 'pinch-zoom-js'; let PinchZoomFinish = true; export default {     name: 'carRecognition',     data() {         return {             vhtmlRotate: 0,             offset:{}         };     },     methods: {         //重置图片         resetImg() {             let me = this;             // 防止快速多次点击             if (!PinchZoomFinish) {                 return;             }             PinchZoomFinish = false;             let vhtmlImage = document.getElementById('vhtmlImage');             vhtmlImage.style.opacity = `0`;             let scale = vhtmlImage.offsetHeight / vhtmlImage.offsetWidth;             if (me.vhtmlRotate % 180) {                   scale = 1;             }             vhtmlImage.style.opacity = `1`;             vhtmlImage.style.transform = `scale(${scale},${scale}) rotate(${me.vhtmlRotate +                 90}deg)`;             me.vhtmlRotate = me.vhtmlRotate + 90;             me.PinchZoom.zoomFactor = 1;             me.PinchZoom.offset = me.offset;             me.PinchZoom.update();             PinchZoomFinish = true;         },     },     created() {         setTimeout(() => {             const el = document.getElementById('image_room');             this.PinchZoom = new PinchZoom(el, {                 zoomOutFactor: 0.5,                 onZoomStart: function(object, event){                     console.log(object,event,'onZoomStart')                 },                 onZoomEnd: function(object, event){                     console.log(object,event,'onZoomEnd')                 },                 onZoomUpdate: function(object, event){                     // console.log(object,event,'onZoomUpdate')                 },                 onDragStart: function(object, event){                     console.log(object,event,'onDragStart')                 },                 onDragEnd: function(object, event){                     console.log(object,event,'onDragEnd')                 },                 onDragUpdate: function(object, event){                     // console.log(object,event,'onDragUpdate')                 },                 onDoubleTap: function(object, event){                     console.log(object,event,'onDoubleTap')                 }             });             this.$nextTick(()=>{                 this.offset = this.PinchZoom.offset                 console.log(this.offset)             })         },200)     } }; </script> <style lang="less"> #pinc_zoom_room {     text-align: left;     height: 7rem;     margin: 0.4rem;     position: relative;     background: #cccccc;     border-radius: 0.066667rem;     -webkit-touch-callout: none; /*系统默认菜单被禁用*/     -webkit-user-select: none; /*webkit浏览器*/     -khtml-user-select: none; /*早期浏览器*/     -moz-user-select: none; /*火狐*/     -ms-user-select: none; /*IE10*/     user-select: none;     #vhtmlImage {         max-height: 7rem;         -webkit-touch-callout: none;     } } </style>


作者:三百云技术中心
链接:https://juejin.cn/post/7047000739712860173


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐