canvas的translate、scale、rotate等方法

1.translate(x,y):平移,将画布的坐标原点向左右方向移动x,向上下方向移动y.canvas的默认位置是在(0,0).

4.transform():切变。所谓切变,其实就是把图像的顶部或底部推到一边。
第一条很好理解,就是要明确顺序。

canvas的转换不是针对整个canvas的,而是针对调用转换方法之后绘制的shapes或 paths。如下:

context.rotate(45 * Math.PI/180);
context.fillRect(50, 50, 50, 50);

顺序很重要,反了就没有旋转的效果了。

第二条,转换的时候,需要把转换的中心点移到shape的自身的中心,不然的话,请看下面这个例子(浅蓝色部分表示canvas):

context.fillRect(50, 50, 50, 50);

canvas的translate、scale、rotate等方法

这是没有转换的效果,接着来看旋转45°的效果:

context.rotate(45 * Math.PI/180);
context.fillRect(50, 50, 50, 50);

canvas的translate、scale、rotate等方法

可以看出,旋转的中心是canvas的左上角(scale()的中心也是左上角),也就是点(0,0),但是通常我们需要的是围绕自己的中心进行旋转,所以就有了第二条。

==========================================================================================
下面说说怎么移动中心点

假如fillRect(50, 50, 50, 50),那么这个矩形的中心点是(x + width/2, y +height/2),即(75, 75)。

上面刚说了,旋转的中心是canvas的左上角,我们要做的就是把(0, 0)移到(75, 75)的位置。

canvas的translate()方法可以使坐标系统的原点向上下左右移动。这正是我们需要的!

context.translate(x + width/2, y +height/2);

好了,中心点处理完了,还记得上面的第一条不,切记顺序,现在该画矩形了,fillRect()的参数 x 和 y现在是什么呢?

调用translate()之后,整个坐标系统都平移了,所以我们之前的fillRect(50, 50, 50,50),矩形的左上角不再是(50, 50)了,而是(-0.5 * width, -0.5 * height);

context.fillRect(-0.5 * width, -0.5 *height);

canvas的translate、scale、rotate等方法

==========================================================================================

再说下scale(),如果我们需要放大1倍,即 scale(2, 2);刚才也说了,缩放的中心点默认也是canvas的左上角,所以我们还是要进行坐标平移:

context.translate(x + width/2, y +height/2);
context.scale(2, 2);

接着画矩形,这里很容易出现幻觉,好像要画一个放大1倍后的矩形,其实不用的,该怎么画还是怎么画:

context.fillRect(50, 50, 50, 50);
 
-----------------------------------------------------------
 
对canvas的translate()方法的理解
  • canvas.save();//锁画布(为了保存之前的画布状态) 
  • canvas.translate(10, 10);//把当前画布的原点移到(10,10),后面的操作都以(10,10)作为参照点,默认原点为(0,0) 
  • drawScene(canvas); 
  • canvas.restore();//把当前画布返回(调整)到上一个save()状态之前 
  •  
  • canvas.save();//锁画布(为了保存之前的画布状态) 
  • canvas.translate(160, 10);//把当前画布的原点移到(160,10),后面的操作都以(160,10)作为参照点, 
  • canvas.clipRect(10, 10, 90, 90);//这里的真实坐标为左上(170,170)、右下(250,250) 
  • canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE); 
  • drawScene(canvas); 
  • canvas.restore();