HTML5 canvas transform与矩阵
首先,我们看一下w3school上的例子:
Javascript语法:context.transform( a , b , c , d , e , f );
定义与用法:画布上的每个对象都拥有一个当前的变换矩阵。而transform则是用来定义一个新的矩阵,来替换原来的变换矩阵。
六个参数,对应的矩阵就是:
在这里,我说一下变换矩阵要用到的关于矩阵的知识,一个图形,在画布上无非是移动,缩小放大,还有旋转,斜切,等等。
PS告诉我们,无论多复杂的图形,都是由一个个点组成的,变换矩阵要做的,无非是应用一定的算法,把一个图形上的一个点,映射到另一个点上。
那么,我们就可以得出以下公式:
根据中间那个矩阵的不同,我们就可以得到不同的变换效果。
矩阵乘法是这样定义的:假设有两个矩阵A和B,如果要通过A*B得到C,那么矩阵A的列数必须与矩阵B的行数相同,方才能进行运算。得到的新的矩阵的第 i 行 ,第 j 列的值 就是A的第 i 行 与 B 的第 j 列相对应的值相乘,然后相加的结果。
首先,我们来看看图形在画布上的移动。
算法很简单:
X’ = X + a
Y’ = Y + b
这样就把点(X,Y)移动到了(X’,Y’)。
对应的变换的矩阵就是
X’ 1 0 a X
Y’ 0 1 b * Y
1 0 0 1 1
X’ = 1*X + 0*Y + a*1;
Y’ = 0*X + 1*Y + b*1;
1 = 0*X + 0*Y + 1*1;
那么,对应的JS代码就是context.transform(1,0,0,1,a,b);
再看缩小放大,算法也很简单:
X’ = X*a;
Y’ = Y*b;
Canvas是按照一定的算法来画图的,也就是说,Canvas画出来的图都是矢量图,不会因为放大与缩小而失真,那么,Canvas是如何实现放大与缩小的呢?
其实,无非是对X轴,Y轴乘以各相对应的缩放因子,然后进行路径的描写,填充。
对应的变换矩阵就是:
X’ a 0 0 X
Y’ 0 b 0 Y
1 0 0 1 1
X’ = 1*X + 0 * Y + 0*1;
Y’ = 0*X + b*Y + 0*1;
1 = 0*X + 0*Y + 1*1;
对应的JS代码就是 context.transform(a,0,0,b,0,0);
再看看旋转,算法
通过图可以看出来,B点是通过把A点旋转θ度得来的,即
X’ = cos(a +θ) * r
Y’ = sin(a +θ) * r
根据三角函数公式:cos(α+β)=cosαcosβ-sinαsinβ
可得 X’ = r*cosa*cosθ–r* sina * sinθ= X * cosθ – Y * sinθ;
同理可得 Y’ = x*sinθ+y*cosθ;
X’ cosθ -sinθ 0 X
Y’ sinθ cosθ 0 Y
1 0 0 1 1
对应的JS代码就是 context.transform(Math.cos(θ * Math.PI/180) , Math.sin(θ*Math.PI/180) , - Math.sin(θ*Math.PI/180) , Math.cos(θ * Math.PI/180) , 0 , 0 );
矩阵的好处就是用6个参数就可以表达出不同的算法来,虽然麻烦了点,但这样做是值得的。
以此类推,斜切也是一样的,只是算法要复杂一些。
记住,在canvas中先确定坐标系,再画图,其实,平移,放大缩小,斜切,旋转,都是针对坐标系的,应用不同的坐标系,就可以画出不同的图形来。