绘制状态存储
canvas 中设置多数都是全局使用的,我们在操作时难免会遇到某个被后,当再次使用到这个时必须是认值的情况,或者我们绘制多个矩形,这些矩形的填充颜色和阴影有一定规律,比如填充颜色为 红、黄、蓝、黄、红这样的顺序,阴影也是有对应顺序,我们应该怎么做呢?本小节我们就来学习如何保存某个绘制状态和地将绘制状态恢复到上阶段。
我们先看不使用存储绘制状态的案例,这个案例中,我们需要绘制5个矩形,其中第和第五个矩形相同,第二个和第四个矩形相同。
<!DOCTYPE html>
<html>
<head>
< charset="utf-8">
<title>网Wiki</title>
<style>
#imooc{
border:px solid #ccc;
}
</style>
</head>
<body>
<canvas id="imooc">您的浏览器 HTML5 canvas </canvas>
<script>
const canvas = document.getElementById('imooc');
canvas.width=;
canvas.height=;
const ctx = canvas.getContext('2d');
// 绘制第矩形
ctx.fillStyle="red"
ctx.shadowBlur=;
ctx.shadowOffsetX=;
ctx.shadowOffsetY=;
ctx.shadowColor="#ccc"
ctx.fillRect(,, ,)
// 绘制第二个矩形
ctx.fillStyle="yellow"
ctx.shadowBlur=;
ctx.shadowOffsetX=;
ctx.shadowOffsetY=;
ctx.shadowColor="#456795"
ctx.fillRect(,, ,)
// 绘制第三个矩形
ctx.fillStyle="blue"
ctx.shadowBlur=;
ctx.shadowOffsetX=;
ctx.shadowOffsetY=;
ctx.shadowColor="#222"
ctx.fillRect(,, ,)
// 绘制第四个矩形
ctx.fillStyle="yellow"
ctx.shadowBlur=;
ctx.shadowOffsetX=;
ctx.shadowOffsetY=;
ctx.shadowColor="#456795"
ctx.fillRect(,, ,)
// 绘制第五个矩形
ctx.fillStyle="red"
ctx.shadowBlur=;
ctx.shadowOffsetX=;
ctx.shadowOffsetY=;
ctx.shadowColor="#ccc"
ctx.fillRect(,, ,)
</script>
<body>
</html>
运行结果:
上面案例中,可以看到,绘制第四个正方形的时候,把所有又写了一遍,但是这个和我们绘制第二个正方形的一样,第五个正方形和第正方形的一样,这样我们不仅浪费时间还了维护成本,维护成本主要指:假如我们要红色的正方形为其他颜色,我们就得两处。
今天我们就用存储绘制状态的来优化一下上面,还是上面那个案例,我们换一种写法。
<!DOCTYPE html>
<html>
<head>
< charset="utf-8">
<title>网Wiki</title>
<style>
#imooc{
border:px solid #ccc;
}
</style>
</head>
<body>
<canvas id="imooc">您的浏览器 HTML5 canvas </canvas>
<script>
const canvas = document.getElementById('imooc');
canvas.width=;
canvas.height=;
const ctx = canvas.getContext('2d');
// 绘制第矩形
ctx.fillStyle="red"
ctx.shadowBlur=;
ctx.shadowOffsetX=;
ctx.shadowOffsetY=;
ctx.shadowColor="#ccc"
ctx.save(); // 这里把当前画布的做了,我们称为:一
ctx.fillRect(,, ,)
// 绘制第二个矩形
ctx.fillStyle="yellow"
ctx.shadowBlur=;
ctx.shadowOffsetX=;
ctx.shadowOffsetY=;
ctx.shadowColor="#456795"
ctx.save(); // 这里把当前画布的做了第二个,我们称为:二
ctx.fillRect(,, ,)
// 绘制第三个矩形
ctx.fillStyle="blue"
ctx.shadowBlur=;
ctx.shadowOffsetX=;
ctx.shadowOffsetY=;
ctx.shadowColor="#222"
ctx.fillRect(,, ,)
// 绘制第四个矩形
ctx.restore() // 这里我们读取了最新的,也就是读区了二的状态,二被读取后就消失了。
ctx.fillRect(,, ,)
// 绘制第五个矩形
ctx.restore(); // 这里我们读取了最新的,也就是读区了一的状态,因为二已经消失了
ctx.fillRect(,, ,)
</script>
<body>
</html>
运行结果:
我们可以看到,运行结果是一样的,我们把主要拆分讲解一下。
设置绘制矩形的相关,并 save 保存绘制状态。
ctx.fillStyle="red"
ctx.shadowBlur=2;
ctx.shadowOffsetX=4;
ctx.shadowOffsetY=4;
ctx.shadowColor="#ccc"
ctx.save(); // 这里把当前画布的做了,我们称为:一
ctx.fillRect(40,40, 40,40)
设置第二个矩形的相关,并 save 保存绘制状态,这个状态会堆放到上状态的上面,该状态的存储符合“栈”的特性:先进后出,也就是最先放进去的最后才被拿走。
我们看形象的,小孩的玩具。
最下面的大圈是最先放进去的,再取出时它是最后被拿出来的。
ctx.fillStyle="yellow"
ctx.shadowBlur=3;
ctx.shadowOffsetX=8;
ctx.shadowOffsetY=8;
ctx.shadowColor="#456795"
ctx.save(); // 这里把当前画布的做了第二个,我们称为:二
ctx.fillRect(100,40, 40,40)
绘制第四个矩形,我们在绘制前先 ctx.restore
取出状态,取出的状态会应用到当前画布上。当前存储的所有状态中,最上面的是二,也就是第二个矩形的状态,所以这里取出来的就是第二个矩形的状态。
ctx.restore() // 取出状态
ctx.fillRect(220,40, 40,40)
绘制第五个矩形,同样 ctx.restore
取出状态,当前存储的状态中只有一,也就是第矩形的状态,所以这里取出来的就是第矩形的状态。
ctx.restore(); // 取出状态
ctx.fillRect(280,40, 40,40)
特别注意 当存储的状态被取完以后,再去取状态,此时会出问题。办法就是:读取状态 restore
的只能小于等于存储 save
的。
本小节我们学习了 save
和 restore
,它们的主要作用是存储某阶段的状态,后面可以恢复存储的状态。
save 说明
语法:
ctx.save();
变量说明:
没有参数。
restore 说明
语法:
ctx.restore();
变量说明:
没有参数。
本小节我们主要学习了利用 save
和 restore
存储和拿取画布状态的,存储状态的目的是后面可以恢复到上绘制状态。本小节我们只是简单体会了存储和拿取的过程,后面小节我们学习了旋转变形的操作,会频繁地用到这个操作。