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还原到原坐标系坐标值。

获取Canvas当前坐标系矩阵的更多相关文章

  1. 软件项目技术点(2)——Canvas之获取Canvas当前坐标系矩阵

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 前言 在我的另一篇博文 Canvas坐标系转换 中,我们知道了所有的平移缩放旋转操作都会影响到画布坐标系.那在我们对画布进行了一系列操 ...

  2. 关于Canvas的坐标系

    注意Canvas的坐标系应该是这样子的: 看下面的例子: 最后的显示效果是:

  3. 如何获取canvas当前的缩放值

    项目中一直有一个问题困扰着我,我们的画布可以缩放平移旋转,支持拖拽生成图形,生成手写笔迹,如果用户选择的线条粗细为5像素,那么即使画布缩放过绘制出的线条粗细也应该是视觉上的5px,所以再绘制时赋值给c ...

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

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

  5. Canvas里绘制矩阵文字

    效果如下 实现方法: [ [0,0,1,1,1,0,0], [0,1,1,0,1,1,0], [1,1,0,0,0,1,1], [1,1,0,0,0,1,1], [1,1,0,0,0,1,1], [1 ...

  6. css3 matrix 2D矩阵和canvas transform 2D矩阵

    一看到“2D矩阵”这个高大上的名词,有的同学可能会有种畏惧感,“矩阵”,看起来好高深的样子,我还是看点简单的吧.其实本文就很简单,你只需要有一点点css3 transform的基础就好. 没有前戏,直 ...

  7. iOS开发-获取子视图坐标系中Point、Rect在父视图坐标系中的实际值

    iOS提供了方法来完成上述值得转换 convertRect:toView:, convertRect:FromView: convertPoint:toView: and convertPoint:f ...

  8. AxeSlide软件项目梳理

    先介绍一下我负责的软件项目 AxeSlide斧子演示,估计大部分人没有听说过,但国外有一款叫Prezi的软件,应该有一部分人使用过. 这是我们产品的官网http://www.axeslide.com/ ...

  9. JavaScript 基于HTML5 canvas 获取文本占用的像素宽度

    基于HTML5 canvas 获取文本占用的像素宽度   by:授客 QQ:1033553122 直接上代码   // 获取单行文本的像素宽度 getTextPixelWith(text, fontS ...

随机推荐

  1. jQuery学习之路(6)- 简单的表格应用

    ▓▓▓▓▓▓ 大致介绍 在CSS技术之前,网页的布局基本都是依靠表格制作,当有了CSS之后,表格就被很多设计师所抛弃,但是表格也有他的用武之地,比如数据列表,下面以表格中常见的几个应用来加深对jQue ...

  2. UWP开发之Mvvmlight实践九:基于MVVM的项目架构分享

    在前几章介绍了不少MVVM以及Mvvmlight实例,那实际企业开发中将以那种架构开发比较好?怎样分层开发才能节省成本? 本文特别分享实际企业项目开发中使用过的项目架构,欢迎参照使用!有不好的地方欢迎 ...

  3. 从啥也不会到可以胜任最基本的JavaWeb工作,推荐给新人的学习路线(二)

    在上一节中,主要阐述了JavaScript方面的学习路线.先列举一下我朋友的经历,他去过培训机构,说是4个月后月薪过万,虽然他现在还未达到这个指标. 培训机构一般的套路是这样:先教JavaSE,什么都 ...

  4. ASP.NET Core 中文文档 第五章 测试(5.2)集成测试

    原文: Integration Testing 作者: Steve Smith 翻译: 王健 校对: 孟帅洋(书缘) 集成测试确保应用程序的组件组装在一起时正常工作. ASP.NET Core支持使用 ...

  5. ASP.NET Core 中文文档 第四章 MVC(4.3)过滤器

    原文:Filters 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:何镇汐 ASP.NET MVC 过滤器 可在执行管道的前后特定阶段执行代码.过滤器可以配置为全局有效.仅对控 ...

  6. ASP.NET MVC5----常见的数据注解和验证

    只要一直走,慢点又何妨. 在使用MVC模式进行开发时,数据注解是经常使用的(模型之上操作),下面是我看书整理的一些常见的用法. 什么是验证,数据注解 验证 从全局来看,发现逻辑仅是整个验证的很小的一部 ...

  7. 从display:run-in;中学习新技能

    有时我们想在一行内显示一个标题,以及一段内容,虽然看起来比较简单,但是为了语义化用dl比较合适,但是它默认是block元素,改成inline?那么有多段呢?不就都跑上来了?用float?那问题也挺多. ...

  8. iOS之延时执行(睡眠)的几种方法

    1. 最直接的方法: [self performSelector:@selector(deleyMethod) withObject:nil afterDelay:1.0]; 此方式要求必须在主线程中 ...

  9. Android中通过ActionBar为标题栏添加搜索以及分享视窗

    在Android3.0之后,Google对UI导航设计上进行了一系列的改革,其中有一个非常好用的新功能就是引入的ActionBar,他用于取代3.0之前的标题栏,并提供更为丰富的导航效果.Action ...

  10. Linux实战教学笔记01:计算机硬件组成与基本原理

    标签(空格分隔): Linux实战教学笔记 第1章 如何学习Linux 要想学好任何一门学问,不仅要眼睛看,耳朵听,还要动手记,勤思考,多交流甚至尝试着去教会别人. 第2章 服务器 2.1 运维的基本 ...