保存画布然后恢复,为什么?

问题描述 投票:21回答:4

我经常看到以下代码

canvas.save().
canvas translate or rotate
some drawing
canvas.restore

我不明白为什么我们保存然后恢复。什么是取消我们刚刚做的事情的重点!我相信我在这里遗漏了一些谢谢

android android-canvas
4个回答
17
投票

我知道这个问题有点陈旧,但对于仍在寻找答案的人我可以ELI5;

想象一下,画布是一张纸,你的任务是将机器人的画面正面向上,底部,另一个机器人颠倒,略微向右移动,顶部小约40%。像这样的东西; Android canvas example

你会怎么开始?先做什么更容易?

您可能会在底部绘制较大的机器人,因为它是正面朝上的,并且在感觉更自然的方向上绘制要容易得多。所以你已经完成了第一个,现在你如何接近第二个颠倒的机器人?

  • 您可以尝试按原样绘制它,但由于您是颠倒的,这将有点困难。

要么

  • 您可以将纸张旋转180°,稍微移动起点,然后以较小的比例开始绘图,完成所有操作后,只需将纸张旋转回来即可。

这就是canvas.save()canvas.restore()所做的,它们允许您以任何方式修改画布,使您更容易画出您需要的东西。您不需要使用这些方法,但它们确实简化了很多过程。上面看起来像

drawRobot()
canvas.save()
canvas.rotate(180)
canvas.translate(100, 0)
canvas.scale(40,40)
drawRobot()
canvas.restore()

如果我们查看restore()文档,它说

用于删除自上次保存调用以来对矩阵/剪辑状态的所有修改

并且看看这些修改是什么我们看看save()它说

translate,scale,rotate,skew,concat或clipRect,clipPath

那么看,我们确实使用translate rotatescale,但我们也打电话给drawRobot()所以不会叫restore擦除我们的绘图?不,因为它不影响绘图,只有修改。因此,当我们调用restore时,它会将我们的画布返回到我们开始第二次绘制之前所处的状态。


29
投票

什么是取消我们刚刚做的事情的重点!

不过,你不是。如果你只是说这些话,听起来就像是可能发生的事情,但实际上并非如此。

可以这样想:

您需要在同一个onDraw(Canvas)调用中应用一系列非常复杂的翻译和旋转。现在,由于您应用于Canvas的每个平移/旋转按顺序发生,您必须撤消对Canvas的最后调整,或以某种方式计算基于前一个的新调整,然后绘制您想要绘制的任何内容。这会很快变得非常混乱。

使用canvas.save()canvas.restore()是简化该过程的一种非常简单的方法。

通过在保存/恢复块中进行适用于Canvas的调整,您可以有效地隔离所述调整,以便您想要绘制的任何内容都不会受到您现在绘制的内容的影响。

现在,更好地解释名称:

canvas.save()说我想保存当前Canvas调整的状态,以便我可以稍后再回过头来。

canvas.restore()说我想恢复我的Canvas的调整回到我最后一次打电话给cavas.save()

它的美妙之处在于它的简洁。如果您已经在保存/恢复区域中绘制了想要绘制的任何内容,并且您不再需要为下一个绘图进行这些调整,那么使用这个让您丢弃那些不必要的调整并返回到您想要开始下一个绘图的状态从。

希望这有助于解释它!


1
投票

使用画布涉及画布上的所有翻译,缩放,旋转,倾斜过程。 save()方法在任何上述增强之前保留一个状态,restore()回退到没有注入增强的状态。换句话说,您可以在任何画布转换之前保存前置状态,在旋转过程中以及在此过程中您想要的任何其他内容,但是在完成任何扩充之前完成倒回到状态。


0
投票

当您有一个由多个对象组成的背景时,一个很好的方法是保存这个“静态”背景并仅重绘已更改的对象。这节省了(处理器)时间。

© www.soinside.com 2019 - 2024. All rights reserved.