A surprise to see my page on HN! For those of you curious about the tech:

Diagrams are in SVG. Canvas would be faster but SVG is easier for me to work with, especially for attaching mouse events to each hexagon. It also automatically scales to high dpi displays. With SVG and HTML accessed the same way, I can use the same code for updating text/samples as I do for updating diagrams. This includes interpolating values as noted by anchpop.

I don't use a build step for the JS code. It's just <script> tags, like it's 1999! You can View Source and see them all. I realize it'd be better if I minified bundled etc. but I'm lazy and this was easier. The page is implemented differently from a "single page app". For that, you might want something like JSX so that you can stay on the JS side, and output HTML+CSS as needed. For this kind of page, I mostly write HTML+CSS, and I tap into JS when needed using Vue.js. For example, I want the text "w = 2 * size" to be next to the rest of the text for that paragraph, instead of in a separate JS file:

<p>
Next we want to put several hexagons together.
In the {{layout}} orientation, a hexagon
has width
<code v-if="layout === 'flat'">w = 2 * size</code>
<code v-else="">w = sqrt(3) * size</code>
…
</p>

I do use a build step for the HTML+SVG. Although the page works without this step (see pre-index.html), the user experience is a little bit better if I generate it on the server. I use cheesy pre-rendering for this: "$(CHROME) --headless --disable-gpu --dump-dom". It means more bytes :( but having all the HTML/SVG load at once is better for linking to a section, hitting the back button, etc. You don't lose the scroll position. Bonus: the page loads if you have Javascript turned off!

The static SVG on the server doesn't include the interactive parts. I use InteractionObserver to replace the static diagram with an interactive one as soon as you scroll to that section of the page.

I said I don't have a JS build step, but that's not quite true. The core hexagon algorithms were originally implemented in Haxe, compiled to Javascript. At the time (2013), I was curious about Haxe as an alternative to Javascript. Because I was either bored or crazy or both, in 2015 I implemented a code generator that used Haxe macros to parse the algorithms in Haxe-ish syntax[1] and then generate C++, Javascript, Python, and other output. The Javascript output from that is what now powers the page. Well, it's even more convoluted than that. The Haxe code generates Typescript[2], which I turn into Javascript[3]. I don't know what I was thinking! Well, I do — I wanted my readers to be able to use my unit-tested hexagon algorithms even if they were using a different programming language.

I wrote [4] describing the process of making an interactive page like this with D3.js. Check out [5] for a collection of interactive explanations from other people.

It's unlikely that you will print the page, but if you do, it will show endnotes for all the links so that you can see the URLs.[6]

[1] https://www.redblobgames.com/grids/hexagons/codegen/Codegen....
[2] https://www.redblobgames.com/grids/hexagons/codegen/output/l...
[3] https://www.redblobgames.com/grids/hexagons/codegen/output/l...
[4] https://www.redblobgames.com/making-of/line-drawing/
[5] https://explorabl.es/
[6] https://simblob.blogspot.com/2018/12/printing-my-pages.html