Canvas Transform
transform这东西,应该算是canvas中一个比较高级的知识点了,别看它好像没什么东西,但很多很炫的效果,都来自于它,所以我觉得还是有必要写点东西记录一下。
因为有可能在进行一连串的转换后,你自己都搞不清到底转换成什么样了,每当这时候,可以首先来一句:
context.setTransform(1,0,0,1,0,0);
这样就重置转换了,参数是个矩阵(别问我,我只知道大概)。
需要记住两点:
1. Transformations are applied to shapes and paths drawn after the setTransform() or other transformation function is called
2. We must “translate” the point of origin to the center of our shape to rotate it around its own center
为什么是英文的,因为是我抄来的。好吧,其实无关大雅,翻译成中文反而表达不准确。
第一条很好理解,就是要明确顺序。
canvas的转换不是针对整个canvas的,而是针对调用转换方法之后绘制的shapes 或 paths。如下:
context.rotate(45 * Math.PI/180); context.fillRect(50, 50, 50, 50);
顺序很重要,反了就没有旋转的效果了。
第二条,转换的时候,需要把转换的中心点移到shape的自身的中心,不然的话,请看下面这个例子(浅蓝色部分表示canvas):
context.fillRect(50, 50, 50, 50);
这是没有转换的效果,接着来看旋转45°的效果:
context.rotate(45 * Math.PI/180); context.fillRect(50, 50, 50, 50);
可以看出,旋转的中心是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);
==========================================================================================
再说下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);