绘制复杂图形必不可少的方法—— save, restore
1、save():保存画布(canvas)的所有状态,会被存储到状态栈中。
一个绘画状态包括:
- 当前应用的变形(即移动,旋转和缩放)
- 以及下面这些属性:strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled
- 当前的裁切路径(clipping path)
2、restore():每一次调用 restore
方法,上一个保存的状态就从栈中弹出,所有设定都恢复。
save 和 restore 方法是用来保存和恢复 canvas 状态的,都没有参数。Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。
<canvas id="canvas" width="300" height="300"></canvas>
<script>
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 150, 150); // 使用默认设置绘制一个矩形
ctx.save(); // 保存默认状态
ctx.fillStyle = '#00b8d4' // 在原有配置基础上对颜色做改变
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); // 使用加载的配置绘制一个矩形
}
draw()
</script>
canvas.clip() 是如何改变画布的状态的?又需要如何恢复画布状态??
第一步:在画布上裁剪一块圆形区域:
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = 500;
canvas.height = 400;
ctx.beginPath();
ctx.fillStyle = "#000";
ctx.fillRect(0,0,500,400);
// 进行裁剪
ctx.beginPath();
ctx.fillStyle = 'navajowhite';
ctx.arc(200,200,150,0,Math.PI*2, false);
ctx.fill();
ctx.clip();
</script>
显示结果如下图:
第二步:裁剪后在画布上绘制一个红色矩形(200*250):
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = 500;
canvas.height = 400;
ctx.beginPath();
ctx.fillStyle = "#000";
ctx.fillRect(0,0,500,400);
// 进行裁剪
ctx.beginPath();
ctx.fillStyle = 'navajowhite';
ctx.arc(200,200,150,0,Math.PI*2, false);
ctx.fill();
ctx.clip();
// +++++ 绘制矩形
ctx.fillStyle = 'red';
ctx.fillRect(0,0,200,250);
</script>
如图:应该让红色矩形全部显示出来,才是理想的结果。但实际的结果却是只显示了裁切区域的部分。也就是说,裁剪后页面中能够显示的区域只有裁剪部分,只有裁剪区域才能渲染出绘图结果。
======》 所以说:裁剪方法改变了当前的绘图环境。
第三步:使用save,restore方法保存与恢复画布原始状态
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = 500;
canvas.height = 400;
ctx.beginPath();
ctx.fillStyle = "#000";
ctx.fillRect(0,0,500,400);
// 添save方法,在裁剪前保存状态
ctx.save();
// 进行裁剪
ctx.beginPath();
ctx.fillStyle = 'navajowhite';
ctx.arc(200,200,150,0,Math.PI*2, false);
ctx.fill();
ctx.clip();
// 添restore方法,裁剪后恢复状态
ctx.restore();
// 绘制矩形
ctx.fillStyle = 'red';
ctx.fillRect(0,0,500,400);
</script>
结果如下:
可以看到,使用save,restore方法就可以完美地解决clip()带来的状态改变问题。