Search code examples
htmlcanvashtml5-canvasdrawingcontext

Accessing the HTML5 Canvas's DrawingContext2D Save/Restore Stack?


Is there a way to access the HTML Canvas element's DrawingContext2D save and restore stack under the hood?

The purpose would be to save a base state, clip a region of it off, allow some operations to take place which may apply clip, save, restore with indeterminate orders (i.e. something might save 2-3 states to the stack and never restore them or it might restore multiple times and lose the original save state prior to going back to the parent function which would then be attempting to restore a state which no longer exists in the stack.)

I'd prefer to do this without a wrapper class around the DrawingContext2D since JavaScript gets a little slower with each function call and rendering tends to be time-sensitive.

It would also be great to be able to limit the number of restore calls possible in the called function without relying on the called function to maintain that limit.


Solution

  • Is there a way to access the HTML Canvas element's DrawingContext2D save and restore stack under the hood?

    The state stack is internal and not exposed in any way. You can tap into the save/restore calls themselves by promoting your own calls as wrappers on the context prototype (see for example this answer which shows one approach) and from there keep count track - this won't affect the rest of the context performance-wise. And of course you still won't have access to the internals. There would be some caveats though such as how do you differentiate call source and how will you know when a call should be allowed or not (calling restore() more than save() is btw. safe).

    However, if possible I would avoid using save/restore at all. Most states can be tracked "manually" by only tracking or setting the states you actually need including transformations (setTransform() is very handy here).

    The major obstacle is when using clipping. There is currently no way to reset clipping without using save/restore (or set size of the context) - the standard includes it but it doesn't seem to be supported by any vendors at this time. However, in many cases you can replace clipping by using compositing instead, sometimes combined with off-screen canvases.