canvas学习笔记1 _ save,restore

163 阅读1分钟

绘制复杂图形必不可少的方法—— 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>

image.png


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>

显示结果如下图:

image.png

第二步:裁剪后在画布上绘制一个红色矩形(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>

image.png

如图:应该让红色矩形全部显示出来,才是理想的结果。但实际的结果却是只显示了裁切区域的部分。也就是说,裁剪后页面中能够显示的区域只有裁剪部分,只有裁剪区域才能渲染出绘图结果。

======》 所以说:裁剪方法改变了当前的绘图环境。

第三步:使用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>

结果如下:

image.png

可以看到,使用save,restore方法就可以完美地解决clip()带来的状态改变问题。