首页前端开发HTML获取Canvas当前坐标系矩阵 - 方帅 -

获取Canvas当前坐标系矩阵 - 方帅 -

时间2024-01-26 16:39:02发布访客分类HTML浏览973
导读:收集整理的这篇文章主要介绍了html5教程-获取Canvas当前坐标系矩阵 - 方帅 -,觉得挺不错的,现在分享给大家,也给大家做个参考。小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。 获取Can...
收集整理的这篇文章主要介绍了html5教程-获取Canvas当前坐标系矩阵 - 方帅 -,觉得挺不错的,现在分享给大家,也给大家做个参考。小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

获取Canvas当前坐标系矩阵 前言

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

具体代码

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

  1 window.TrackTransform = function () {
      2     VAR svg = document.createElementNS("https://www.w3.org/2000/svg", 'svg');
      3     var xform = svg.createSVGMatrix();
      4     var savedTransforms = [];
  5     this.trackTransform=function(ctx) {
  6           7         ctx.getTransform = function () {
     return xform;
 }
    ;
      8           9         var save = ctx.save;
 10         ctx.save = function () {
     11             savedTransforms.push(xform.translate(0, 0));
     12             return save.call(ctx);
 13         }
    ;
     14         var reStore = ctx.restore;
 15         ctx.restore = function () {
     16             xform = savedTransforms.pop();
     17             return restore.call(ctx);
 18         }
    ;
     19          20         var scale = ctx.scale;
 21         ctx.scale = function (sx, sy) {
     22             xform = xform.scaleNonUniform(sx, sy);
     23             return scale.call(ctx, sx, sy);
 24         }
    ;
     25         var rotate = ctx.rotate;
 26         ctx.rotate = function (deg) {
     27              28             var radians = deg * Math.PI / 180;
     29             xform = xform.rotate(deg);
     30             return rotate.call(ctx, radians);
 31         }
    ;
     32         var translate = ctx.translate;
 33         ctx.translate = function (dx, dy) {
     34             xform = xform.translate(dx, dy);
     35             return translate.call(ctx, dx, dy);
 36         }
    ;
     37         var transform = ctx.transform;
 38         ctx.transform = function (a, b, c, d, e, f) {
     39             var m2 = svg.createSVGMatrix();
     40             m2.a = a;
     m2.b = b;
     m2.c = c;
     m2.d = d;
     m2.e = e;
     m2.f = f;
     41             xform = xform.multiply(m2);
     42             return transform.call(ctx, a, b, c, d, e, f);
 43         }
    ;
     44         var setTransform = ctx.setTransform;
 45         ctx.setTransform = function (a, b, c, d, e, f) {
     46             xform.a = a;
     47             xform.b = b;
     48             xform.c = c;
     49             xform.d = d;
     50             xform.e = e;
     51             xform.f = f;
     52             return setTransform.call(ctx, a, b, c, d, e, f);
 53         }
    ;
     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         }
     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         }
     66         var clearRect = ctx.clearRect;
 67         ctx.clearRect = function (x, y, w, h) {
     68             ctx.save();
     69             ctx.setTransform(1, 0, 0, 1, 0, 0);
     70             clearRect.call(ctx, x, y, w, h);
     71             ctx.restore();
 72         }
 73     }
 74 }
    

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

TrackTransform类使用

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

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

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

1 创建矩阵对象xform
  2     var svg = document.createElementNS("https://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。

11transformedPoint方法
 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则是通过一种矩阵算法来进行运算得到相应的变形的效果的。矩阵的一些基本算法就不多总结了,以前上课就学过了,网上也有不少讲解。

12transformedPoint2方法
 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当前坐标系矩阵 前言

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

具体代码

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

  1 window.TrackTransform = function () {
      2     var svg = document.createElementNS("https://www.w3.org/2000/svg", 'svg');
      3     var xform = svg.createSVGMatrix();
      4     var savedTransforms = [];
  5     this.trackTransform=function(ctx) {
  6           7         ctx.getTransform = function () {
     return xform;
 }
    ;
      8           9         var save = ctx.save;
 10         ctx.save = function () {
     11             savedTransforms.push(xform.translate(0, 0));
     12             return save.call(ctx);
 13         }
    ;
     14         var restore = ctx.restore;
 15         ctx.restore = function () {
     16             xform = savedTransforms.pop();
     17             return restore.call(ctx);
 18         }
    ;
     19          20         var scale = ctx.scale;
 21         ctx.scale = function (sx, sy) {
     22             xform = xform.scaleNonUniform(sx, sy);
     23             return scale.call(ctx, sx, sy);
 24         }
    ;
     25         var rotate = ctx.rotate;
 26         ctx.rotate = function (deg) {
     27              28             var radians = deg * Math.PI / 180;
     29             xform = xform.rotate(deg);
     30             return rotate.call(ctx, radians);
 31         }
    ;
     32         var translate = ctx.translate;
 33         ctx.translate = function (dx, dy) {
     34             xform = xform.translate(dx, dy);
     35             return translate.call(ctx, dx, dy);
 36         }
    ;
     37         var transform = ctx.transform;
 38         ctx.transform = function (a, b, c, d, e, f) {
     39             var m2 = svg.createSVGMatrix();
     40             m2.a = a;
     m2.b = b;
     m2.c = c;
     m2.d = d;
     m2.e = e;
     m2.f = f;
     41             xform = xform.multiply(m2);
     42             return transform.call(ctx, a, b, c, d, e, f);
 43         }
    ;
     44         var setTransform = ctx.setTransform;
 45         ctx.setTransform = function (a, b, c, d, e, f) {
     46             xform.a = a;
     47             xform.b = b;
     48             xform.c = c;
     49             xform.d = d;
     50             xform.e = e;
     51             xform.f = f;
     52             return setTransform.call(ctx, a, b, c, d, e, f);
 53         }
    ;
     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         }
     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         }
     66         var clearRect = ctx.clearRect;
 67         ctx.clearRect = function (x, y, w, h) {
     68             ctx.save();
     69             ctx.setTransform(1, 0, 0, 1, 0, 0);
     70             clearRect.call(ctx, x, y, w, h);
     71             ctx.restore();
 72         }
 73     }
 74 }
    

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

TrackTransform类使用

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

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

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

1 创建矩阵对象xform
  2     var svg = document.createElementNS("https://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。

11transformedPoint方法
 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则是通过一种矩阵算法来进行运算得到相应的变形的效果的。矩阵的一些基本算法就不多总结了,以前上课就学过了,网上也有不少讲解。

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

 

觉得可用,就经常来吧! 欢迎评论哦! html5教程,巧夺天工,精雕玉琢。小宝典献丑了!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

APIClassdivpost-format-galleryRestthis数组

若转载请注明出处: 获取Canvas当前坐标系矩阵 - 方帅 -
本文地址: https://pptw.com/jishu/587011.html
Canvas坐标系转换 Canvas绘图之平移translate、旋转rotate、缩放scale

游客 回复需填写必要信息