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()状态的保存和恢复使用方法及实例的更多相关文章

  1. Android canvas.save()与canvas.restore()的使用总结

    含义canvas.save(); 画布将当前的状态保存canvas.restore(); 画布取出原来所保存的状态使用 canvas.save();与canvas.restore();一般结合使用,. ...

  2. activity状态的保存和恢复

    activity状态的保存和恢复 一.简介 1.保存activity状态 * 保存activity状态,onSaveInstanceState这个方法会自动保存有ID的组件的状态 * 没有ID的组件或 ...

  3. Android中canvas.save()和canvas.restore()的使用

    自己定义控件时经常遇到重写View的Ondraw()方法,Ondraw()方法经常设计到save()和restore()这两个方法.这两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的. ...

  4. Canvas状态的保存与恢复

    Canvas的API提供了save()和restore()的方法,用于保存及恢复当前canvas绘图环境的所有属性. save()与restore()方法可以嵌套调用 save()方法将当前绘图环境压 ...

  5. Android之Activity状态的保存和恢复

    系统在某些情况下会调用onSaveInstanceState()和onRestoreInstanceState() 这两个方法来保存和恢复Activity的状态. 一句话:Activity在" ...

  6. Android开发中Activity状态的保存与恢复

    当置于后台的Activity因内存紧张被系统自动回收的时候,再次启动它的话他会重新调用onCretae()从而丢失了之前置于后台前的状态. 这时候就要重写Activity的两个方法来保存和恢复状态,具 ...

  7. Activity 状态的保存和恢复

    Activity状态保存的两种情况 一.Activity状态保持概念 保存Activity的状态是非常重要的,例如我们在玩一个游戏的时候,突然来了一个电话,这个时候在接听完电话之后我们返回到游戏中,这 ...

  8. Android笔记之自定义的RadioGroup、RadioButton,以及View实例状态的保存与恢复

    效果图 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLay ...

  9. 【转】Android Canvas的save(),saveLayer()和restore()浅谈

    Android Canvas的save(),saveLayer()和restore()浅谈 时间:2014-12-04 19:35:22      阅读:1445      评论:0      收藏: ...

随机推荐

  1. 在阿里云 ECS 搭建 nginx https nodejs 环境 (一、 nginx)

    首先介绍下相关环境.软件的版本 1.阿里云 ECS . ubuntu-14.04.5 LTS 2.nginx 版本 1.9.2 可能会遇到的问题: 一.在 ssh 服务器上的时候,提示 这个时候需要将 ...

  2. 用户身份切换之初窥企业远程用户没root还有root权限

    一直很困扰我,既然企业不让用root不能登录,那怎么操作文件呢? 原来...... su -    用来切换初始变量 $PATH $HOME等 sudo 用的时候会su到root需要root的密码,这 ...

  3. 做了2个多月的设计和编码,我梳理了Flutter动态化的方案对比及最佳实现

    背景 在端上为了提升App的灵活性, 快速解决万变的业务需求,开发者们探索了多种解决方案,如PhoneGap ,React Native ,Weex等,但在Flutter生态还没有好的解决方案.未来闲 ...

  4. 新的一年,来看看大数据与AI的未来展望

    本文由云+社区发表 作者:堵俊平 在数据爆炸与智能革命的新时代,新的平台与应用层出不穷,开源项目推动了前沿技术和业界生态快速发展.本次分享将以技术和生态两大视角来看大数据和人工智能技术的发展,通过分析 ...

  5. [四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式

      前言简介   前文已经对虚拟机进行过了简单的介绍,并且也对class文件结构,以及字节码指令进行了详尽的说明 想要了解JVM的运行机制,以及如何优化你的代码,你还需要了解一下,java编译器到底是 ...

  6. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

  7. 【原创】PicUploader: 一个还不错的图床工具

    PicUploader PicUploader 是一个用php编写的图床工具,它能帮助你快速上传你的图片到云图床,并自动返回Markdown格式链接到剪贴板.配置完成后,要获取一个可用于markdow ...

  8. .NET [MVC] 利用特性捕捉异常

    声明:本代码只适用于.NET MVC. 先创建一个类继承ActionFilterAttribute这个抽象类以及实现IExceptionFilter接口,并实现它的方法OnException. 代码如 ...

  9. pl/sql to_date

    to_date 函数:TO_DATE( string1 [, format_mask] [, nls_language] ) 后面两个函数为可选 ,意思将字符串类型转换为时间类型 , 可以自定义时间格 ...

  10. Java开发笔记(七十四)内存溢出的两种错误

    前面介绍的几种异常,其实都存在这样那样的逻辑问题,属于程序员的编码手误.还有一大类系统错误,表面上看不出什么问题,但是程序仍然运行不下去,兹举二例说明.第一个例子且看下列的测试代码: // 测试内存溢 ...