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. Java基础8:深入理解内部类

    更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...

  2. 【Java基础】【08面向对象_继承&方法&final】

    08.01_面向对象(代码块的概述和分类)(了解)(面试的时候会问,开发不用或者很少用) A:代码块概述 在Java中,使用{}括起来的代码被称为代码块. B:代码块分类 根据其位置和声明的不同,可以 ...

  3. .NET快速信息化系统开发框架 V3.2 -> WinForm“组织机构管理”界面组织机构权限管理采用新的界面,操作权限按模块进行展示

    对于某些大型的企业.信息系统,涉及的组织机构较多,模块多.操作权限也多,对用户或角色一一设置模块.操作权限等比较繁琐.我们可以直接对某一组织机构进行权限的设置,这样设置后,同一组织机构的用户就可以拥有 ...

  4. vue开发项目详细教程(第一篇 搭建环境篇)

    最近做vue做项目碰到了不少坑,看了三天文档便开始上手做项目了,不是我牛b,是因为项目紧,我没有时间去深入学习,所以只能一边学一边做了. 我要做的项目是一个官方网站(包括管理后台),也因为是我第一次使 ...

  5. Signalr指定Websocket方式跨域数据传输

    跨域通俗理解就是两个域名后面的web服务地址,即都是独立的网站.现实业务的情况会有很多需要跨域推送数据的情况, 比如类似饿了么商户后台会收到客户端确认订单后,后台服务会推送一条订单消息给商户前台. S ...

  6. Kafka基础入门

    1. Kafka简介 Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写.Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作 ...

  7. Django 系列博客(十六)

    Django 系列博客(十六) 前言 本篇博客介绍 Django 的 forms 组件. 基本属性介绍 创建 forms 类时,主要涉及到字段和插件,字段用于对用户请求数据的验证,插件用于自动生成 h ...

  8. .net里面的字典Dictionary

    Dictionary<int, string> d = new Dictionary<int, string>();            d.Add(1, "wjl ...

  9. [转]nodejs使用request发送http请求

    本文转自:https://blog.csdn.net/dreamer2020/article/details/52074516/ 在nodejs的开发中,有时需要后台去调用其他服务器的接口,这个时候, ...

  10. Java开发笔记(五十五)关键字static的用法

    前面介绍嵌套类的时候讲到了关键字static,用static修饰类,该类就变成了嵌套类.从嵌套类的用法可知,其它地方访问嵌套类之时,无需动态创建外层类的实例,直接创建嵌套类的实例就行.其实static ...