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

Sna*_*ake 29 android android-canvas

我经常看到以下代码

canvas.save().
canvas translate or rotate
some drawing
canvas.restore
Run Code Online (Sandbox Code Playgroud)

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

Cru*_*ceo 29

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

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

可以这样想:

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

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

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

现在,更好地解释名称:

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

canvas.restore()是说我想把我Canvas的调整还原到我最后一次打电话的时候cavas.save()

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

希望这有助于解释它!

  • 非常感谢您的解释.因此,如果我们保存状态,进行绘图和矩阵变换然后进行恢复,那么我们就有效地删除了我们所做的事情.因此,当我们完成提取时,事情将与我们开始提取时的情况相同.那么这种方法没用了,不是吗?我想你会恢复你开始提取而不是最后恢复.我在这里仍然缺少一些东西,我不是:)? (2认同)
  • 现在,如果你在同一个onDraw方法中对几个不同的对象进行了几次不同的调整; 突然保存/恢复成为神派.假设您在(0,0)处有对象A,B.您想将A移动到(30,0),将B移动到(0,50).首先很容易.将画布翻译为30.完成.现在第二个是它变得有趣的地方,因为你不只是从0到50,你在x中是30到0,然后在0到50,所以你要翻译(-30,50)而不是我们的简单(0,50).现在,如果您在保存/恢复中进行A的翻译,您将只能翻译(续...) (2认同)

Pzt*_*tar 24

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

想象一下,画布是一张纸,您的任务是在右下方(底部朝上)绘制一个机器人的图片,在下一个机器人(向右上方稍稍移到顶部)缩小约40%的位置绘制图片。像这样的东西; Android canvas示例

您将如何开始?首先更容易做什么?

您可能会首先在底部绘制较大的机器人,因为它朝上,并且朝着更自然的方向绘制要容易得多。这样您就完成了第一个,现在如何处理第二个倒置机器人?

  • 您可以尝试按原样绘制它,但这会有些困难,因为您的颠倒了。

要么

  • 您可以将纸张旋转180°,稍微移动起点,然后以较小的比例开始绘制,完成之后,您只需向后旋转纸张即可。

这是什么canvas.save()canvas.restore()做什么,他们让你修改你的画布以任何方式,使得它更容易为你画你所需要的。您不需要使用这些方法,但是它们确实可以简化很多过程。上面看起来像

drawRobot()
canvas.save()
canvas.rotate(180)
canvas.translate(100, 0)
canvas.scale(40,40)
drawRobot()
canvas.restore()
Run Code Online (Sandbox Code Playgroud)

如果我们看一下restore()文档说

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

并查看这些修改都是我们来看看save()它说:

平移,缩放,旋转,倾斜,合并或clipRect,clipPath

好了,看看,我们实际上使用过translate rotatescale但是我们也确实调用过,drawRobot()所以不调用会restore擦除我们的图形吗?不,因为它不影响图形,影响修改。因此,当我们调用restore它时,它将使画布返回到开始第二个绘图之前的状态。

  • 我读过一段时间的最佳答案。加油! (3认同)