绘制状态存储
1. 前言
canvas 中设置属性多数都是全局使用的,我们在操作时难免会遇到某个属性被修改后,当再次使用到这个属性时必须是默认值的情况,或者我们绘制多个矩形,这些矩形的填充颜色和阴影有一定规律,比如填充颜色为 红、黄、蓝、黄、红这样的顺序,阴影也是有对应顺序,我们应该怎么做呢?本小节我们就来学习如何保存某个绘制状态和快速地将绘制状态恢复到上一个阶段。
2. 存储绘制状态
<!DOCTYPE html>
<html>
<head>
<Meta 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>
<Meta 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)
3. 方法整理
3.1 存储状态 save
save 说明
语法:
ctx.save();
变量说明:
没有参数。
3.2 存储状态 restore
restore 说明
语法:
ctx.restore();
变量说明:
没有参数。