详解通过变换矩阵实现canvas的缩放功能


Posted in HTML / CSS onJanuary 14, 2019

这篇文章主要介绍一种通过设置canvas的变换矩阵来实现canvas的缩放。

第一步就是监听鼠标的滚轮事件,在滚轮事件中根据鼠标的滚动以及基于前一次的变换,重新设置context的缩放和平移,核心代码如下:

let delta = this.deltaInst;
 delta.bind('zoom', (data) => {
 delta._transform.scale.forEach((s, i) => {
   delta._transform.scale[i] *= data.delta > 0? 2 : 1/2;
 });
 let offsetX = data.x - delta._transform.translate[0];
 let offsetY = data.y - delta._transform.translate[1];
 delta._transform.translate[0] += -(data.delta > 0? 1 : -1/2)*offsetX;
 delta._transform.translate[1] -=  (data.delta > 0? 1 : -1/2)*offsetY;
 delta.refreshAll();
});

这里假设每次缩放都都放2倍,也可以是其他缩放比例。

第一步根据滚动的方向在当前缩放比的基础上乘以2或者除以2;

第二步计算平移,基本思路是计算基于新鼠标位置缩放canvas上的点到心位置时,对canvas平移到什么位置是可以达到相同的效果。

下面看一下refreshAll的代码:

let ctx = this.context;
   let matrix = this.getTransformMatrix();
   ctx.save();
   ctx.transform(...matrix);
   //ctx.translate(...this._transform.translate);
   //ctx.scale(...this._transform.scale);
   if (!Array.isArray(shapes)) {
     shapes = [shapes];
   }
   shapes.forEach( (shape) => {
     shape.render(ctx);
   });
   ctx.restore();

代码中首先获取到基于之前计算的缩放值scale和平移值translate,得到一个变化矩阵 ,然后将矩阵中对应的值传递给context的transform方法,对画布进行给定的变换,之后进行前一次缩放完全一致的绘图操作,就和已得到缩放后的效果了~~

在上面的代码中,ctx.transform() 也可以完全用ctx.translate()和ctx.scale()方法代替,如代码中的注释部分所示,参数即为前面计算得到的值。

完整代码可参考github地址: https://github.com/helloweilei/delta

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
CSS3 完美实现圆角效果
Jul 13 HTML / CSS
CSS3动画:5种预载动画效果实例
Apr 05 HTML / CSS
CSS3实现渐变背景兼容问题
May 06 HTML / CSS
CSS3 transition 实现通知消息轮播条
Oct 14 HTML / CSS
HTML5 语义化结构化规范化
Oct 17 HTML / CSS
css 如何让背景图片拉伸填充避免重复显示
Jul 11 HTML / CSS
HTML5实现的图片无限加载的瀑布流效果另带边框圆角阴影
Mar 07 HTML / CSS
纯HTML5+CSS3制作生日蛋糕(代码易懂)
Nov 16 HTML / CSS
H5调用相机拍照并压缩图片的实例代码
Jul 20 HTML / CSS
Html5移动端适配IphoneX等机型的方法
Jun 25 HTML / CSS
详解移动端h5页面根据屏幕适配的四种方案
Apr 15 HTML / CSS
html5 横向滑动导航栏的方法示例
May 08 HTML / CSS
html Table 表头固定的实现
Jan 22 #HTML / CSS
Html5如何唤起百度地图App的方法
Jan 27 #HTML / CSS
canvas学习笔记之绘制简单路径
Jan 28 #HTML / CSS
web页面录屏实现
Feb 12 #HTML / CSS
Canvas 文本转粒子效果的实现代码
Feb 14 #HTML / CSS
canvas学习笔记之2d画布基础的实现
Feb 21 #HTML / CSS
使用HTML5原生对话框元素并轻松创建模态框组件
Mar 06 #HTML / CSS
You might like
PHP4之COOKIE支持详解
2006/10/09 PHP
安装APACHE
2007/01/15 PHP
php集成动态口令认证
2016/07/21 PHP
PHP设计模式之单例模式原理与实现方法分析
2018/04/25 PHP
php 使用mpdf实现指定字段配置字体样式的方法
2019/07/29 PHP
Javascript实例教程(19) 使用HoTMetal(2)
2006/12/23 Javascript
推荐20家国外的脚本下载网站
2011/04/28 Javascript
js分解url参数(面向对象-极简主义法应用)
2012/08/09 Javascript
6款新颖的jQuery和CSS3进度条插件推荐
2013/03/05 Javascript
JS常见问题之为什么点击弹出的i总是最后一个
2016/01/05 Javascript
js实现密码强度检测【附示例】
2016/03/30 Javascript
修改jquery中dialog的title属性方法(推荐)
2016/08/26 Javascript
基于Bootstrap 3 JQuery及RegExp的表单验证功能
2017/02/16 Javascript
详解Javascript几种跨域方式总结
2017/02/27 Javascript
深入学习 JavaScript中的函数调用
2017/03/23 Javascript
JS实现的汉字与Unicode码相互转化功能分析
2018/05/25 Javascript
vue项目中axios请求网络接口封装的示例代码
2018/12/18 Javascript
puppeteer库入门初探
2019/01/09 Javascript
layui数据表格跨行自动合并的例子
2019/09/02 Javascript
基于JS实现快速读取TXT文件
2020/08/25 Javascript
[01:36]极致酷炫!TI9典藏宝瓶+撼地者至宝展示
2019/06/11 DOTA
Python判断某个用户对某个文件的权限
2016/10/13 Python
Python编程scoketServer实现多线程同步实例代码
2018/01/29 Python
Python利用神经网络解决非线性回归问题实例详解
2019/07/19 Python
python安装gdal的两种方法
2019/10/29 Python
使用pandas库对csv文件进行筛选保存
2020/05/25 Python
python 实现一个简单的线性回归案例
2020/12/17 Python
使用CSS媒体查询(Media Queries)和JavaScript判断浏览器设备类型的方法
2014/04/03 HTML / CSS
什么造成了Java里面的异常
2016/04/24 面试题
怎么处理XML的中文问题
2015/03/26 面试题
实习教师自我鉴定
2013/12/12 职场文书
领导干部民主生活会自我剖析材料范文
2014/09/20 职场文书
博士给导师的自荐信
2015/03/06 职场文书
2015年仓库管理工作总结
2015/05/25 职场文书
财务管理制度范本
2015/08/04 职场文书
女性励志书籍推荐
2019/08/19 职场文书