Canvas画布状态操作-应用实例

在Canvas中,状态操作是绘制复杂图形和动画的重要基础。通过save()restore()方法,我们可以保存和恢复Canvas的绘图状态,包括当前的变换矩阵(平移、旋转、缩放等)、样式设置(如填充色、边框色、线宽等)、剪裁区域等。以下是一个HTML文件的示例,展示了如何使用Canvas的状态操作来绘制一个具有多个层次和变换的图形场景。

示例效果与源代码:

运行效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas 状态操作应用实例</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="300" style="border:1px solid #000;"></canvas>

<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// 绘制背景
ctx.fillStyle = '#f0f0f0';
ctx.fillRect(0, 0, canvas.width, canvas.height);

// 保存初始状态
ctx.save();

// 绘制第一个圆(原始位置)
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI * 2, false);
ctx.fill();

// 保存当前状态(包含圆的绘制状态)
ctx.save();

// 对当前状态进行变换(平移和缩放)
ctx.translate(150, 0); // 平移
ctx.scale(0.5, 0.5); // 缩放

// 绘制第二个圆(在变换后的位置)
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI * 2, false);
ctx.fill();

// 恢复到上一个保存的状态(不包含变换)
ctx.restore();

// 绘制第三个圆(在同一位置但颜色不同)
ctx.fillStyle = 'green';
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI * 2, false);
ctx.fill();

// 恢复到初始状态(无变换,填充色重置)
ctx.restore();

// 在初始状态下绘制第四个圆(在不同位置)
ctx.fillStyle = 'yellow';
ctx.beginPath();
ctx.arc(300, 100, 50, 0, Math.PI * 2, false);
ctx.fill();

// 额外示例:使用变换绘制矩形
ctx.save();
ctx.translate(200, 150); // 平移
ctx.rotate(Math.PI / 4); // 旋转
ctx.fillStyle = 'purple';
ctx.fillRect(-50, -25, 100, 50); // 绘制一个旋转并平移的矩形
ctx.restore();
</script>
</body>
</html>

在这个示例中,我们首先绘制了一个灰色的背景,然后通过save()restore()方法管理了Canvas的绘图状态。我们绘制了四个圆,每个圆都展示了不同的绘图状态。第一个圆在原始位置绘制;第二个圆在保存了第一个圆的状态后,通过平移和缩放变换绘制在了一个新位置;第三个圆通过restore()方法恢复到第一个圆的状态后,改变了填充色但保留了位置信息重新绘制;第四个圆则是在完全恢复到初始状态后,在另一个位置绘制的。

此外,我们还展示了如何使用translate()rotate()方法进行图形的变换,并绘制了一个旋转且平移的紫色矩形作为额外示例。这些操作都依赖于Canvas的状态管理机制,使得我们能够创建出复杂且动态的图形效果。