当前位置: 首页 > news >正文

js实现图片以鼠标为中心滚轮缩放-vue

功能背景

  • 实现以鼠标在图中的位置为中心进行图片的滚轮缩放,现在是无论鼠标位置在哪都以图片中心进行缩放,这不符合预期;

关键点

  • 缩放前鼠标在的位置是 A(clinetX,clientY) 点,缩放后鼠标的位置是 A’(x2,y2)点,为了保持鼠标位置不变,需要将A’平移到A, 就需要计算出disx的距离,即偏移量;
  • 绿色代表:缩小后的图片;
  • 黄色代表:原始图片;
    所以需平移+缩放。
    在这里插入图片描述

主要步骤:

  1. 监听图片mousewheel事件 计算scale:
  2. 鼠标滚轮事件event.deltaY< 0 ,滚轮向上滚,放大;
  3. 根据当前scale,preScale,clientx ,clienty,计算出偏移量(disx),用上一次的位置 - 计算出新旧之间的相对偏移量 (disx)= 最新的位置(x,y);
  4. 保存新计算得出的位置,以便后续计算;
  5. 根据上式得出新的scale,x,y进行transform; ​

缩放比例n:

n = w i d t h 1 w i d t h = s c a l e p r e S c a l e n =\frac{width_1}{width}=\frac{scale}{preScale} n=widthwidth1=preScalescale
已知:
w i d t h 1 = n ∗ w i d t h width_1 = n*width width1=nwidth
 ( x 2 − x ′ ) = ( c l i e n t x − x ) n (x_2 - x') = (clientx-x)n (x2x)=(clientxx)n

由图可知:
d i s x = ( w i d t h − w i d t h 1 ) 2 + ( x 2 − x ′ ) − ( c l i e n t x − x ) disx = \frac{(width-width_1)}{2} + (x_2 - x') - (clientx - x) disx=2(widthwidth1)+(x2x)(clientxx)

联立上面两式可得:
d i s x = ( w i d t h − n ∗ w i d t h ) 2 + ( c l i e n t x − x ) n − ( c l i e n t x − x ) disx = \frac{(width-n*width)}{2} +(clientx-x)n - (clientx - x) disx=2(widthnwidth)+(clientxx)n(clientxx)

可简化为:
d i s x = ( 1 − n ) ( w i d t h 2 − c l i e n t x + x ) disx = (1-n)(\frac{width}{2} -clientx+x) disx=(1n)(2widthclientx+x)

y同理可得

handleMousewheel: debounce(function(event) {event.preventDefault();let { deltay,clientX,clienty }=event;const isZoomout = deltaY<0;//小于0放大let scale = this.getNewSacle(this.prescale,isZoomOut);// 计算此次缩放比例this.handleZoomImg(this.scale,this.preScale,clientx,clientY);//根据新,旧比例,鼠标位置 进行图片调整this.preScale = scale;
}
200)methods: {getNewSacle(preScale,isZoomout){if(isZoomout){return preScale*1.1;} else return preScale /1.1;},handleZoomImg(scale,preScale,clientX,clienty) {let {x: oX, y: oY}=this.lastSite;let n =  scale / preScale;let img = this.$refs.image; // 图片domlet { x:x1,y:y1,width, height }=img.getBoundingclientRect();// 带入上面得到的算式, x,y减去偏移量就是新的位置oX-= (1-n)*(width/2-clientX + x1);oY-= (1-n)*(height/2-clientY + y1);this.lastSite={x: oX,y: oY}this.updateDom(resScale, oX, oY);},updateDom(scale,x,y){this.$refs.image.style.transform = `matrix(${scale},,θ,${scale},${x}, ${y})`,}

注意:updateDom方法里,如果使用translate和scale要先写translate再scale

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 深度学习中常用概念总结
  • 一次sql请求,返回分页数据和总条数
  • 【深度学习】【语音TTS】GPT-SoVITS v2 实战,训练一个人的音色,Docker镜像
  • Centos7安装Redis(采用docker安装方式)
  • 贪吃蛇(C语言详解)
  • 【精通SDL之----SDL_RenderReadPixels截屏】
  • Jenkins默认工作目录修改及迁移(Windows)
  • 《中国数据库前世今生》——历史的深度与未来的展望
  • 迷茫而又焦虑
  • Java | Leetcode Java题解之第335题路径交叉
  • Vue2 消息订阅与发布
  • java中List列表转成子父集列表
  • 一口气把halcon的所有运算符说清楚
  • python爬虫滑块验证及各种加密函数(基于ddddocr进行的一层封装)
  • 什么是NLP实体识别?
  • 08.Android之View事件问题
  • Android组件 - 收藏集 - 掘金
  • Angular 响应式表单 基础例子
  • Computed property XXX was assigned to but it has no setter
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • go语言学习初探(一)
  • JSDuck 与 AngularJS 融合技巧
  • LeetCode18.四数之和 JavaScript
  • MD5加密原理解析及OC版原理实现
  • MQ框架的比较
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • Vue实战(四)登录/注册页的实现
  • win10下安装mysql5.7
  • 大快搜索数据爬虫技术实例安装教学篇
  • 给Prometheus造假数据的方法
  • 汉诺塔算法
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 嵌入式文件系统
  • 推荐一个React的管理后台框架
  • 走向全栈之MongoDB的使用
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​​​【收录 Hello 算法】9.4 小结
  • # 数论-逆元
  • # 移动硬盘误操作制作为启动盘数据恢复问题
  • #控制台大学课堂点名问题_课堂随机点名
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (Java企业 / 公司项目)点赞业务系统设计-批量查询点赞状态(二)
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (超详细)语音信号处理之特征提取
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (算法)大数的进制转换
  • (算法二)滑动窗口
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题)
  • .Net core 6.0 升8.0
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET IoC 容器(三)Autofac