# 变形
到目前为止,我们只是根据我们的需要使用默认的网格,改变整个画布的大小。
变形是一种更强大的方法,可以将原点移动到另一点、对网格进行旋转和缩放。
# 状态的保存和恢复
save()
restore()
function draw() {
const canvas = document.getElementById("demo8_0");
const ctx = 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()
它用来移动 canvas 和它的原点到一个不同的位置。
TIP
在做变形之前先保存状态是一个良好的习惯。大多数情况下,调用 restore 方法比手动恢复原先的状态要简单得多。
function draw() {
const canvas = document.getElementById("demo8_1");
const 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();
}
}
}
# 旋转
rotate(deg)
它用于以原点为中心旋转 canvas。
function draw() {
const ctx = document.getElementById("demo8_2").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();
}
}
# 缩放
接着是缩放。我们用它来增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大。
scale(x, y)
scale方法可以缩放画布的水平和垂直的单位
function draw() {
const ctx = document.getElementById("demo8_3").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
function draw() {
const canvas =document.getElementById("demo8_4")
canvas.width = 200
canvas.height = 360
const ctx = canvas.getContext("2d");
const sin30 = Math.sin(Math.PI / 6);
const cos30 = 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);
// 顺时针旋转画布30度
ctx.transform(cos30, sin30, -sin30, cos30, 0, 0);
}
// 不缩放 竖直方向进行倾斜 向下移动100 单位
ctx.setTransform(1, 1, 0, 1, 0, 100);
ctx.fillStyle = "rgba(255, 128, 255, 0.5)";
ctx.fillRect(0, 50, 100, 100);
}