-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[HTML] Canvas place element #1076
Comments
Copying over some of the offline discussion on this for posterity.
At first glance, positioning an element over the canvas seems like an obvious polyfill for this feature but it’s difficult to interleave canvas and DOM painted content. For example, you can’t render canvas painted content on top of the DOM element. There’s workarounds like stacking multiple canvas and DOM elements but that increases complexity. For 3D, there are both UI use cases, as well as text on GL cases).
What we have so far in Chrome is just a proof-of-concept. We plan to incubate this feature in WHATWG following the Stages process to ensure there’s extensive cross-browser and developer feedback before the API is shipped. We realize that this is not a trivial feature and will take time to properly consider all the issues.
A terse overview for how the feature works is that the browser keeps track of where the painted element draws into the canvas buffer. Such that if the element’s content changes (including its bounding box size), the canvas buffer is re-composited with the updated content. The browser also keeps track of the bounding box for each draw command along with its matrix/clip to support hit-testing. These data structures remain in sync with the element’s painted content into the canvas buffer. So the author wouldn’t need to do anything if the element’s rendering changes (from user interaction or otherwise). Top layer elements like select popovers could potentially be rendered outside of the canvas. The situation is more complicated for WebGL/WebGPU where the browser can’t automatically support re-rendering. The pattern there is to notify script when an element needs changes (i.e. when the browser would do a paint invalidation internally), and allow script to redraw the canvas in response. The hit testing data structures mentioned above are provided by script in this case. This does mean there’s more work on the author to redraw the element/keep the hit testing data in sync. But with this feature, it would be a small subset of the work they do today where in addition to managing redraw/hit-testing of interactive content, they have to:
There’s 2 ways we’re thinking about hit-testing:
For complex cases in WebGL/WebGPU a script API where if an event hits the canvas buffer we ask script to hit-test and provide the target element and map the point into the element’s image. This would take care of advanced shader cases like splitting an element into 2. The script API ensures that authors can handle any case and as patterns become more common, we can try to make them declarative.
Is this question similar to 2? Does our answer there address this concern?
Absolutely agreed. The standardization for this has only just started. We’re expecting a good chunk of the discussion to happen at WHATWG with instances of joint CSS/WHATWG meetings since there’s an overlap with CSS concepts.
There are design aspects which require close attention for good performance. For example, theoretically re-compositing the canvas when an element changes requires preserving all draw commands that have ever been rendered on the canvas. This is of course not possible so browsers would need to squash/layerize internally; detect when a command ( While it’s not trivial, ensuring good perf for this feature doesn’t seem insurmountable. |
Request for Mozilla Position on an Emerging Web Specification
@
-mention GitHub accounts): @khushalsagar, @fserbOther information
This proposal is being incubated in WICG and following the WHATWG stages process. Please use the WICG repo linked above for detailed issues.
The text was updated successfully, but these errors were encountered: