玩转canvas之你不知道的transform

transform

canvas中的transform和css3中的transform在所表达的含义是相同的,都是对当前的元素/图像的的环境进行转换,也就是我们熟知的平移,旋转,缩放。虽然使用方法是相同的,但所实现出来的效果却是不同的。

canvas-transform

实现的效果差异

css3的transform

在css3中的transform,我们设置的平移,旋转,缩放的值,就是当前元素的平移,旋转,缩放的值。
例如

el.style.transform = 'translate(100px,0) scale(1.5) rotate(90deg)' 
el.style.transform = 'translate(50px,0) scale(1.2) rotate(180deg)' 

最终实现的效果是
元素在x轴向右平移50px,x与y方向缩放1.2倍,顺时针旋转180度。

canvas的tranform

ctx.scale(2)
ctx.rotate(Math.PI/4)
ctx.tanslate(20,20)
ctx.scale(1.5)
ctx.rotate(Math.PI/2)
ctx.tanslate(40,0)

按照css3的理解,上面的代码应该实现的效果是
元素在x轴向右平移20px,x与y方向缩放2倍,顺时针旋转45度。
但实际上,canvas中的转换是叠加性的,也就是说,实际的转换效果应该是以往设置的转换效果的累加,因此,上面代码真正的转换效果是
元素在x轴向右平移60px,y轴向下平移20px;x与y方向缩放3倍,顺时针旋转135度。

并且相对于css3中transform是对于单个元素的转换
canvas实际上是对画布的转换,平移实际是对画布原点的重新定位,旋转实际是对画布位置的旋转,缩放实际是对画布大小的缩放,通过对画布的转换来实现对绘制图像的转换,而且这种转换对接下来绘制的所有图像都是成立的,除非我们重置矩阵

canvas转换的缺点

在css3中的transform我们是可以通过js来获取当前元素的转换值,但是在canvas中,我们是无法获取当前的转换值的,也就是说我们无法知道,我们现在的平移值,缩放值以及旋转值都是无法获取的。这对我们绘图也是有一定障碍的,

纠错

这里对上面这个问题进行纠错,实际上canvas中有一个方法可以获取到当前的实际转换矩阵的

ctx.getTransform()

这个方法会返回给我们一个matrix对象,对象包括了我们当前的转换矩阵值以及matrix矩阵

canvas转换矩阵的重置

因为canvas转换效果是叠加的,而我们又无法获取canvas转换的实际值,所以需要对当前转换值进行重置是很困难的,这个时候就可以使用canvas api中给出的转换矩阵的重置方法来重置当前的转换矩阵。

ctx.setTransform(a,b,c,d,e,f)

这个方法可以帮助我们将当前的转换矩阵重置为单元矩阵,然后运行ctx.transform(a,b,c,d,e,f)

canvas中转换矩阵的b和c

我们知道canvas中的transform方法有6个参数,并通过该方法来添加一个新的变换矩阵。

参数描述
a水平缩放绘图。
b水平倾斜绘图。
c垂直倾斜绘图。
d垂直缩放绘图。
e水平移动绘图。
f垂直移动绘图。

可以发现,这里面会有b水平倾斜绘图与c垂直倾斜绘图这两个参数,但是却没有设置旋转的参数。矩阵实际上也是通过b和c来实现旋转的,但其实际的意义是x与y轴的倾斜。也是css3中transform的skew属性,canvas转换矩阵通过对xy轴同步倾斜来实现旋转,如果xy倾斜不同步则会导致图像失真的情况
例如

var ctx=c.getContext("2d");
ctx.fillStyle="yellow";
ctx.fillRect(0,0,250,100)
ctx.transform(1,0.5,-0.3,1,30,10);
ctx.fillStyle="red";
ctx.fillRect(0,0,250,100);

在这里插入图片描述
我们可以看到,转换的矩形已经不是一个正经的矩形了。因此对矩形的旋转,如何b与c的值不符合匹配,图像就会失真。

总结

canvas中的transform与我们常用的css3中的transform还是有一定不同的,如果你希望可以获取实际的canvastransform,你可以用一个对象来记录所有操作的转换的值的修改,从而获取真实的transform属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值