jquery 绑定 mousewheel,Fabric 实现滚轮缩放
给 canvas 绑定鼠标滚轮事件,以便滚轮实现画布缩放功能。
Fabric 有一个 canvas 的 mouse:wheel 事件; jquery 也有,这里先用 jquery。
webpack 项目引入 jquery,可以在文件中直接 import
不过有个问题就是哪个文件要用,就要在当前文件引入,所以使用一个一劳永逸的办法
在 webpack.config.js 中引入:
jquery 有了,下面绑定鼠标滚轮事件,百度了一下都说是绑定 'mousewheel' 事件
这个监听不能加载 canvas 上,而要加在 Fabric 自动生成的上层容器(.upper-canvas)中。
但是项目抛出了错误,可见百度出来的东西也不一定是经过测验的
后来看了下 jquery 里的事件 ,发现鼠标滚轮事件是 wheel,不是 mousewheel!
接下来在实现缩放方法
通过 event.originalEvent.deltaY 来判断滚轮是向上还是向下
验证之后会有如下代码:
抽取变量,做到灵活可配
if 判断后调用计算 scale 方法
先计算画布缩放尺寸
这里会有一个小瑕疵,计算精度的问题:
可以 toFixed 解决一下
这里抽取了一个 getScaleValue 的方法,用于获取当前缩放值 和 缩放比例,比例用于后续计算尺寸
画布计算好后,再进行包含对象的尺寸计算:分别计算缩放以及位置的值
逻辑清晰没问题,代码优化一下:
贴代码贴代码:
// 滚轮监听 $(".upper-canvas").on('wheel', (e) => { if (e.originalEvent.deltaY > 0) { console.log('上', e.originalEvent.deltaY); this.calculateScale(this.canvas, this.scaleStep); } else { console.log('下', e.originalEvent.deltaY); this.calculateScale(this.canvas, -this.scaleStep); } }); /** * 缩放画布 */ calculateScale(canvas, num) { let scale; [ this.currentScale, scale ] = this.getScaleValue(this.currentScale, num); console.log(this.currentScale); this.canvas.setWidth(this.canvas.getWidth() * scale); this.canvas.setHeight(this.canvas.getHeight() * scale); // 计算包含对象的尺寸布局 this.calculateEleScale(canvas, scale); this.canvas.renderAll(); } /** * 获取缩放值与比例,增加限制最大最小 */ getScaleValue(currentScale, num) { let newScale = this.currentScale + num; // 处理计算精度瑕疵 newScale = Number(newScale.toFixed(1)); if (newScale < this.scaleMin || newScale > this.scaleMax) { // 越限直接返回当前比例 return [ currentScale, 1 ]; } // 处理比例关系 return [ newScale, (this.currentScale + num) / this.currentScale ]; } /** * 计算画布包含对象的缩放 */ calculateEleScale(canvas, scale) { let objects = canvas.getObjects(); for (let i in objects) { let map = [ 'scaleX', 'scaleY', 'left', 'top' ]; map.map((attr) => { objects[i][attr] *= scale; }); } }
记录:canvas 内部 滚轮事件,实现逻辑类似,效果一样
canvas.on({ "mouse:wheel": (e) => { event.deltaY > 0; }, });
记录其他实现:
// 向中心缩放 let zoom; canvas.on({ // 鼠标滚动缩放 "mouse:wheel": (e) => { zoom = (event.deltaY > 0 ? -0.1 : 0.1) + canvas.getZoom(); zoom = Math.max(0.1, zoom); //最小为原来的1/10 zoom = Math.min(3, zoom); //最大是原来的3倍 let zoomPoint = new fabric.Point(400, 400); // 中心点 canvas.zoomToPoint(zoomPoint, zoom); }, });
// 向左上角缩放 canvas.on('mouse:wheel', function(opt) { let delta = opt.e.deltaY; let zoom = canvas.getZoom(); zoom *= 0.999 ** delta; if (zoom > 20) zoom = 20; if (zoom < 0.01) zoom = 0.01; canvas.setZoom(zoom); opt.e.preventDefault(); opt.e.stopPropagation(); });
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2020-04-14 python 处理 excel 基本操作