canvas save()和canvas restore()状态的保存和恢复使用方法及实例
canvas.save()用来保存先前状态的
canvas.restore()用来恢复之前保存的状态
注:两种方法必须搭配使用,否则没有效果
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
canvas{
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas width="800" height="600"></canvas>
<script>
var canvas=document.querySelector('canvas');
var ctx=canvas.getContext('2d');
ctx.save();//状态的保存
ctx.setLineDash([5]);
ctx.lineWidth=4;
ctx.strokeStyle='red';
ctx.strokeRect(50,50,300,300); ctx.restore();//状态的恢复
ctx.arc(400,300,150,0,2*Math.PI);
ctx.stroke();
</script>
</body>
</html>
代码效果如下:

大家可以看到,在最上面的时候在canvas中画了一个矩形,而且是虚线矩形,红色,线宽为5,后来又画了一个圆形
注意并没有开辟新路径,这个圆保持了canvas默认的状态,黑色实线1px线宽,这是为什么呢?
就是因为在定义了ctx以后,我们用了save()保存了初始的状态,在我们划圆的时候用restore恢复了初始的状态,所以为黑色实线。
再看下面这个例子上面的代码简单做了改变,但是效果却不一样了
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
canvas{
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas width="800" height="500"></canvas>
<script>
var canvas=document.querySelector('canvas');
var ctx=canvas.getContext('2d');
ctx.setLineDash([5]);
ctx.lineWidth=4;
ctx.save();//状态的保存,-----改变了保存的位置
ctx.strokeStyle='red';
ctx.strokeRect(50,50,300,300); ctx.restore();//状态的恢复
ctx.arc(400,300,150,0,2*Math.PI);
ctx.stroke();
</script>
</body>
</html>
代码效果如下:

这次发生了什么变化?
圆圈变成了虚线,并且线宽也是4了,但是颜色没有变,为啥子嘞?就是因为使用canvas中save()方法时,先执行的虚线和线宽的代码,也就是在保存的时候已经把虚线和线宽保存了,所以后来在执行恢复的时候就会恢复上
不过还有一个问题是,如果进行多次保存并且多次恢复的时候,那他又是什么样子的呢?先看看代码
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
canvas{
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas width="800" height="600"></canvas>
<script>
var canvas=document.querySelector('canvas');
var ctx=canvas.getContext('2d'); ctx.save();//第一次保存 ctx.setLineDash([5]);
ctx.lineWidth=4;
ctx.strokeStyle='red';
ctx.strokeRect(50,50,100,100); ctx.save();//第二次保存
ctx.setLineDash([10,5,15]);
ctx.lineWidth=8;
ctx.strokeStyle='blue';
ctx.strokeRect(100,100,100,100); ctx.save();//第三次保存 ctx.restore();//恢复第一次
ctx.strokeRect(500,300,100,100);
ctx.restore();//恢复第二次
ctx.strokeRect(600,400,100,100);
ctx.restore();//恢复第一次
ctx.strokeRect(700,500,100,100);
</script>
</body>
</html>
代码运行效果如下:

so?看到这个效果的时候是肿么想的?这是神他喵的恢复功能?每个都不同,哈哈
接下来给大家说一个概念,就是内存中栈的概念–栈存储的规律:先保存的,后恢复,后保存的,先恢复,ok,这个save和restore就是这样的原理给大家画一个图,方便理解下

图上面中3第一个存储到到栈中,2是第二个存储到里面的,1是最后一个存储上的,但是想要取出是就会先取出1,在取出2,在取出3,这也就解释了栈的规律,先保存的后恢复,后保存的先恢复。
这个规律如果理解的话,那么上面canvas中用save()多次存储和多次恢复的顺序就好理解了。
ok,现在就来说下那个是怎么恢复的
第一个保存的时候是canvas初始的状态,没有进行任何操作的
第二个保存的时候为虚线,线宽为4,线的颜色为红色
第三次保存的时候虚线[10,5,15],线宽为8,线的颜色为蓝色
第一次恢复的就是第三次保存的,即虚线[10,5,15],线宽为8,线的颜色为蓝色
第二次恢复的就是第二次保存的,即虚线,线宽为4,线的颜色为红色
第三次恢复的就是canvas初始的状态,默认线宽1px,黑色;
好啦,今天就写到这里吧,休息休息…..一休哥,拜拜喽!
转:https://blog.csdn.net/dayewandou/article/details/78230380
canvas save()和canvas restore()状态的保存和恢复使用方法及实例的更多相关文章
- Android canvas.save()与canvas.restore()的使用总结
含义canvas.save(); 画布将当前的状态保存canvas.restore(); 画布取出原来所保存的状态使用 canvas.save();与canvas.restore();一般结合使用,. ...
- activity状态的保存和恢复
activity状态的保存和恢复 一.简介 1.保存activity状态 * 保存activity状态,onSaveInstanceState这个方法会自动保存有ID的组件的状态 * 没有ID的组件或 ...
- Android中canvas.save()和canvas.restore()的使用
自己定义控件时经常遇到重写View的Ondraw()方法,Ondraw()方法经常设计到save()和restore()这两个方法.这两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的. ...
- Canvas状态的保存与恢复
Canvas的API提供了save()和restore()的方法,用于保存及恢复当前canvas绘图环境的所有属性. save()与restore()方法可以嵌套调用 save()方法将当前绘图环境压 ...
- Android之Activity状态的保存和恢复
系统在某些情况下会调用onSaveInstanceState()和onRestoreInstanceState() 这两个方法来保存和恢复Activity的状态. 一句话:Activity在" ...
- Android开发中Activity状态的保存与恢复
当置于后台的Activity因内存紧张被系统自动回收的时候,再次启动它的话他会重新调用onCretae()从而丢失了之前置于后台前的状态. 这时候就要重写Activity的两个方法来保存和恢复状态,具 ...
- Activity 状态的保存和恢复
Activity状态保存的两种情况 一.Activity状态保持概念 保存Activity的状态是非常重要的,例如我们在玩一个游戏的时候,突然来了一个电话,这个时候在接听完电话之后我们返回到游戏中,这 ...
- Android笔记之自定义的RadioGroup、RadioButton,以及View实例状态的保存与恢复
效果图 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLay ...
- 【转】Android Canvas的save(),saveLayer()和restore()浅谈
Android Canvas的save(),saveLayer()和restore()浅谈 时间:2014-12-04 19:35:22 阅读:1445 评论:0 收藏: ...
随机推荐
- Lucene 05 - 使用Lucene的Java API实现分页查询
目录 1 Lucene的分页查询 2 代码示例 3 分页查询结果 1 Lucene的分页查询 搜索内容过多时, 需要考虑分页显示, 像这样: 说明: Lucene的分页查询是在内存中实现的. 2 代码 ...
- plsql可视化文件夹解释
function:一般是存储函数或者方法 procedures:一般是存放存储过程 Table:一般是存放建的表 packages:包(头) package bodies:包体types:类型 typ ...
- transient和synchronized的使用
transient和synchronized这两个关键字没什么联系,这两天用到了它们,所以总结一下,两个关键字做个伴! transient 持久化时不被存储,当你的对象实现了Serializable接 ...
- 【ASP.NET Core快速入门】(十)Cookie-based认证实现
准备工作 新建MVC项目,然后用VSCode打开 dotnet new mvc --name MvcCookieAuthSample 在Controllers文件夹下新建AdminController ...
- JVM(四)垃圾回收的实现算法和执行细节
全文共 1890 个字,读完大约需要 6 分钟. 上一篇我们讲了垃圾标记的一些实现细节和经典算法,而本文将系统的讲解一下垃圾回收的经典算法,和Hotspot虚拟机执行垃圾回收的一些实现细节,比如安全点 ...
- 基于React-Native0.55.4的语音识别项目全栈方案
移动端的API能力验证方案与PC端不一样!不一样!!不一样!!! 即使需要使用的API都存在,也不一定能用,这一点和PC端是有很大区别的,国内的手机系统虽然都是基于Android,但几乎都会经过各大厂 ...
- JDK源码分析(三)—— LinkedList
参考文档 JDK源码分析(4)之 LinkedList 相关
- 杭电ACM2009--求数列的和
求数列的和 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- npm --save 、-D 、--save -dev
npm install 和 npm i 是一样 --save 和 -S 是一样 --save-dev 和 -D 是一样的 区别: -S, --save 安装包信息将加入到dependencies(生产 ...
- bitset用法小结
bitset bitset大概就是类似于bool数组一样的东西 但是它的每个位置只占1bit(特别特别小) bitset的原理大概是将很多数压成一个,从而节省空间和时间(暴力出奇迹) 一般来说bits ...