Rewrite rendering code to use canvas instead of SVG
This still requires a good bit of research and at least a few demos to make sure various features work as required across browsers, but it looks like it should be possible to render the expressions using canvas instead of SVG. This should provide quite a speed boost since it will be possible to pre-plan where elements need to be positioned, then just render them (instead of the current process of rendering them to the SVG element, the re-positioning once dimensions can be calculated...leading to may reflows and rerenders event with the image off-screen). All current features should still be possible, including the link to download the image.
The only downside I can think of so far is that the resulting image would be a PNG instead of SVG, so enlarging would not be possible. The upside to the different image format is more consistent rendering by applications (I've seen the SVG images have varying levels of inconsistent rendering between applications...mostly due to font sizing/positioning).
-
HTMLCanvasElement.toDataURL() can be used to convert the rendered image to a
data:
URL for the download link. Users can also just right-click on the image to download it, so the download link may not even be necessary in this case. - CanvasRenderingContext2D.measureText() can be used to determine the size of rendered text for sizing and positioning boxes around the text
- The TextMetrics object returned by
measureText
appears to only supportwidth
across browsers. This might be all that is necessary (there are no multi-line strings rendered, so it may be possible to just guess on a height). This will have to be experimented with.
The rest of the rendering consists of drawing lines (some bezier or quadratic), boxes, and circles; all of which can be handled by canvas methods easily enough.
The basic building block that needs to be proven in order for canvas rendering to be viable is drawing a single line of text within a filled box with rounded corners and knowing what the bounding box of the result will be before it is rendered.