scratchblocks icon indicating copy to clipboard operation
scratchblocks copied to clipboard

Scratchblocks SSR

Open FunctionalMetatable opened this issue 3 years ago • 9 comments

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?

FunctionalMetatable avatar Nov 07 '21 09:11 FunctionalMetatable

Can't it be rendered client-side?

CST1229 avatar Nov 07 '21 09:11 CST1229

Can't it be rendered client-side?

I want it to be rendered server-side so its less work for the client

FunctionalMetatable avatar Nov 07 '21 14:11 FunctionalMetatable

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.)

apple502j avatar Nov 10 '21 08:11 apple502j

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 to SVG.move which uses transform: translate(dx, dy).
  • L448, L523 This .width is also measured.
  • L600 This .width is measured, and goes to <rect>.
  • L652
  • L684
  • L755 etc.

apple502j avatar Nov 10 '21 14:11 apple502j

Somehow s3blocks do this?

FunctionalMetatable avatar Dec 06 '21 18:12 FunctionalMetatable

@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.

apple502j avatar Jan 30 '22 10:01 apple502j

@tjvr There are three ways for this:

  1. Calculate text width server-side. This can potentially lead to rendering issues (e.g. font difference?), but is easier.
  2. Make it generate a JavaScript code that would output SVG. Rendering would be correct, but may not be easy to use.
  3. Make everything server-side - the result is a PNG file and has no rendering issue, although this is terrible for accessibility.

apple502j avatar Jan 30 '22 13:01 apple502j

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.

tjvr avatar Mar 06 '22 18:03 tjvr

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.)

zamfofex avatar Jul 10 '23 19:07 zamfofex