AxeSlide软件项目梳理   canvas绘图系列知识点整理

前言

在我的另一篇博文 Canvas坐标系转换 中,我们知道了所有的平移缩放旋转操作都会影响到画布坐标系。那在我们对画布进行了一系列操作之后,怎么再知道当前矩阵数据状态呢。

具体代码

首先请看下面的一段代码(下文具体解释代码作用):

 window.TrackTransform = function () {
var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
var xform = svg.createSVGMatrix();
var savedTransforms = [];
this.trackTransform=function(ctx) { ctx.getTransform = function () { return xform; }; var save = ctx.save;
ctx.save = function () {
savedTransforms.push(xform.translate(0, 0));
return save.call(ctx);
};
var restore = ctx.restore;
ctx.restore = function () {
xform = savedTransforms.pop();
return restore.call(ctx);
}; var scale = ctx.scale;
ctx.scale = function (sx, sy) {
xform = xform.scaleNonUniform(sx, sy);
return scale.call(ctx, sx, sy);
};
var rotate = ctx.rotate;
ctx.rotate = function (deg) { var radians = deg * Math.PI / 180;
xform = xform.rotate(deg);
return rotate.call(ctx, radians);
};
var translate = ctx.translate;
ctx.translate = function (dx, dy) {
xform = xform.translate(dx, dy);
return translate.call(ctx, dx, dy);
};
var transform = ctx.transform;
ctx.transform = function (a, b, c, d, e, f) {
var m2 = svg.createSVGMatrix();
m2.a = a; m2.b = b; m2.c = c; m2.d = d; m2.e = e; m2.f = f;
xform = xform.multiply(m2);
return transform.call(ctx, a, b, c, d, e, f);
};
var setTransform = ctx.setTransform;
ctx.setTransform = function (a, b, c, d, e, f) {
xform.a = a;
xform.b = b;
xform.c = c;
xform.d = d;
xform.e = e;
xform.f = f;
return setTransform.call(ctx, a, b, c, d, e, f);
};
var pt = svg.createSVGPoint();
//通过原坐标系点x,y求对应当前坐标系的坐标值
ctx.transformedPoint = function (x, y) {
pt.x = x; pt.y = y;
return pt.matrixTransform(xform.inverse());
}
var pt2 = svg.createSVGPoint();
//当前坐标系中的的xy还原到原坐标系坐标值
ctx.transformedPoint2 = function (x, y) {
pt2.x = x; pt2.y = y;
return pt2.matrixTransform(xform);
}
var clearRect = ctx.clearRect;
ctx.clearRect = function (x, y, w, h) {
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
clearRect.call(ctx, x, y, w, h);
ctx.restore();
}
}
}

代码中主要定义了一个类TrackTransform,重写了CanvasRenderingContext2D对象的save,restore,scale,rotate,translate,transform,setTransform,clearRect方法。

TrackTransform类使用

如何使用window.TrackTransform类呢?通过以下两句代码,变量contex的转换方法即进行了重写。

 //初始化矩阵转换; context为 getContext("2d")所得的CanvasRenderingContext2D对象。
var track = new TrackTransform();
track.trackTransform(context);

方法详解

具体解释上面各行代码的作用

1 创建矩阵对象xform

 2     var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
3 var xform = svg.createSVGMatrix();

第2行代码通过createElementNS创建与获取到SVG对象。

第3行代码通过createSVGMatrix()方法创建并返回一个新的2x3的矩阵SVGMatrix矩阵对象赋值到xform。

我们在浏览器中打开开发者工具,到控制台可以输出矩阵看看初始值。

a b c d e f 这6个值就对应了我们在介绍transform方法的那6个参数。这个2x3的矩阵为了方便矩阵运算我们把它扩展为一个3x3的矩阵。

svgMatrix介绍

这里再简单解释下svgMatrix:

svgMatrix的方法和属性如下图(具体可参阅:https://developer.mozilla.org/en-US/docs/Web/API/SVGMatrix)

2 save方法

             savedTransforms.push(xform.translate(0, 0));
return save.call(ctx);

先将xform存储在一个数组savedTransforms中,然后调用原API方法。

3 restore方法

            xform = savedTransforms.pop();
return restore.call(ctx);

从savedTransforms数组中去除最后一个对象,并将其赋值到变量xform,然后调用原API方法。

4 scale方法

            xform = xform.scaleNonUniform(sx, sy);
return scale.call(ctx, sx, sy);

维护xform,将其缩放,然后调用原API方法。

5 rotate方法

        var radians = deg * Math.PI / 180;
xform = xform.rotate(deg);
return rotate.call(ctx, radians);

将角度转为弧度,维护xform将其进行旋转变换,然后调用原API方法。

6 translate方法

            xform = xform.translate(dx, dy);
return translate.call(ctx, dx, dy);

维护xform将其进行平移变换,然后调用原API方法。

7 transform方法

            var m2 = svg.createSVGMatrix();
m2.a = a; m2.b = b; m2.c = c; m2.d = d; m2.e = e; m2.f = f;
xform = xform.multiply(m2);
return transform.call(ctx, a, b, c, d, e, f);
首先声明一个新的矩阵m2,m2赋值为要进行变换的6个参数值,然后xform和m2执行矩阵乘法运算,运算结果赋值到xform将其维护。然后调用原API方法。

8 setTransform方法

            xform.a = a;
xform.b = b;
xform.c = c;
xform.d = d;
xform.e = e;
xform.f = f;
return setTransform.call(ctx, a, b, c, d, e, f);

维护xform的值,然后调用原API方法。

9 clearRect方法

            ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
clearRect.call(ctx, x, y, w, h);
ctx.restore();

首先保存context的当前状态,将画布重置到原始状态(可以理解为坐标系重置到默认坐标系),然后调用原API方法清除画布指定范围内容。清除后调用restore恢复Canvas之前保存的状态。

10 getTeansform方法

ctx.getTransform = function () { return xform; };

接下来介绍的三个方法都是原API没有的。getTeansform直接返回xform,可以看到代表画布矩阵的6个值abcdef。

11 transformedPoint方法

54         var pt = svg.createSVGPoint();
55 //通过原坐标系点x,y求对应当前坐标系的坐标值
56 ctx.transformedPoint = function (x, y) {
57 pt.x = x; pt.y = y;
58 return pt.matrixTransform(xform.inverse());
59 }

通过原坐标系点x,y求对应当前坐标系的坐标值。

createSVGPoint创建的点为(0,0),xform.inverse()是求xform的逆矩阵。MatrixTransform则是通过一种矩阵算法来进行运算得到相应的变形的效果的。矩阵的一些基本算法就不多总结了,以前上课就学过了,网上也有不少讲解。

12 transformedPoint2方法

60         var pt2 = svg.createSVGPoint();
61 //当前坐标系中的的xy还原到原坐标系坐标值
62 ctx.transformedPoint2 = function (x, y) {
63 pt2.x = x; pt2.y = y;
64 return pt2.matrixTransform(xform);
65 }

当前坐标系中的的x,y还原到原坐标系坐标值。

软件项目技术点(2)——Canvas之获取Canvas当前坐标系矩阵的更多相关文章

  1. 软件项目技术点(5)——在canvas上绘制动态网格线

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 grid类的实现 当鼠标在画布上缩放时,网格能跟着我的鼠标滚动而相应的有放大缩小的效果. 下面是具体实现的代码,draw函数里计算出大 ...

  2. 软件项目技术点(7)——在canvas上绘制自定义图形

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 图形种类 目前我们软件可以绘制出来的形状有如下这几种,作为开发者我们一直想支持用户可以拖拽的类似word里面图形库,但目前还没有找到比 ...

  3. 软件项目技术点(8)—— canvas调用drawImage绘制图片

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 html5中标签canvas,函数drawImage(): 使用drawImage()方法绘制图像.绘图环境提供了该方法的三个不同版本 ...

  4. 软件项目技术点(6)——结合鼠标操作绘制动态canvas画布

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 我们创建一个类封装了所有鼠标需要处理的事件. export class MouseEventInfo { el: HTMLElemen ...

  5. 软件项目技术点(2)——Canvas之平移translate、旋转rotate、缩放scale

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 画布操作介绍 画布绘图的环境通过translate(),scale(),rotate(), setTransform()和transf ...

  6. 软件项目技术点(2)——Canvas之坐标系转换

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 默认坐标系与当前坐标系 canvas中的坐标是从左上角开始的,x轴沿着水平方向(按像素)向右延伸,y轴沿垂直方向向下延伸.左上角坐标为 ...

  7. 软件项目技术点(1)——d3.interpolateZoom-在两个点之间平滑地缩放平移

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 软件参考d3的知识点 我们在软件中主要用到d3.js的核心函数d3.interpolateZoom - 在两个点之间平滑地缩放平移.请 ...

  8. 软件项目技术点(1)——Tween算法及缓动效果

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 Tween算法及缓动效果 软件里在切换步序时需要有过渡动画效果,从当前位置的画面缓动到目标位置的画面.动画效果可重新查看文章系列第一篇 ...

  9. 软件项目技术点(9)——如何将gif动态图拆分绘制

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 背景介绍 我们的软件支持插入gif图片,并且展示在软件里是动态的,例如插入下面这张gif图. 在软件里显示的同样是这样的动态效果: 那 ...

随机推荐

  1. JDBC_设计架构_驱动类加载_建立Connection_效率测试

    JDBC(Java DataBase Connection) 访问数据库流程:驱动管理器--连接数据库--sql语句--结果集 装载mysql驱动 Class.forName("com.jd ...

  2. Wiki凭什么持续得到开发人员和团队的喜爱

    大家好,我是华为云DevCloud项目管理服务的产品经理恒少,作为布道师和产品经理,出差各地接触客户是常态,线下和华为云的客户交流.布道.技术沙龙. 但是线下交流,覆盖的用户总还是少数.我希望借助线上 ...

  3. eclipse的一些快捷键记录

    查看所有快捷键:Ctrl + Shift + L Ctrl + Shift + F:格式化(关闭搜狗输入法的所有快捷键) Alt + /:智能提示,自动补全 Ctrl + / :添加单行注释(取消:C ...

  4. Mac下安装配置Python2和Python3并相互切换使用 转

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u014259820/article/details/81023224 安装Python2 Mac系统 ...

  5. <转> django模板语言filter方法

    Django的模板是一个简单的文本文件,它可以生成任何文本格式(HTML.XML.CSV等),在本文开始之前先看一个Django模板的例子: 从这个例子中可以看到,模板标签可以是单独出现的,如exte ...

  6. git 各个区的区别

    Git有三大区(工作区.暂存区.版本库)以及几个状态(untracked.unstaged.uncommited) 把文件往Git版本库里添加的时候,是分两步执行的: 第一步是用 git add 把文 ...

  7. Nginx负载均衡详解

     upstream mysvr {  server 192.168.10.121:3333; server 192.168.10.122:3333; } server { .... location ...

  8. 【算法笔记】B1035 插入与归并

    1035 插入与归并 (25 分) 根据维基百科的定义: 插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列.每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置.如此迭代直 ...

  9. 隐藏入口文件的apache配置

    AllowOverride None->AllowOverride All #LoadModule rewrite_module modules/mod_rewrite.so->LoadM ...

  10. webstorm预览时把浏览器地址localhost改成IP

    可以通过 File --> Setting,搜索 deployment 点击 + 号 然后输入一个名称,选择:Local or mounted folder,点击 OK 接下来选择你的本地项目路 ...