scratchblocks
scratchblocks copied to clipboard
Scratchblocks SSR
I'm making a tutorials site (using svelte and sveltekit) and it seems that scratchblocks only can run in the browser. Is there anyway to support SSR/svg strings?
Can't it be rendered client-side?
Can't it be rendered client-side?
I want it to be rendered server-side so its less work for the client
Syntax parsing can be done on the server (and there is a unittest for that).
Rendering, on the other hand, requires client:
- The code assumes DOM is available. This is less of a concern when using JSDOM etc.
- Likewise, it also requires XML parsing/serializer to be available.
-
The generated SVG depends on rendered text size - before rendering, the code calls
measureText
to measure the length of the strings used, in whatever font it is using.
If that one gets fixed in some way, this can be rendered server-side. Until then, it's time to use puppeteer. (Luckily, the setup is already there.)
Usage of .width
(used for rendering): scratch3/blocks.js
- L87 This is NOT measured. Additionally, the value isn't used anyway (ignored inside SVG.symbol)
- L178 This value, and therefore
InputView.width
, IS measured. the value is calculated and passed toSVG.move
which usestransform: translate(dx, dy)
. - L448, L523 This
.width
is also measured. - L600 This
.width
is measured, and goes to<rect>
. - L652
- L684
- L755 etc.
Somehow s3blocks do this?
@FunctionalMetatable This requires canvas
dependency, and doesn't make sense, since text measurement and actual rendering should be performed at the same time for it to be effective.
@tjvr There are three ways for this:
- Calculate text width server-side. This can potentially lead to rendering issues (e.g. font difference?), but is easier.
- Make it generate a JavaScript code that would output SVG. Rendering would be correct, but may not be easy to use.
- Make everything server-side - the result is a PNG file and has no rendering issue, although this is terrible for accessibility.
I'm not sure what you mean by (2) -- how would this be different to using the library currently?
I think rendering to PNG would probably be the only sensible way to achieve "server-side rendering", if you really want to.
I have recently decided to set up something like this myself, so that people may more easily embed blocks on GitHub and Discord (and other places) which do not support the plugin!
SVG
There is also proof-of-concept support for PNG output support, but it does not have text until yisibl/resvg-js#217 is merged.
PNG
To use, just percent‐encode the program and put it into the URL’s query part (line breaks can be encoded as %0A
): https://scratch.deno.dev/blocks.svg?say%20%5BHello%21%5D
(Hmm, now that I think about it, maybe I should set up some way to control the size of the blocks.)