canvas 中save() 和restore()

save()和restore()

save()和restore()方法是绘制复杂图形必不可少的方法.它们分别是用来保存和恢复 canvas 状态的,都没有参数。

  • canvas.save()用来保存先前状态的
  • canvas.restore()用来恢复之前保存的状态
    注:两种方法必须搭配使用,否则没有效果

对canvas中特定元素的旋转平移等操作实际上是对整个画布进行了操作, 默认情况下那么每一次绘图都会在上一次的基础上进行操作,最后导致错位。
比如 页面上的元素相对于原点30度递增旋转,30,60,90.如果不使用save 以及 restore
就会变成30, 90, 150,每一次在前一次基础上进行了旋转。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			canvas{
				background-color:#CECECE;
			}
		</style>
	</head>
	<body>
		<canvas width="400" height="400">
			
		</canvas>
		<script type="text/javascript">
			var canvas = document.querySelector("canvas");
			var ctx = canvas.getContext("2d");
			ctx.translate(100,10)
			for(var i = 1;i<3;i++){
				ctx.rotate(i*30* Math.PI/180 );		
				ctx.fillRect(100,10,100,50)
			}
		</script>
	</body>
</html>

在这里插入图片描述
按照正常的运算第二个图形应该旋转的是60度但是实际上他旋转了90度.这就是上面所述的会累加直线的旋转的度数.

利用canvas.save()和canvas.restore()就可以完美的解决问题;
在改变画布旋转之前前保存画布,在旋转之后回复之前保存的画布

var canvas = document.querySelector("canvas");
	var ctx = canvas.getContext("2d");
			ctx.translate(100,10)
			for(var i = 1;i<3;i++){
				//保存当前画布的环境
				ctx.save();
				ctx.rotate(i*30* Math.PI/180 );		
				ctx.fillRect(100,10,100,50)
				//回复之前保存的画布
				ctx.restore();
			}

在这里插入图片描述
canvas 在绘画的过程中难免会改变整个画布,导致坐标错位等情况,所以在我们改变整个画布之前使用save() 保存一下画布,在我们需要他回复之前的状态的时候使用restore()回到之前的状态

注意:回到之前保存的状态是不把画布的内容回到之前的状态,而是把画布的配置 比如原点,旋转角度,画笔的颜色等该变成之前的状态

比如一下情况

		var canvas = document.querySelector("canvas");
			var ctx = canvas.getContext("2d");
			ctx.translate(100,10)
			for(var i = 1;i<3;i++){
					//保存当前画布的环境
				ctx.save();
				if(i==1){
					ctx.fillStyle="red"
				}
				ctx.fillRect(100,10+i*100,100,50)
				//回复之前保存的画布
				ctx.restore();
			}

当 i ==1 的时候画笔填充色为红色

在这里插入图片描述

这是我们理想中的结果,但是当去掉canvas.save()和canvas.restore()时就达我们想象要的效果
在这里插入图片描述

方向推断可以得 可以把画笔的颜色变回到之前保存的状态,那么画笔的其他被配置是否也可以.

在Canvas环境中绘图时,canvas 状态是以堆(stack)的方式保存的,每一次调用 save 方法,当前的状态就会被推入堆中保存起来

如上所述用堆栈的原理来解释,就是调用save()方法时,将记录当前的绘图状态,并压入一个堆栈中;接着调用restore()方法时,就会把上一次记录的绘图状态从堆栈中弹出。

需要注意的是,出栈的次数不能多于入栈的次数,故程序中restore()方法调用的次数不应该比save()方法多。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值