Starter page - interactive diagrams

from Red Blob Games
14 Apr 2020

Table of Contents

I have a interactive tutorial that takes you step by step to make an interactive tutorial. However, the code for that is more involved than I’d like, so I wanted to make something even simpler.

 1  Vanilla javascript#

No libraries, no build step.

Demo and code[1]

Notes:

 2  Lit-html#

Small output library (11k), no build step required.

Demo and code[2]

Notes:

Tricky:

 3  Vue#

Medium sized input&output library (80k), no build step required.

Notes:

Tricky:

 4  React#

Medium sized input&output library (116k), build step strongly recommended to convert code into regular Javascript.

Demo and code[6] (demo doesn’t use the build step)

Notes:

Tricky:

 5  Preact + htm#

Small input&output library (10k), no build step needed if also using HTM (2k).

Demo and code[8] (demo doesn’t use the build step)

Notes:

Preact is like React, but without the tricky items I listed under React: it allows html names like class=… rather than javascript names like className=…; and it allows svg names like fill-opacity=… rather than fillOpacity like React requires. This means you can use an SVG visual editor and export it directly into Preact.

It normally uses JSX like React does but Preact’s HTM is like lit-html’s format, without the tricky items I listed under lit-html: you don’t have to have both html`` and svg``; the templates support xml syntax; and there’s a prebundled version of the library.

Tricky:

 6  Svelte#

Medium sized input&output library, build step required to convert Svelte code into regular Javascript

TODO: demo

Notes:

Tricky:

 7  My thoughts#

The main idea with templates is that instead of writing commands to generate html, we describe the html we want, with some placeholders for values that come from Javascript values. For example:

<rect fill=red x=${col} y=${row} width=1 height=1 />

Compare this to the vanilla approach:

let rect = document.createElementNS("http://www.w3.org/2000/svg", 'rect");
rect.setAttribute("fill", "red");
rect.setAttribute("x", col);
rect.setAttribute("y", row);
rect.setAttribute("width", 1);
rect.setAttribute("height", 1);
svg.appendChild(rect);

or the d3.js approach:

let rect = svg.append("rect")
              .attr("fill", "red")
              .attr("x", col)
              .attr("y", row)
              .attr("width", 1)
              .attr("height", 1);

I find templates to be a big win. The major libraries in this space (React, Vue, Svelte, Preact, lit-html) all use templates, but the details differ.

<!-- react/preact/vue with jsx -->
<rect fill=red x={col} y={row} width=1 height=1 />
<!-- vue templates -->
<rect fill=red :x="col" :y="row" width=1 height=1 />
<!-- lit-html, and react/preact with htm -->
<rect fill=red x=${col} y=${row} width=1 height=1 />

There’s some difference in how the templates are written. React uses an extension of Javascript called JSX to allow you to write html in your Javascript. You run a compiler to translate that into regular Javascript. Vue reads HTML from your document, or in strings in the source code. Lit-html uses a relatively new feature, Javascript template literals. Preact normally uses JSX but there’s an option to use HTM template literals. Svelte uses its own file format that is compiled into regular Javascript.

In addition, React, Preact, Vue, and Svelte offer a component system that allows you to create custom elements like <GridWorld> that are then expanded into HTML. Lit-html doesn’t do this, and instead leaves that to a separate library, LitElement. For my small projects, the component system doesn’t help me, as I can use regular Javascript functions and classes instead. However, for larger projects, it provides some modularity and also allows you to reuse components that others have written. LitElement uses standard web components that can be used with any other system, whereas React, Preact, Vue, Svelte components can only be used within their own system.

Tricky: in some of these template systems, it is hard to programatically construct the html in certain ways. For example in lit-html the tag name has to be specified statically.

Email me , or tweet @redblobgames, or comment: