绘制复杂图形的两个必不可少的方法:
save() 保存画布的所有状态。
restore() save和restore方法是用来保存和恢复canvas状态的。canvas的状态就是当前画面应用的所有样式和变形的一个快照。
Canvas状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存。一个绘画状态包括:可以调用任意多次 save 方法。每一次调用 restore 方法,上一个保存的状态就从栈中弹出,所有设定都恢复。
变形是一种更强大的方法,可以将原点移动到另一点、对网格进行旋转和缩放。
状态的保存和恢复 Saving and restoring state
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
ctx.fillRect(0,0,150,150); // 使用默认设置绘制一个矩形
ctx.save(); // 保存默认状态
ctx.fillStyle = '#09F' // 在原有配置基础上对颜色做改变
ctx.fillRect(15,15,120,120); // 使用新的设置绘制一个矩形
ctx.save(); // 保存当前状态
ctx.fillStyle = '#FFF' // 再次改变颜色配置
ctx.globalAlpha = 0.5;
ctx.fillRect(30,30,90,90); // 使用新的配置绘制一个矩形
ctx.restore(); // 重新加载之前的颜色状态
ctx.fillRect(45,45,60,60); // 使用上一次的配置绘制一个矩形
ctx.restore(); // 加载默认颜色配置
ctx.fillRect(60,60,30,30); // 使用加载的配置绘制一个矩形
}
复制代码
移动 translating
移动canvas和它的原点到一个不同的位置。
translate(x,y)translate 方法接受两个参数。x 是左右偏移量,y 是上下偏移量,如右图所示。
在做变形之前先保存状态是一个良好的习惯。大多数情况下,调用 restore 方法比手动恢复原先的状态要简单得多。
例子
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
ctx.save();
ctx.fillStyle = 'rgb(' + (51 * i) + ', ' + (255 - 51 * i) + ', 255)';
ctx.translate(10 + j * 50, 10 + i * 50);
ctx.fillRect(0, 0, 25, 25);
ctx.restore();
}
}
}
复制代码
旋转rotating
用于以原点为中心旋转canvas,只接受一个参数-旋转的角度,顺时针方向,以弧度为单位,旋转的中心点始终是canvas的原点,如果要改变它我们需要用到translate方法。
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
ctx.translate(75,75);
for (var i=1;i<6;i++){ // Loop through rings (from inside to out)
ctx.save();
ctx.fillStyle = 'rgb('+(51*i)+','+(255-51*i)+',255)';
for (var j=0;j<i*6;j++){ // draw individual dots
ctx.rotate(Math.PI*2/(i*6));
ctx.beginPath();
ctx.arc(0,i*12.5,5,0,Math.PI*2,true);
ctx.fill();
}
ctx.restore();
}
}
复制代码
缩放Scaling
scale(x, y)
scale(x, y) scale 方法可以缩放画布的水平和垂直的单位。两个参数都是实数,可以为负数,x 为水平缩放因子,y 为垂直缩放因子,如果比1小,会比缩放图形, 如果比1大会放大图形。默认值为1, 为实际大小。
画布初始情况下, 是以左上角坐标为原点的第一象限。如果参数为负实数, 相当于以x 或 y轴作为对称轴镜像反转(例如, 使用translate(0,canvas.height); scale(1,-1); 以y轴作为对称轴镜像反转, 就可得到著名的笛卡尔坐标系,左下角为原点)。
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
// draw a simple rectangle, but scale it.
ctx.save();
ctx.scale(10, 3);
ctx.fillRect(1, 10, 10, 10);
ctx.restore();
// mirror horizontally
ctx.scale(-1, 1);
ctx.font = '48px serif';
ctx.fillText('MDN', -135, 120);
}
复制代码
变形 Transfroms
transform(m11, m12, m21, m22, dx, dy)这个方法是将当前的变形矩阵乘上一个基于自身参数的矩阵,在这里我们用下面的矩阵:
m11 m21 dx
m12 m22 dy
0 0 1
复制代码
m11:水平方向的缩放
m12:水平方向的倾斜偏移
m21:竖直方向的倾斜偏移
m22:竖直方向的缩放
dx:水平方向的移动
dy:竖直方向的移动