Canvas的save和restore

我们在看很多自定义view的源码里经常会有canvas.save()和canvas.restore()出现,今天我们就来看一下canvas为什么要进行这样的操作以及这样的操作的原理.

在我们平时的概念里应该觉得canvas就是我们的屏幕,但是其实不是的,canvas其实应该是一个静态缓冲层,我们在canvas是做完绘画的操作,然后系统将canvas上的图像放置到屏幕上.下面我们举一个例子,具体步骤是首先在canvas上面画一个红色矩形,然后调用canvas.rotate()方法将canvas旋转一定角度后,然后再画一个绿色矩形,如果canvas对应的是我们看到的屏幕的话,那么红色的矩形也应该会跟绿色的一样发生倾斜,下面我们上代码:

protected void onDraw(Canvas canvas) {
	// TODO Auto-generated method stub
	super.onDraw(canvas);
	

	Paint paint_green = generatePaint(Color.GREEN, Style.FILL, 5);
	Paint paint_red   = generatePaint(Color.RED, Style.STROKE, 5);
	
	Rect rect1 = new Rect(300,10,500,100);
	canvas.drawRect(rect1, paint_red); //画出原轮廓
	
	canvas.rotate(30);//顺时针旋转画布
	canvas.drawRect(rect1, paint_green);//画出旋转后的矩形
} 
代码运行结果如图所示:

我们看到红色的矩形并没有跟随发生旋转,所以说我们的canvas并不是我们看到的屏幕.刚才我们说canvas是一个静态缓冲层,缓冲层已经证明了,那么为什么说是静态的呢?说canvas是静态是因为它发生变换(包括位移,旋转,切割,放缩,斜切)后是不可逆的,假如说我们执行了canvas.translate()方法让canvas向右平移100个像素,那么我们之后对canvas的所有绘画动作都是基于它位移过后的位置.

那么我们如何在一次canvas变换后重新得到初始状态的canvas呢,我们可以使用canvas.save()保存canvas状态,使用canvas.restore()来取回canvas.我们这里主要说的是canvas.save()和canvas.restore()的保存和取回规则.我们可以这样认为,调用canvas.save()方法我们将一个canvas实例放进了一个栈中,调用canvas.restore()方法是将一个canvas实例从栈中取出,我们知道栈的特点是后进先出,所以当我们多次调用canvas.save()方法后,再调用canvas.restore()方法,我们取出的是最后一个存入栈中的canvas实例,如果继续调用canvas.restore()我们得到的是倒数第二个存入栈中的canvas实例.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HTML5 canvas 是一个强大的绘图API,提供了一些方法来帮助开发者控制绘图状态。其中两个非常有用的方法是 save() 和 restore()。 save() 方法用于保存当前绘图状态,包括当前的变换矩阵、剪切区域和样式属性等。调用 save() 方法后,我们可以对绘图状态进行任意修改,而不会影响到之前保存的状态。 restore() 方法用于恢复之前保存的绘图状态。调用 restore() 方法后,我们可以回到之前保存的状态,并且继续在该状态下进行绘图操作。 这两个方法通常是成对使用的。例如,我们可以在进行一些复杂的绘图操作之前调用 save() 方法来保存当前状态,然后在绘制完成后调用 restore() 方法来恢复之前的状态。这样可以避免对后续绘图操作造成影响。 下面是一个简单的示例代码,演示了如何在 canvas 中使用 save() 和 restore() 方法: ```html <canvas id="myCanvas" width="200" height="100"></canvas> <script> var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); // 保存当前状态 ctx.save(); // 绘制一个矩形,并修改一些属性 ctx.fillStyle = "red"; ctx.fillRect(10, 10, 50, 50); ctx.strokeStyle = "blue"; ctx.lineWidth = 3; ctx.strokeRect(20, 20, 30, 30); // 恢复之前的状态 ctx.restore(); // 绘制一个圆形,此时样式属性已经恢复到之前的状态 ctx.beginPath(); ctx.arc(100, 50, 30, 0, 2*Math.PI); ctx.fillStyle = "green"; ctx.fill(); </script> ``` 在上面的代码中,我们首先调用了 save() 方法来保存当前状态,然后绘制了一个红色填充、蓝色边框的矩形。接着,我们又调用了 restore() 方法来恢复之前保存的状态。最后,我们绘制了一个绿色的圆形,此时样式属性已经恢复到之前的状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值