cre*_*not 17 skia dart flutter
我想知道您为什么以及何时会使用Canvas.save
, Canvas.restore
,甚至Canvas.saveLayer
.
我听说它们真的很有用,但我不知道什么时候使用它们。
cre*_*not 22
Canvas.save
并且Canvas.saveLayer
工作方式略有不同,但它们都有相同的对应物:
Canvas.restore
这允许您恢复保存堆栈上最新条目之前的状态,即“弹出当前保存堆栈”。这意味着在当前状态下对画布所做的任何转换和剪辑都将被删除,如果saveLayer
使用,保存的图层将被合成到画布中(绘制顺序将保持不变)。
Canvas.save
正如我之前提到的,这允许您保存画布所处的状态。您可以进行任何您想要的转换和剪辑,这些将使用restore
以下命令删除:
canvas.save();
canvas.transform(..); // Transforms the canvas, which will affect the draw call.
canvas.drawRect(...); // Affected by the transform.
canvas.restore();
canvas.drawRect(...); // Not affected by the transform.
Run Code Online (Sandbox Code Playgroud)
您可以使用任意数量的save
before restore
,堆栈将记住所有条目,即restore
始终弹出最近的条目。
示例:如果您想在绘制更大的图片时旋转单个部分,您可以简单地在save
-restore
块内进行旋转,然后在顶部绘制一些没有旋转的东西。
请注意, a 的所有子项RenderObject
都将使用相同的PaintingContext
,即相同的Canvas
。因此,如果您在单个子级中转换画布,它也会为之后绘制的所有其他子级转换。这是潜在的有害行为,也是您总是想要save
和restore
画布状态的原因。
Canvas.saveLayer
这有点复杂,我强烈建议您阅读此方法的综合文档。顺便说一句,截至 2019 年 1 月,saveLayer
在Flutter web 中不起作用。
saveLayer
和之间的基本区别save
是saveLayer
将在使用restore
. 举个简单的例子,我在没有 bounds
(这就是为什么null
通过)的情况下构建了这个片段,这将保存整个画布:
canvas.drawRect(rect, Paint()..color = const Color(0xffff0000)); // Draws a red rect.
canvas.saveLayer(null, Paint()..blendMode = BlendMode.multiply); // Saves the whole canvas.
canvas.drawRect(
rect.shift(const Offset(20, 20)),
Paint()..color = const Color(0xff0000ff), // Draws a blue rect.
);
canvas.restore(); // Composites the red rect into the blue rect.
Run Code Online (Sandbox Code Playgroud)
请注意,蓝色矩形仍将合成在红色矩形上方。
这个例子也可以不用 using 来实现,saveLayer
因为Paint.blendMode
I used 也可以传递给Canvas.drawRect
. 但是,当使用例如 a 时TextPainter
,您不能传递混合模式。此外,saveLayer
允许您传递边界,这提供了更多的可能性(阅读文档了解更多信息,也关于剪辑)。剪裁实际上可能是结合使用最有用的操作saveLayer
- 我没有包括它是为了有一个简单的例子。
这是示例在没有的情况下的外观saveLayer
: