canvas理解:一看就懂的save和restore
一看就懂的save和restore
对于save()和restore()方法,我一开始有一个错误的理解,以为每一步都save()之后restore()就等同于command + z(或者ctrl + z),其实save()保存的只是CanvasRenderingContext2D对象的状态以及对象的所有属性,并不包括这个对象上绘制的图形。
如果对CanvasRenderingContext2D还不是很清楚又想要详细理解CanvasRenderingContext2D上的属性和方法的可以看这里
总结
- save:用来保存最近一次的Canvas的状态和属性。
- restore:用来获取save保存的Canvas之前的状态和属性。防止save后对Canvas执行的平移、放缩、旋转、错切、裁剪等可以改变画布的操作对后续的绘制的影响。
下面我会从颜色属性接平移属性对save和restore做解析,至于其他的放缩、旋转、错切、裁剪我就不一一说明,原理都是一样的,感兴趣的自行实验
- 颜色属性
<script>const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// 第一个矩形pinkctx.fillStyle = 'pink'ctx.fillRect(10,10,70,30);// 第二个矩形orangectx.fillStyle = 'orange'ctx.fillRect(130,10,70,30);// 第三个矩形yellowctx.fillStyle = 'yellow'ctx.fillRect(250,10,70,30);// 这矩形会自动继承上一次的canvas的状态,颜色是yellowctx.fillRect(370,10,100,100)
</script>
渲染效果:如果不保存之前的canvas状态,这最新一次的图形会自动继承上一次的canvas状态(上面的图形4就继承了图形3的颜色,表现为填充颜色为yellow)
<script>const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// 第一个矩形pinkctx.fillStyle = 'pink'ctx.fillRect(10,10,70,30);// 保存第一个canvas的状态ctx.save();// 第二个矩形orangectx.fillStyle = 'orange'ctx.fillRect(130,10,70,30);// 保存第二个canvas的状态ctx.save();// 第三个矩形yellowctx.fillStyle = 'yellow'ctx.fillRect(250,10,70,30);// 保存第三个canvas的状态ctx.save();// 回到第三次保存的canvas状态ctx.restore();// 这矩形会使用第三次的canvas的状态,颜色是yellowctx.fillRect(370,10,100,100)
</script>
渲染效果:由于依次保存了三次canvas的状态,然后restore了一次,所以canvas状态回到了倒数第一次save的状态(图形4就继承了图形3的颜色,表现为填充颜色为yellow)
<script>const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// 第一个矩形pinkctx.fillStyle = 'pink'ctx.fillRect(10,10,70,30);// 保存第一个canvas的状态ctx.save();// 第二个矩形orangectx.fillStyle = 'orange'ctx.fillRect(130,10,70,30);// 保存第二个canvas的状态ctx.save();// 第三个矩形yellowctx.fillStyle = 'yellow'ctx.fillRect(250,10,70,30);// 保存第三个canvas的状态ctx.save();// 回到第三次保存的canvas状态ctx.restore();// 回到第二次保存的canvas状态ctx.restore();// 这矩形会使用第二次的canvas的状态,颜色是orangectx.fillRect(370,10,100,100)
</script>
渲染效果:由于依次保存了三次canvas的状态,然后restore了两次次,所以canvas状态回到了倒数第二次save的状态(图形4就继承了图形2的颜色,表现为填充颜色为orange)
<script>const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// 第一个矩形pinkctx.fillStyle = 'pink'ctx.fillRect(10,10,70,30);// 保存第一个canvas的状态ctx.save();// 第二个矩形orangectx.fillStyle = 'orange'ctx.fillRect(130,10,70,30);// 保存第二个canvas的状态ctx.save();// 第三个矩形yellowctx.fillStyle = 'yellow'ctx.fillRect(250,10,70,30);// 保存第三个canvas的状态ctx.save();// 回到第三次保存的canvas状态ctx.restore();// 回到第二次保存的canvas状态ctx.restore();// 回到第一次保存的canvas状态ctx.restore();// 这矩形会使用第一次的canvas的状态,颜色是pinkctx.fillRect(370,10,100,100)
</script>
渲染效果:由于依次保存了三次canvas的状态,然后restore了三次,所以canvas状态回到了倒数第三次save的状态,也即是第一次save(图形4就继承了图形1的颜色,表现为填充颜色为pink)
**总结:**经过上面的实例,我们可以把save看成是一个入栈的过程,save一次,就向栈里面push一次cnavas的状态,而restore就是一个出栈的过程,每restore一次,就相当于弹出一次之前save的canvas状态,当前的canvas状态也就恢复成出栈的那个canvas状态,后面的图形的绘制就会在这个canvas状态之上绘制
- 平移(translate)
<script>const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// 矩形pink和矩形orange之间相隔20pxctx.fillStyle='pink';ctx.fillRect(10,10,100,100);ctx.fillStyle='orange';ctx.fillRect(130,10,100,100);
</script>
渲染效果:没有平移之前,pink和orange的矩形都是相对于红色坐标的(0,0)绘制
<script>const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// X坐标ctx.beginPath();ctx.lineWidth = 10;ctx.strokeStyle = 'red'ctx.moveTo(0,0);ctx.lineTo(600,0);ctx.stroke();// Y坐标ctx.beginPath();ctx.lineWidth = 10;ctx.strokeStyle = 'red'ctx.moveTo(0,0);ctx.lineTo(0,600);ctx.stroke();ctx.fillStyle='pink';ctx.fillRect(10,10,100,100);// 画布水平和垂直都平移了110px,相当于画布的之前的(0,0)坐标,变成了(110,110)ctx.translate(110,110);// X坐标ctx.beginPath();ctx.lineWidth = 5;ctx.strokeStyle = 'green'ctx.moveTo(0,0);ctx.lineTo(600,0);ctx.stroke();// Y坐标ctx.beginPath();ctx.lineWidth = 5;ctx.strokeStyle = 'green'ctx.moveTo(0,0);ctx.lineTo(0,600);ctx.stroke();ctx.fillStyle='orange';ctx.fillRect(130,10,100,100);
</script>
渲染效果:添加了ctx.translate(110,110)之后,相当于画布的之前的(0,0)坐标,变成了(110,110),orange矩形就相对于绿坐标(110,110)绘制
<script>const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// X坐标ctx.beginPath();ctx.lineWidth = 10;ctx.strokeStyle = 'red'ctx.moveTo(0,0);ctx.lineTo(600,0);ctx.stroke();// Y坐标ctx.beginPath();ctx.lineWidth = 10;ctx.strokeStyle = 'red'ctx.moveTo(0,0);ctx.lineTo(0,600);ctx.stroke();ctx.fillStyle='pink';ctx.fillRect(10,10,100,100);// 保存此时的canvas状态ctx.save();// 画布水平和垂直都平移了110px,相当于画布的之前的(0,0)坐标,变成了(110,110),坐标从红色变成绿色ctx.translate(110,110);// X坐标ctx.beginPath();ctx.lineWidth = 5;ctx.strokeStyle = 'green'ctx.moveTo(0,0);ctx.lineTo(600,0);ctx.stroke();// Y坐标ctx.beginPath();ctx.lineWidth = 5;ctx.strokeStyle = 'green'ctx.moveTo(0,0);ctx.lineTo(0,600);ctx.stroke();ctx.fillStyle='orange';ctx.fillRect(130,10,100,100);// 恢复之前保存的canvas状态,此时颜色yellow的矩形相对于之前的红色坐标绘制ctx.restore();ctx.fillStyle='yellow';ctx.fillRect(130,10,100,100);
</script>
渲染效果:使用ctx.save()来保存之前的canvas状态,使后面的yellow矩形绘制不受ctx.translate(110,110);影响,用ctx.restore()还原canvas状态,使矩形yellow是相当于红坐标(0,0)绘制
canvas理解:一看就懂的save和restore相关推荐
- canvas中save和restore的理解和使用
canvas中save和restore的理解和使用 理解save和restore不一定总是成对出现的 太阳系 理解save和restore不一定总是成对出现的 每个 canvas 的 context ...
- 理解Canvas的save()和restore()方法
save()和restore()方法是绘制复杂图形必不可少的方法.它们分别是用来保存和恢复 canvas 状态的,都没有参数. Canvas 状态是以堆(stack)的方式保存的,每一次调用 save ...
- 史密斯圆图串并联口诀_看得懂的史密斯圆图(个人总结)
看得懂的史密斯圆图(个人总结) 2018-09-11 史密斯圆图(Smith chart)是一款用于电机与电子工程学的圆图,主要用于传输线的阻抗匹配上.一条传输线(transmission line) ...
- 《零基础看得懂的C++入门教程 》——(10)面向对象
一.学习目标 了解C++类是什么 了解类对象与类型修饰一样进行创建 了解了类的属性如何使用 了解了类方法的使用方法 目录 预备第一篇,使用软件介绍在这一篇,C++与C使用的软件是一样的,查看这篇即可: ...
- 《零基础看得懂的C++入门教程 》——(5) 容我套个娃 循环
一.学习目标 了解循环的使用方法 目录 预备第一篇,使用软件介绍在这一篇,C++与C使用的软件是一样的,查看这篇即可:<软件介绍> 想了解编译原理和学习方法点这篇,学习方法和一些原理C++ ...
- 《零基础看得懂的C++入门教程 》——(4)条件判断原来如此
一.学习目标 了解什么是条件判断 了解多个条件判断 了解输入 了解什么是逻辑与.逻辑或 目录 预备第一篇,使用软件介绍在这一篇,C++与C使用的软件是一样的,查看这篇即可:<软件介绍> 想 ...
- 《零基础看得懂的C++入门教程 》——(2)什么是数据类型、变量?一看便会
一.学习目标 了解基本常用的数据类型 了解什么是变量 目录 预备第一篇,使用软件介绍在这一篇,C++与C使用的软件是一样的,查看这篇即可:<软件介绍> 想了解编译原理和学习方法点这篇,学习 ...
- 《假如编程是魔法之零基础看得懂的Python入门教程 》——(七)我把魔法变成了积木
学习目标 了解魔法积木的使用--自定义函数 了解魔法积木的结果反馈--自定义函数返回值 了解魔法积木的原料传递--自定义函数传参 了解魔法积木的类型分类--类与对象 推荐 1.<备受好评的看得懂 ...
- 《假如编程是魔法之零基础看得懂的Python入门教程 》——(六)精简魔法更强大
学习目标 了解对相似逻辑的简化编写--循环 推荐 1.<备受好评的看得懂的C语言入门教程> 目录 第一篇:<假如编程是魔法之零基础看得懂的Python入门教程 >--(一)既然 ...
最新文章
- 创建 VXLAN - 每天5分钟玩转 OpenStack(111)
- 线程锁与避免线程锁 线程锁检测
- “中能融合杯”线下赛感悟
- 2、安装和连接mysql
- stream of java_Java 8 新特性-Stream更优雅的处理集合入门
- 计算机基础知识教程算法,快速掌握!计算机二级公共基础知识教程:算法
- 【干货】联邦学习在腾讯微视广告投放中的实践
- SM系列国密算法(转)
- Mego(05) - Mego Tools使用教程
- 为什么程序员老在改 Bug,就不能一次改好吗?
- 使用Julia进行图像处理--JuliaImages介绍与基础使用
- linux 内核修炼之道——系统调用
- python程序设计总结报告_把PPT 总结报告上传
- 几种典型信号的频谱 周期单位脉冲序列的频谱
- 父亲母亲-山里老房子
- 微信支付元转分的正确姿势
- 使用腾讯云 SCF 云函数压缩 COS 对象存储文件
- Cocos Creator 3.61所有工具软件的使用
- 如何评价《就算老公一毛钱股份都没拿到,在我心里,他依然是最牛逼的创业者》里面这位CEO的所作所为?
- DeepCTR DeepMatch简单实用指南