详解通过变换矩阵实现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的transition和animation的用法实例介绍
Aug 20 HTML / CSS
轻松掌握CSS3中的字体大小单位rem的使用方法
May 24 HTML / CSS
CSS3下的渐变文字效果实现示例
Mar 02 HTML / CSS
css3进阶之less实现星空动画的示例代码
Sep 10 HTML / CSS
CSS3颜色值RGBA与渐变色使用介绍
Mar 06 HTML / CSS
详解CSS3 filter:drop-shadow滤镜与box-shadow区别与应用
Aug 24 HTML / CSS
CSS3实现菜单悬停效果
Nov 17 HTML / CSS
HTML5地理定位实例
Oct 15 HTML / CSS
简述Html5 IphoneX 适配方法
Feb 08 HTML / CSS
使用iframe+postMessage实现页面跨域通信的示例代码
Jan 14 HTML / CSS
前端H5 Video常见使用场景简介
Aug 21 HTML / CSS
CSS filter 有什么神奇用途
May 25 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
php漏洞之跨网站请求伪造与防止伪造方法
2013/08/15 PHP
Drupal7中常用的数据库操作实例
2014/03/02 PHP
PHP中ajax无刷新上传图片与图片下载功能
2017/02/21 PHP
两个SUBMIT按钮,如何区分处理
2006/08/22 Javascript
Extjs中ComboBoxTree实现的下拉框树效果(自写)
2013/05/28 Javascript
Nodejs极简入门教程(一):模块机制
2014/10/25 NodeJs
jQuery实现平滑滚动页面到指定锚点链接的方法
2015/07/15 Javascript
基于jQuery实现淡入淡出效果轮播图
2020/07/31 Javascript
js倒计时简单实现代码
2016/08/11 Javascript
如何使用headjs来管理和异步加载js
2016/11/29 Javascript
javascript滚轮事件基础实例讲解(37)
2017/02/14 Javascript
微信小程序checkbox组件使用详解
2018/01/31 Javascript
node 使用 async 控制并发的方法
2018/05/07 Javascript
vue指令只能输入正数并且只能输入一个小数点的方法
2018/06/08 Javascript
详解Vue中组件的缓存
2019/04/20 Javascript
使用Node.js写一个代码生成器的方法步骤
2019/05/10 Javascript
JS数组属性去重并校验重复数据
2020/01/10 Javascript
vue中组件通信详解(父子组件, 爷孙组件, 兄弟组件)
2020/07/27 Javascript
JavaScript日期库date-fn.js使用方法解析
2020/09/09 Javascript
详解Python的Django框架中的模版相关知识
2015/07/15 Python
Python中方法链的使用方法
2016/02/23 Python
Python用Bottle轻量级框架进行Web开发
2016/06/08 Python
python利用正则表达式排除集合中字符的功能示例
2017/10/10 Python
Pycharm 创建 Django admin 用户名和密码的实例
2018/05/30 Python
解决Pycharm下面出现No R interpreter defined的问题
2018/10/29 Python
python中的函数递归和迭代原理解析
2019/11/14 Python
Python -m参数原理及使用方法解析
2020/08/21 Python
师范学院毕业生求职信范文
2013/12/26 职场文书
党支部特色活动方案
2014/08/20 职场文书
交通事故委托书范本
2014/09/28 职场文书
关于运动会广播稿300字
2014/10/05 职场文书
现实表现材料范文
2014/12/23 职场文书
毕业实习指导教师评语
2014/12/31 职场文书
社区党支部公开承诺书
2015/04/29 职场文书
三好学生主要事迹怎么写
2015/11/03 职场文书
python全面解析接口返回数据
2022/02/12 Python