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
Appending canvas to SVG breaks canvas element #236
Comments
Please read the documentation for how namespaces work in D3. When you append an element and you don’t specify a namespace, it is inherited from the parent element. The only exception to this is elements whose name matches the namespace prefix, which in practice is just the |
Thanks for the quick help! I didn't find anything useful in the docs or on Stack Overflow. For future reference, the right way to specify the namespace is: const canvas = svg.append('xhtml:canvas'); It tried to solve the namespace problem with SVG attributes like |
The relevant documentation from the README is on selection.append:
In particular, “If no namespace is specified, the namespace will be inherited from the parent element.” Meaning that your append was equivalent to |
Appending a canvas node to a SVG node and trying to get a context results in an error message:
Uncaught TypeError: canvas.node(...).getContext is not a function
. This affects Chrome, Firefox and Safari. I didn't test other browsers.Minimal example:
Apparently the canvas node gets created using the wrong constructor:
SVGElement
. Wrapping the canvas in a SVG foreignObject didn't fix the problem for me.However, the canvas element works just fine when it is created using standard DOM API methods:
By doing so, the
HTMLCanvasElement
constructor is used to create the element, which seems to be correct.I never encountered this problem with d3-select outside of SVG nodes and I'm not sure whether this combination of SVG and canvas is even compatible with any web standard. The SVG
foreignObject
allows you to embed elements from a different namespace, but the examples I've seen so far were mostly XHTML-compatible, which canvas isn't (?).Still, most browsers care little about namespaces and will try to parse and render the content anyway. Having a canvas embed in SVG can be very convenient, especially when working with maps applications and d3-zoom.
Full demo: https://observablehq.com/@stekhn/d3-cant-create-canvas-element-within-svg-element
The text was updated successfully, but these errors were encountered: