Canvas 06
canvas画布状态的保存和恢复
save() —— 保存画布 (canvas) 的所有状态 restore() —— 恢复画布之前保存状态 保存的Canvas状态就是当前画布应用的所有样式和变形的一个快照。 我们可以想象canvas的状态保存在一个栈里面,调用save就会将栈状态保存到栈中。调用restore将保存的状态从栈弹出。
- 画布的变形(平移、缩放、旋转)
- 样式属性 strokeStyle,fillStyle,globalAlpha,globalCompositeOperation,font,imageSmoothEnabled
- 当前的裁切路径
示例
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); // 使用加载的配置绘制一个矩形
}
移动
translate(x, y) 示例
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();
}
}
}
旋转
rotate(angle) —— 以原点为中心旋转canvas,旋转的角度,顺时针方向,以弧度为单位。
π * 角度 / 180 => 弧度 示例
function draw() {
const ctx = document.getElementById("canvas").getContext("2d");
// left rectangles, rotate from canvas origin
ctx.save();
// blue rect
ctx.fillStyle = "#0095DD";
ctx.fillRect(30, 30, 100, 100);
ctx.rotate((Math.PI / 180) * 25);
// grey rect
ctx.fillStyle = "#4D4E53";
ctx.fillRect(30, 30, 100, 100);
ctx.restore();
// right rectangles, rotate from rectangle center
// draw blue rect
ctx.fillStyle = "#0095DD";
ctx.fillRect(150, 30, 100, 100);
ctx.translate(200, 80); // translate to rectangle center
// x = x + 0.5 * width
// y = y + 0.5 * height
ctx.rotate((Math.PI / 180) * 25); // rotate
ctx.translate(-200, -80); // translate back
// draw grey rect
ctx.fillStyle = "#4D4E53";
ctx.fillRect(150, 30, 100, 100);
}
缩放
scale(x, y) —— x y 为负数的话,就会在对应方向上镜像翻转。
默认情况下,canvas的一个单位为一个像素。如果我们的缩放因子是0.5,则一个单位对应就变成0.5个像素。
示例
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);
}
变形
transform(a, b, c, d, e, f) —— 该方法允许我们直接对变形矩阵进行修改。表示将当前的变形矩阵乘上一个基于自身参数的矩阵。 a 水平方向的缩放 b 竖直方向的倾斜偏移 c 水平方向的倾斜偏移 d 竖直方向的缩放 e 水平方向的移动 f 竖直方向的移动 setTransform(a, b, c, d, e, f) —— 将当前变换矩阵重置为单位矩阵,并用设置参数调用transform方法变换图形。(该方法是取消了当前变形,然后设置为指定的变形。) resetTransform() —— 重置当前的变换为单位变换矩阵。等同于ctx.setTransform(1, 0, 0, 1, 0, 0)。
示例
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);
}
ctx.transform(cos, sin, -sin, cos, 0, 0) 解释当前方法执行为什么表示将图形旋转30° 我们以单位变形出发,半径是一个单位(sin30正弦值 cos30是余弦值),根据相关参数水平竖直方向缩放cos30,竖直和水平方向偏移sin30,组合起来刚好是一个直角三角形,并且夹角30度,所以表示旋转了30度。
写在最后
未完待续… 希望大家好好生活,健康快乐。