五、状态的保存与恢复

五、状态的保存与恢复

在操作图像的时候,很可能会用到 ctx之前的状态,canvas提供了相应的API,用于保存状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 获取元素
var canvas = document.getElementById("myCanvas");
// 获取画笔
var ctx = canvas.getContext("2d");

//改变填充色
ctx.fillStyle = "blue";
// 绘制矩形
ctx.fillRect(0, 0, 100, 100);

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

//改变填充色
ctx.fillStyle = "orange";
// 绘制矩形
ctx.fillRect(100, 100, 100, 100);

// 恢复状态
ctx.restore();
// 绘制矩形
ctx.fillRect(200, 200, 100, 100);

UYg0Qx.png

save方法可以使用多次,每save一次,就把当前的canvas上的状态复制一份,每restore一次就用掉一次save

save一次相当于往子弹夹中装一颗子弹

restore一次相当于将弹夹中的子弹发射一颗

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
//改变填充色
ctx.fillStyle = "blue";
// 保存状态
ctx.save();

//改变填充色
ctx.fillStyle = "orange";
// 保存状态
ctx.save();

//改变填充色
ctx.fillStyle = "pink";
// 保存状态
ctx.save();

// 绘制矩形
ctx.fillRect(0, 0, 100, 100);

// 恢复一次
ctx.restore();
ctx.fillRect(100, 100, 100, 100);

// 再恢复两次
ctx.restore();
ctx.restore();
ctx.fillRect(200, 200, 100, 100);

UYg6Te.png

5.1 应用:一个旋转一个静止

ctx.save();ctx.restore(); 之间的内容相当于一个封闭的盒子,对其他部分没有影响

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
// 获取元素
var canvas = document.getElementById("myCanvas");
// 获取画笔
var ctx = canvas.getContext("2d");

// 绘制矩形
// ctx.fillRect(100, 100, 400, 400);

// 平移坐标系
ctx.translate(canvas.width / 2, canvas.height / 2);
// 绘制矩形
ctx.fillRect(-200, -200, 400, 400);

// 定义角度
var deg = Math.PI / 180;
// 定义信号量
var i = 0;

// 定义定时器
var timer = setInterval(function(){
i++;
// 清屏
ctx.clearRect(-3000, -3000, 30000, 30000);
// 保存初始状态 黑色填充 不旋转
ctx.save();
// 旋转
ctx.rotate(deg * i);
// 绘制矩形
ctx.fillRect(-200, -200, 400, 400);
// 恢复到初始状态 黑色填充 不旋转
ctx.restore();

// 保存初始状态 黑色填充 不旋转
ctx.save();
//改变填充颜色
ctx.fillStyle = "orange";
// 绘制矩形
ctx.fillRect(100, -100, 100, 100);
// 恢复到初始状态 黑色填充 不旋转
ctx.restore();
}, 200);

UYgfSI.png

5.2 应用:时钟

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// 获取元素
var canvas = document.getElementById("myCanvas");
// 获取画笔
var ctx = canvas.getContext("2d");

// 平移坐标系
ctx.translate(canvas.width / 2, canvas.height / 2);

// 改变线宽
ctx.lineWidth = 4;
// 绘制秒针
line(0, 20, 0, -180);

// 改变线宽
ctx.lineWidth = 6;
// 绘制分针
line(0, 15, 0, -150);

// 改变线宽
ctx.lineWidth = 8;
// 绘制时针
line(0, 10, 0, -120);

// 绘制圆
drawCircle(0, 0, 5);

// 获取当前时间
var date = new Date();

// 定义角度
var deg = Math.PI / 180;
// 信号量
var i = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds();


// 开启定时器
var timer = setInterval(function(){
i++;
// 清屏
ctx.clearRect(-600, -600, 3000, 3000);
// 渲染
// 保存状态 指针不旋转
ctx.save();
// 旋转
ctx.rotate(deg * i * 6);
// 改变线宽
ctx.lineWidth = 4;
// 绘制秒针
line(0, 20, 0, -180);
// 恢复 指针不旋转
ctx.restore();

// 保存状态 指针不旋转
ctx.save();
// 旋转
ctx.rotate(deg * i / 10);
// 改变线宽
ctx.lineWidth = 6;
// 绘制分针
line(0, 15, 0, -150);
// 恢复 指针不旋转
ctx.restore();

// 保存状态 指针不旋转
ctx.save();
// 旋转
ctx.rotate(deg * i / 120);
// 改变线宽
ctx.lineWidth = 8;
// 绘制时针
line(0, 10, 0, -120);
// 恢复 指针不旋转
ctx.restore();
}, 1000);

// 封装函数,传递两个点,绘制两个点之间的线段
function line(x1, y1, x2, y2){
// 开启路径
ctx.beginPath();
// 移动画笔到某个位置
ctx.moveTo(x1, y1);
// 绘制路径
ctx.lineTo(x2, y2);
// 关闭路径
ctx.closePath();
// 描边
ctx. stroke();
}

// 封装一个函数,用于绘制圆
function drawCircle(x, y, r){
// 开启路径
ctx.beginPath();
// 绘制圆
ctx.arc(x, y, r, 0, Math.PI * 2);
// 闭合路径
ctx.closePath();
// 描边
ctx.stroke();
}

UYgT0S.png

点击查看

本文标题:五、状态的保存与恢复

文章作者:Mango

发布时间:2020年07月14日 - 13:23:53

最后更新:2020年07月14日 - 13:27:10

原始链接:https://mango185.github.io/post/564881cb.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------------本文结束 感谢您的阅读-------------------