根据上面的总结,我们使用 transform() 或 setTransform() 可以实现斜切效果:
// 水平斜切 ctx.transform(1, 0, k, 1, 0, 0) 或者 ctx.setTransform(1, 0, k, 1, 0, 0) // 垂直斜切 ctx.transform(1, k, 0, 1, 0, 0) 或者 ctx.setTransform(1, k, 0, 1, 0, 0) // 水平和垂直方向斜切 ctx.transform(1, k1, k2, 1, 0, 0) 或者 ctx.setTransform(1, k1, k2, 1, 0, 0)注意,其中 k 或者 k1 和 k2 是弧度值,来看个实例:
ctx.fillStyle = '#f36'; ctx.transform(1, Math.PI * 30 / 180, Math.PI * 30 / 180, 1, 0, 0); ctx.fillRect(0,0,100,100);上面的示例相当于CSS中的 transform: skew(30deg, 30deg) :
对称变换
除了上面讲到的四中基本变换外,事实上,我们还可以利用矩阵,进行对称变换。所谓对称变换,就是经过变化后的图像和原图像是关于某个对称轴是对称的。比如,某点 P0(x0,y0) 结过对称变换后得到 P(x,y) 。如果对称轴是 x 轴,那么:
x = x0 y = -y0用矩阵表示就是:
如果对称轴是 y 轴,那么:
x = -x0 y = y0对矩阵表示就是:
如果对称轴是 y = x ,如图:
那么:
很容易可以解得:
x = x0 y = y0用矩阵表示,就是:
同样的道理,如果对称轴是 y = -x ,那么用矩阵表示就是:
特殊地,如果对称轴是 y = kx ,如下图所示:
那么:
可以解得:
用矩阵表示:
当 k=0 时,即 y=0 ,也就是对称轴为 x 轴的情况;当 k 趋于无穷大时,即 x=0 ,也就是对称轴为 y 轴的情况;当 k=1 时,即 y=x ,也就是对称轴为 y=x 的情况;当 k=-1 时,即 y=-x ,也就是对称轴为 y=-x 的情况。不难验证,这和我们前面说到的四种具体情况是相吻合的。
如果对称轴是 y = kx + b 这样的情况,只需要在上面的基础上增加两次平移变换即可,即先将坐标原点移动到 (0,b) ,然后做上面的关于 y = kx 的对称变换,再然后将坐标原点移回到原来的坐标原点即可。用矩阵表示大致是这样的:
特别需要注意:在实际编程中,我们知道屏幕的 y 坐标的正向和数学中 y 坐标的正向刚好是相反的,所以在数学上 y=x 和屏幕上的 y=-x 才是真正的同一个东西,反之亦然。也就是说,如果要使图片在屏幕上看起来像按照数学意义上 y=x 对称,那么需要用这种转换:
要使用图片在屏幕上看起来像按照数学意义上 y=-x 对称,那么需要使用这种转换:
关于对称轴为 y=kx 或 y=kx+b 的情况,同样需要考虑这方面的问题。
对称变换在实际中,可以帮助我们实现图像的镜像效果,比如下面的这个小示例:
ctx.strokeStyle = '#f36'; ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(100, 100); ctx.lineTo(50, 150); ctx.closePath(); ctx.stroke(); ctx.setTransform(-1, 0, 0, -1, 220, 200); ctx.strokeStyle = '#00f'; ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(100, 100); ctx.lineTo(50, 150); ctx.closePath(); ctx.stroke();效果如下:
前面介绍了怎么使用矩阵实现不同的变换。从前面的示例当中,不难发现,像旋转变换,缩放变换都是围绕坐标原点来做的。但实际使用当中,我们很多时候需要的围绕某个点做旋转和缩放。比如说让一个正方形围绕其自身中心点做旋转。那这样的怎么使用矩阵来表示呢?接下来我们简单的来看一下。
如果是围绕某个点 (xp,yp) 顺时针旋转 θ ,那么可以用矩阵表示为:
可以简化为:
这里涉及到了矩阵的计算,这也就是为什么我要在前面花很大的篇幅来介绍矩阵的基础知识。如果你仔细看了上面的内容,那对于这样的矩阵计算就不是什么难度了。其实在整个过程,我们红历了三步。
第一步,下面的矩阵:
实现了将坐标原点移动到点 (xp,yp) 后, P(x0,y0) 的新坐标。接下来下面的矩阵是将第一步变换后的 P(x0,y0) 围绕新的坐标原点顺时针旋转 θ :
结过第二步的旋转变换之后,再将坐标原点移回到原来的坐标原点,用矩阵可以像下面这样表示: