html5 canvas获取坐标系,获取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。

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

6b070e64d49d1398921fb78143f62e77.png

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

1700043a15f6d5ae3b3dced1ffe4dbc1.png

svgmatrix介绍

这里再简单解释下svgmatrix:

svgmatrix的方法和属性如下图(具体可参阅:https://developer.mozilla.org/en-us/docs/web/api/svgmatrix)

790e0bac19164c594412b3c157f12f4a.png

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值