I am wondering why and when you would use Canvas.save
, Canvas.restore
, and maybe even Canvas.saveLayer
.
I have heard that they are really useful, but I do not know when to use them.

- 114,516
- 58
- 291
- 402
-
1fun fact : im using your repo and also wonder what save and store did rofl ( funvas btw ) – shadow Nov 01 '22 at 11:25
1 Answers
Canvas.save
and Canvas.saveLayer
work slightly differently, but they both have the same counterpart:
Canvas.restore
This allows you to restore the state before the most recent entry on the save stack, i.e. it "Pops the current save stack". This means that any transformations and clips done to the canvas in the current state will be removed and if saveLayer
was used, the saved layer will be composited into the canvas (the draw order will remain the same).
Canvas.save
As I mentioned earlier, this allows you to save the state the canvas is in. You can do any transformation and clips you want and those will be removed using 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.
You can use any number of save
before restore
and the stack will remember all entries, i.e. restore
will always pop the most recent entry.
When would I use this?
Example: if you wanted to rotate a single piece when drawing a bigger picture, you can simply do the rotation inside a save
-restore
block and draw something without the rotation on top afterwards.
Note that all children of a RenderObject
will use the same PaintingContext
, i.e. the same Canvas
. So if you transform the canvas in a single child, it will also be transformed for all other children that draw afterwards. This is potentially unwanted behavior and the reason why you always want to save
and restore
the canvas state.
Canvas.saveLayer
This is a bit more complicated and I urge you to read the comprehensive documentation of this method. Btw, saveLayer
does not work in Flutter web as of January, 2019.
The basic difference between saveLayer
and save
is that saveLayer
will composite the layer upon usage of restore
. For a simple example, I constructed this snippet without bounds
(which is why null
is passed), which will save the whole canvas:
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.
Note that the blue rect will still be composited above the red rect.
This example could also be achieved without using saveLayer
because the Paint.blendMode
I used can also be passed to Canvas.drawRect
. However, when using e.g. a TextPainter
, you cannot pass blend modes. Additionally, saveLayer
allows you to pass bounds, which gives far more possibilites (read the documentation for more information, also about clips). Clipping is actually probably the most useful operation in combination with saveLayer
- I did not include it in order to have a simple example.
This is how the example would look without saveLayer
:

- 114,516
- 58
- 291
- 402
-
2I appreciate your interesting questions and answers. But I was wondering why you create these questions and reply to them immediately. Wouldn't it make more sense to write an article about it? – J. S. Jan 11 '20 at 18:33
-
@JoãoSoares Nice question :) So why I create them: [This](https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions/) and with this one I answered a [question on Twitter](https://twitter.com/wyldebill00/status/1214744228259082240?s=20) - I actually linked to it in my question. Generally, I do this when I ask myself something and think it would be useful for others to find out what my research has shown. For example, turns out [this question](https://stackoverflow.com/q/50081213/6509751) was extremely popular *after* I asked about it - I was able to help many people. – creativecreatorormaybenot Jan 11 '20 at 22:08
-
@JoãoSoares As I accept my own answers in that case (to show that the question has an answer), I could also write articles, yes. I will be getting into writing articles - I recently wrote [this "test" article](https://medium.com/@creativecreatorormaybenot/sites-shamelessly-ripping-off-stack-overflow-content-4c10597ade57?source=friends_link&sk=e6b6e61bf938be6495208cfdad1f075b) (maybe it is interesting to you). However, I see a few benefits to writing an answer in this article style on SO: it is more concise and easier to find, probably helps more people and there are less expectations. – creativecreatorormaybenot Jan 11 '20 at 22:13
-
@JoãoSoares I will try to write an article about render objects and stuff (in connection to the Flutter Clock challenge) soon and then I can see how that works out for me. If you have any feedback about my style of writing or w/e or any questions in general, just HMU. I am glad to answer them :) – creativecreatorormaybenot Jan 11 '20 at 22:15
-
1Thank you for the replies. I am definitely interested. I love Flutter and have dedicated a lot of time to it. Learning more is always great and it looks like you have a lot to teach. Thank you for sharing. – J. S. Jan 11 '20 at 22:17
-
@JoãoSoares This is great to hear :) I think that most of the topics that would be discussed in articles are rather lengthy and a decent commitment to cover - like your video tutorials, which I appreciate. In that sense, I am not sure if I see myself as a "teacher" enough. I try to share my experience whenever I can to help out others and because I believe in this community. The StackOverflow community is very helpful and the same applies to people making tutorials and writing articles! I like about SO that writing an answer is not a huge commitment to make (: – creativecreatorormaybenot Jan 11 '20 at 22:40
-
Thank you for this well written answer. As you said so yourself, the example you provided for `Canvas.saveLayer` is not a good use for saveLayer. In the flutter docs, they gave an example of "having multiple semi-transparent objects", if those were drawn separately, the overlapping parts will be darker than usual. With `saveLayer` we can then draw objects with opaque paint on a saved layer, then apply opacity in one go. I think that would be a good example but I couldn't find a way to apply arbitrary alpha value when blending. Do you think what they said is actually doable? – WSBT Feb 24 '21 at 07:32