## 坐标变换 在Canvas中,变形包括移动、旋转、缩放、变形,跟CSS3中的2D转换类似。 (注意:原有内容不会受变形的影响,变形只是坐标变换,新绘制的图形就是在变换后的坐标轴里绘制的。) 下面我们来逐一的认识。 **一、移动(translate)** canvas的移动是指移动 canvas 和它的原点到一个不同的位置。 ``` translate(x, y) ``` translate 方法接受两个参数。x 是左右偏移量,y 是上下偏移量,如右图所示。 实例:canvas-demo/translate.html: ``` cxt.fillRect(0,0,100,100); cxt.save(); cxt.translate(60,60); cxt.fillStyle="red"; cxt.fillRect(0,0,100,100); cxt.restore(); ``` **二、旋转(rotate)** 用于以原点为中心旋转 canvas。 ``` rotate(angle) ``` 这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。 实例:canvas-demo/tranform-rotate.html: ``` cxt.beginPath(); cxt.moveTo(0,50); cxt.lineTo(100,50); cxt.stroke(); cxt.save(); cxt.rotate(Math.PI/12); cxt.strokeStyle="red"; cxt.beginPath(); cxt.moveTo(0,50); cxt.lineTo(100,50); cxt.stroke(); cxt.restore(); ``` **三、缩放(scale)** ``` scale(x, y) ``` scale 方法接受两个参数。x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。值比 1.0 小表示缩小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。 实例:canvas-demo/scale.html: ``` cxt.fillRect(20,20,50,50); cxt.save(); cxt.scale(.5,.5); cxt.fillStyle="red"; cxt.fillRect(20,20,50,50); ``` **四、变形** 区别: transform()方法的行为相对于由 rotate(),scale(), translate(), or transform() 完成的其他变换。例如:如果我们已经将绘图设置为放到两倍,则 transform() 方法会把绘图放大两倍,那么我们的绘图最终将放大四倍。这一点和之前的变换是一样的。 但是setTransform()不会相对于其他变换来发生行为。它的参数也是六个,context.setTransform(a,b,c,d,e,f),与transform()一样。 ``` transform(m11, m12, m21, m22, dx, dy) ``` 参数: m11 水平缩放绘图。 默认值1 m12 水平倾斜绘图。 默认值0 m21 垂直倾斜绘图。 默认值0 m22 垂直缩放绘图。 默认值1 dx 水平移动绘图。 默认值0 dy 垂直移动绘图。 默认值0 这个方法必须将当前的变形矩阵乘上下面的矩阵: ``` m11 m21 dx m12 m22 dy 0 0 1 ``` 注意:该变换只会影响 transform() 方法调用之后的绘图。 ``` setTransform(m11, m12, m21, m22, dx, dy) ``` 参数: m11 水平缩放绘图。 默认值1 m12 水平倾斜绘图。 默认值0 m21 垂直倾斜绘图。 默认值0 m22 垂直缩放绘图。 默认值1 dx 水平移动绘图。 默认值0 dy 垂直移动绘图。 默认值0 **五、transform和translate、scale、rotate** **5.1 translate** ``` cxt.translate(dx,dy) ``` cxt.transform (1,0,0,1,dx,dy)代替cxt.translate(dx,dy)。 也可以使用 cxt.transform(0,1,1,0.dx,dy)代替。 **5.2 scale** ``` cxt.scale(m11, m22): ``` 也即是说可以使用 cxt.transform(m11,0,0,m22,0,0)代替cxt.scale(m11,m22); 也可以使用cxt.transform (0,m22,m11,0, 0,0); **5.3 rotate** ``` rotate(θ) ``` 也即是说可以用 - `cxt.transform(Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180)` - `Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180),0,0)`可以替代`context.rotate(θ)`。 - 也可以使用 cxt.transform(-Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180), Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180), 0,0)替代。