网站首页 » 前端开发 » HTML5 » Canvas save() 和 restore() 方法
上一篇:
下一篇:

Canvas save() 和 restore() 方法

最近因为要实现一些效果(合成图片),所以就接触到了 Canvas 这个HTML5 的新标签。于是二话不说就开始了Canvas 的学习之旅。虽然在项目中使用 Canvas 时没有用到  save() 和 restore() 方法,但是无意间看到了这两个方法。感觉还是的非常地有用,于是就在网上对它们俩进行了人肉搜索。

基本都是这么定义它们的使用的 save() 和 restore() 分别用来保存和恢复 Canvas 状态的。短短的一句话,虽然很明了,但什么是 Canvas 状态呢???

在 MDN 中关于 Canvas 状态,列举了一些情况及属性:

  • 当前的坐标变换(变换矩阵)
  • 当前裁剪区域
  • 包括如下属性:strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled.

如果不知道上面的属性都有什么使用可以看这里《HTML5 Canvas 教程》。为了让你更浅显地知道save() 方法和restore() 方法,我们还是有必要来看一个简单的例子。

完整代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas save() 方法和 restore() 方法</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
</head>
<body>
<canvas width="500" height="450" id="canvas">Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var ctx = document.getElementById('canvas').getContext("2d");
// 共用的样式,所以提到前面统一写就好
ctx.shadowOffsetX = 8;
ctx.shadowOffsetY = 8;
ctx.shadowBlur = 18;

// 画每一个矩形
ctx.fillStyle = "#404040";
ctx.shadowColor = "rgba(64,64,64,0.5)";
ctx.fillRect(20,20,150,100);
ctx.save(); // 保存状态1

// 画第二个矩形
ctx.fillStyle = "#76daff";
ctx.shadowColor = "rgba(118, 218, 255,0.5)";
ctx.fillRect(20,160,150,100);
ctx.save(); // 保存状态2

// 画第三个矩形
ctx.fillStyle = "#96b38a";
ctx.shadowColor = "rgba(150, 179, 138,0.5)";
ctx.fillRect(20,300,150,100);
ctx.save(); // 保存状态3

// 恢复状态3,画第一个圆
ctx.restore(); // 恢复状态3
ctx.beginPath();
ctx.arc(420, 70, 50, 0, Math.PI*2, false);
ctx.closePath();
ctx.fill();

// 恢复状态2,画第二个圆
ctx.restore(); // 恢复状态2
ctx.beginPath();
ctx.arc(420, 210, 50, 0, Math.PI*2, false);
ctx.closePath();
ctx.fill();

// 恢复状态1,画第三个圆
ctx.restore(); // 恢复状态1
ctx.beginPath();
ctx.arc(420, 350, 50, 0, Math.PI*2, false);
ctx.closePath();
ctx.fill();
</script>
</body>
</html>

save() 方法保存的状态是保存到栈中的,所以用restore() 方法就是先从最后一个状态开始恢复的,下面的例子中,我们先画出三个矩形并且分别保存状态(矩形的阴影、背景色),然后通过恢复每一个状态来画圆,最终的效果图如下:

Canvas save() 和 restore() 方法

简单的来说:保存状态的顺序为左边矩形的状态1、状态2、状态3。而当我们第一次调用 restore() 方法恢复状态时,就是恢复最后一个状态(状态3),第二次调用 restore() 方法时就是恢复到倒数第二个(状态2),第三次调用 restore() 方法时恢复的就是状态1。如果我们保存了更多的状态,那么恢复的状态就依此类推。也就是我们常说的“先进后出”。

提示

一般情况下save() 方法和 restore() 方法都是配套使用的。也就是说它们是一对一的关系,但如果 restore() 方法调用的次数比调用 save() 方法的次数多也不会有问题。

完整代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas save() 方法和 restore() 方法</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
</head>
<body>
<canvas width="500" height="500" id="canvas">Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var ctx = document.getElementById('canvas').getContext("2d");
// 共用的样式,所以提到前面统一写就好
ctx.shadowOffsetX = 8;
ctx.shadowOffsetY = 8;
ctx.shadowBlur = 18;
ctx.save(); // 保存画布初始状态

ctx.translate(280,20);
// 画第一个矩形
ctx.fillStyle = "#404040";
ctx.shadowColor = "rgba(64,64,64,0.5)";
ctx.fillRect(0,0,150,100);

// 恢复画布默认状态
ctx.restore();
// 重新保存画布默认状态
ctx.save();
ctx.translate(280,160);
// 旋转后画第二个圆
ctx.rotate(90*Math.PI/180); // 注意:这里需要把角度转为弧度
ctx.translate(0,100); // 再使画布沿Y轴位移100px
ctx.fillStyle = "#76daff";
ctx.shadowColor = "rgba(118, 218, 255,0.5)";
ctx.fillRect(0,0,150,100);

// 恢复画布默认状态
ctx.restore();
// 画第三个矩形
ctx.translate(280,300);
ctx.fillStyle = "#96b38a";
ctx.shadowColor = "rgba(150, 179, 138,0.5)";
ctx.fillRect(0,0,150,100);

</script>
</body>
</html>

你想要的效果:

Canvas rotate() 与坐标的关系

可理想很丰满,现实很骨感,你在浏览器中看到的是下面这样子的:

Canvas rotate() 与坐标的关系

因为 使用了rotate() 方法对画布进行旋转后,其实整个坐标也是跟着旋转的。

在上面的这个例子中,我们没有使用 fillRect() 方法中的参数来给矩形指定坐标,而是通过 translate() 方法来定位矩形位置。在画矩形2时,对画布进行了两次位移,第一次就是定位到指定位置,在使用了旋转后我们再次让让画布在 Y 轴上位移100px。此就矩形2 就会出现如上图的效果(不是按常理的向下位移,而是向左边位移了),这就说明了旋转会影响坐标轴方向。

Canvas save() 和 restore() 基本的用法就这么简单,关于这两个方法你只需要记住一点就是“状态”是什么。

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/canvas-states-save-and-restore/

Leave a Reply

Your email address will not be published. Required fields are marked *

评论 END