1.状态的保存和回复 Saving and Restoring state
1.1 save()
保存画布(canvas)当前的所有状态
1.2 restore()
恢复画布(canvas)的上一个已保存的状
Canvas状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存。
一个绘画状态包括:
- 当前应用的变形(即移动,旋转和缩放)
- strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值
- 当前的裁切路径(clipping path)
可以调用任意多次 save 方法。
每一次调用 restore 方法,上一个保存的状态就从栈中弹出,所有设定都恢复。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function draw() { var canvas = document.getElementById('tutorial'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.fillRect(0, 0, 150, 150); ctx.save(); ctx.fillStyle = "#f00"; ctx.fillRect(20, 20, 110, 110); ctx.save(); ctx.fillStyle = "#ff0"; ctx.fillRect(40, 40, 70, 70); ctx.save(); ctx.restore(); ctx.fillRect(30, 30, 90, 90); ctx.restore(); ctx.fillRect(10, 10, 130, 130); ctx.restore(); ctx.fillRect(0, 0, 150, 150);
} }
|
2.移动 Translating
1.1 translate(x, y)它用来移动 canvas 和它的原点到一个不同的位置。
translate 方法接受两个参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function draw() { var canvas = document.getElementById('tutorial'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); for (let i = 0; i < 3; i++) { for (let 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();
}
}
} }
|
未使用translate,如果不使用 translate 方法,那么所有矩形都将被绘制在相同的位置(0,0)
使用translate,可以移动 canvas 原点,translate 方法同时让我们可以任意放置这些图案,而不需要在 fillRect() 方法中手工调整坐标值
2.旋转 Rotating
2.1 rotate(angle) 以原点为中心旋转 canvas
rotate(angle)
这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。
旋转的中心点始终是 canvas 的原点,如果要改变它,我们需要用到 translate 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function draw() { var canvas = document.getElementById('tutorial'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.translate(75, 75); for (let i = 0; i < 6; i++) { ctx.save(); ctx.fillStyle = 'rgb(' + (51 * i) + ',' + (255 - 51 * i) + ',255)'; for (let j = 0; j < i*1; j++) { 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();
}
} }
|
j < i*1;
当i分别为0,1,2,3,4,5时,效果如下:
3.缩放 Scaling
3.1 scale(x,y) 增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大
两个参数都是实数,可以为负数,如果比1小,会比缩放图形, 如果比1大会放大图形。默认值为1, 为实际大小。
1 2 3 4 5 6 7 8 9 10
| function draw() { var canvas = document.getElementById('tutorial'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.save(); ctx.scale(10, 3); ctx.fillRect(1, 10, 10, 10); ctx.restore(); } }
|
未设置缩放
设置缩放 ctx.scale(10, 3);
1 2 3 4 5 6 7 8 9
| function draw() { var canvas = document.getElementById('tutorial'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.scale(-1, 1); ctx.font = '48px serif'; ctx.fillText('Nancy', -135, 120) } }
|
- m11:水平方向的缩放
- m12:水平方向的倾斜偏移
- m21:竖直方向的倾斜偏移
- m22:竖直方向的缩放
- dx:水平方向的移动
- dy:竖直方向的移动等同于
1
| ctx.setTransform(1, 0, 0, 1, 0, 0);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function draw() { var ctx = document.getElementById('canvas').getContext('2d');
var sin = Math.sin(Math.PI/6); var cos = Math.cos(Math.PI/6); ctx.translate(100, 100); var c = 0; for (var i=0; i <= 12; i++) { c = Math.floor(255 / 12 * i); ctx.fillStyle = "rgb(" + c + "," + c + "," + c + ")"; ctx.fillRect(0, 0, 100, 10); ctx.transform(cos, sin, -sin, cos, 0, 0); } ctx.setTransform(-1, 0, 0, 1, 100, 100); ctx.fillStyle = "rgba(255, 128, 255, 0.5)"; ctx.fillRect(0, 50, 100, 100); }
|