获取Canvas当前坐标系矩阵
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当前坐标系矩阵的更多相关文章
- 软件项目技术点(2)——Canvas之获取Canvas当前坐标系矩阵
AxeSlide软件项目梳理 canvas绘图系列知识点整理 前言 在我的另一篇博文 Canvas坐标系转换 中,我们知道了所有的平移缩放旋转操作都会影响到画布坐标系.那在我们对画布进行了一系列操 ...
- 关于Canvas的坐标系
注意Canvas的坐标系应该是这样子的: 看下面的例子: 最后的显示效果是:
- 如何获取canvas当前的缩放值
项目中一直有一个问题困扰着我,我们的画布可以缩放平移旋转,支持拖拽生成图形,生成手写笔迹,如果用户选择的线条粗细为5像素,那么即使画布缩放过绘制出的线条粗细也应该是视觉上的5px,所以再绘制时赋值给c ...
- 软件项目技术点(2)——Canvas之坐标系转换
AxeSlide软件项目梳理 canvas绘图系列知识点整理 默认坐标系与当前坐标系 canvas中的坐标是从左上角开始的,x轴沿着水平方向(按像素)向右延伸,y轴沿垂直方向向下延伸.左上角坐标为 ...
- 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 ...
- css3 matrix 2D矩阵和canvas transform 2D矩阵
一看到“2D矩阵”这个高大上的名词,有的同学可能会有种畏惧感,“矩阵”,看起来好高深的样子,我还是看点简单的吧.其实本文就很简单,你只需要有一点点css3 transform的基础就好. 没有前戏,直 ...
- iOS开发-获取子视图坐标系中Point、Rect在父视图坐标系中的实际值
iOS提供了方法来完成上述值得转换 convertRect:toView:, convertRect:FromView: convertPoint:toView: and convertPoint:f ...
- AxeSlide软件项目梳理
先介绍一下我负责的软件项目 AxeSlide斧子演示,估计大部分人没有听说过,但国外有一款叫Prezi的软件,应该有一部分人使用过. 这是我们产品的官网http://www.axeslide.com/ ...
- JavaScript 基于HTML5 canvas 获取文本占用的像素宽度
基于HTML5 canvas 获取文本占用的像素宽度 by:授客 QQ:1033553122 直接上代码 // 获取单行文本的像素宽度 getTextPixelWith(text, fontS ...
随机推荐
- 日期格式代码出现两次的错误 ORA-01810
错误的原因是使用了两次MM . 一.Oracle中使用to_date()时格式化日期需要注意格式码 如:select to_date('2005-01-01 11:11:21','yyyy-MM-dd ...
- 在传统.NET Framework 上运行ASP.NET Core项目
新的项目我们想用ASP.NET Core来开发,但是苦于我们历史的遗产很多,比如<使用 JavaScriptService 在.NET Core 里实现DES加密算法>,我们要估计等到.N ...
- Redis数据库
Redis是k-v型数据库的典范,设计思想及数据结构实现都值得学习. 1.数据类型 value支持五种数据类型:1.字符串(strings)2.字符串列表(lists)3.字符串集合(sets)4.有 ...
- 了解PHP中的Array数组和foreach
1. 了解数组 PHP 中的数组实际上是一个有序映射.映射是一种把 values 关联到 keys 的类型.详细的解释可参见:PHP.net中的Array数组 . 2.例子:一般的数组 这里,我 ...
- C#关于分页显示
---<PS:本人菜鸟,大手子还请高台贵手> 以下是我今天在做分页时所遇到的一个分页显示问题,使用拼写SQL的方式写的,同类型可参考哦~ ------------------------- ...
- WebLogic的安装和配置以及MyEclipse中配置WebLogic
WebLogic 中间件: 是基础软件的一大类,属于可复用软件的范畴,顾名思义,中间件属于操作系统软件与应用软件的中间,比如:JDK,框架,weblogic. weblogic与tomcat区别 : ...
- 游走 bzoj 3143
游走(2s 128MB)walk [问题描述] [输入格式] [输出格式] [样例输入] 3 3 2 3 1 2 1 3 [样例输出] 3.333 [样例说明] 题解: 主要算法:贪心:高斯消元: 题 ...
- CSS3自定义滚动条样式 -webkit-scrollbar(转)
有没有觉得浏览器自带的原始滚动条很不美观,同时也有看到很多网站的自定义滚动条显得高端,就连chrome32.0开发板都抛弃了原始的滚动条,美观多了.那webkit浏览器是如何自定义滚动条的呢? 前言 ...
- 检查sql执行效率
SELECT SUBSTRING(ST.text, ( QS.statement_start_offset / 2 ) + 1, ( ( CASE statem ...
- photoshop:无法完成请求 因为暂存盘已满
今天photoshop打开一个问题,提醒:无法完成请求因为暂存盘已满 不用担心这个问题很好解决可能是你做的图比较大并不需要清理C盘空间 选择:编辑→首选项→暂存盘 设置第一暂存盘为D盘或E盘 总之 第 ...