From 9e9464e797c72262e45efed1502c7dfd3c9996c2 Mon Sep 17 00:00:00 2001 From: Zach Dunn Date: Fri, 16 Oct 2026 11:03:22 -0400 Subject: [PATCH 1/3] feat(site): a tilted table of the examples as the home page hero The hero now shows each example as a cluster on a tilted table: the post as a tall page, two of its figures pulled out with leaders, its deck, its video, and for Sunny the room from its post as a 3D model, with the camera orbiting it. The camera settles on a cluster, glides to the next and wraps; a chip types the request that made the cluster in view, and a pager picks one. It's one three.js scene (site/assets/hero/hero.js, layout in layout.js), rendered on demand and only while the hero is on screen, at most 1.25x the screen's density into a 2x multisampled target. Images are cut to the width they're drawn at, in a desktop and a phone size, since the GPU holds them decoded whatever their format. A baked poster shows until the scene is ready, and for good under reduced motion or without WebGL. - site/hero.mjs cuts the images (from site/hero/src) and bakes the posters with Chrome, like card.mjs; its output is committed. - three.js r160 is served from the site, named by an import map. - The build copies site/assets/hero whole; the Worker answers Range requests for the hero's videos too, which Safari needs to play them. --- dev/test/site.test.mjs | 23 + docs/developing.md | 5 +- site/assets/hero/d/releases/digest-card.jpg | Bin 0 -> 16015 bytes site/assets/hero/d/releases/frame-01.jpg | Bin 0 -> 8524 bytes site/assets/hero/d/releases/frame-03.jpg | Bin 0 -> 6878 bytes site/assets/hero/d/releases/frame-05.jpg | Bin 0 -> 5211 bytes site/assets/hero/d/releases/frame-07.jpg | Bin 0 -> 5004 bytes site/assets/hero/d/releases/post.jpg | Bin 0 -> 50786 bytes site/assets/hero/d/releases/replay-tue.jpg | Bin 0 -> 8513 bytes site/assets/hero/d/sunny/boardroom.jpg | Bin 0 -> 7966 bytes site/assets/hero/d/sunny/frame-01.jpg | Bin 0 -> 9997 bytes site/assets/hero/d/sunny/frame-02.jpg | Bin 0 -> 5975 bytes site/assets/hero/d/sunny/frame-05.jpg | Bin 0 -> 6867 bytes site/assets/hero/d/sunny/frame-07.jpg | Bin 0 -> 5856 bytes site/assets/hero/d/sunny/lamp-after.jpg | Bin 0 -> 6857 bytes site/assets/hero/d/sunny/post.jpg | Bin 0 -> 61521 bytes site/assets/hero/d/uploads/comment-pair.jpg | Bin 0 -> 11376 bytes .../hero/d/uploads/file-page-compare.jpg | Bin 0 -> 6629 bytes site/assets/hero/d/uploads/frame-01.jpg | Bin 0 -> 7621 bytes site/assets/hero/d/uploads/frame-02.jpg | Bin 0 -> 5860 bytes site/assets/hero/d/uploads/frame-03.jpg | Bin 0 -> 6296 bytes site/assets/hero/d/uploads/frame-06.jpg | Bin 0 -> 6413 bytes site/assets/hero/d/uploads/post.jpg | Bin 0 -> 59770 bytes site/assets/hero/hero.js | 356 ++ site/assets/hero/layout.js | 45 + site/assets/hero/m/releases/digest-card.jpg | Bin 0 -> 6714 bytes site/assets/hero/m/releases/frame-01.jpg | Bin 0 -> 4152 bytes site/assets/hero/m/releases/frame-03.jpg | Bin 0 -> 3306 bytes site/assets/hero/m/releases/frame-05.jpg | Bin 0 -> 2497 bytes site/assets/hero/m/releases/frame-07.jpg | Bin 0 -> 2930 bytes site/assets/hero/m/releases/post.jpg | Bin 0 -> 21203 bytes site/assets/hero/m/releases/replay-tue.jpg | Bin 0 -> 4126 bytes site/assets/hero/m/sunny/boardroom.jpg | Bin 0 -> 4060 bytes site/assets/hero/m/sunny/frame-01.jpg | Bin 0 -> 4665 bytes site/assets/hero/m/sunny/frame-02.jpg | Bin 0 -> 3023 bytes site/assets/hero/m/sunny/frame-05.jpg | Bin 0 -> 3327 bytes site/assets/hero/m/sunny/frame-07.jpg | Bin 0 -> 2942 bytes site/assets/hero/m/sunny/lamp-after.jpg | Bin 0 -> 3599 bytes site/assets/hero/m/sunny/post.jpg | Bin 0 -> 25902 bytes site/assets/hero/m/uploads/comment-pair.jpg | Bin 0 -> 4714 bytes .../hero/m/uploads/file-page-compare.jpg | Bin 0 -> 3053 bytes site/assets/hero/m/uploads/frame-01.jpg | Bin 0 -> 3658 bytes site/assets/hero/m/uploads/frame-02.jpg | Bin 0 -> 2948 bytes site/assets/hero/m/uploads/frame-03.jpg | Bin 0 -> 3005 bytes site/assets/hero/m/uploads/frame-06.jpg | Bin 0 -> 3121 bytes site/assets/hero/m/uploads/post.jpg | Bin 0 -> 24947 bytes site/assets/hero/poster-phone.jpg | Bin 0 -> 65696 bytes site/assets/hero/poster.jpg | Bin 0 -> 143797 bytes site/assets/hero/releases.mp4 | Bin 0 -> 325076 bytes site/assets/hero/room.glb | Bin 0 -> 353824 bytes site/assets/hero/sunny.mp4 | Bin 0 -> 295923 bytes site/assets/hero/three/LICENSE | 21 + .../hero/three/build/three.module.min.js | 6 + .../three/examples/jsm/loaders/GLTFLoader.js | 4663 +++++++++++++++++ .../examples/jsm/utils/BufferGeometryUtils.js | 1375 +++++ site/assets/hero/uploads.mp4 | Bin 0 -> 266282 bytes site/build.mjs | 11 +- site/hero.mjs | 105 + site/hero/greek.js | 29 + site/hero/room.blend | Bin 0 -> 144705 bytes site/hero/src/releases/digest-card.jpg | Bin 0 -> 40327 bytes site/hero/src/releases/frame-01.jpg | Bin 0 -> 14540 bytes site/hero/src/releases/frame-03.jpg | Bin 0 -> 14522 bytes site/hero/src/releases/frame-05.jpg | Bin 0 -> 11074 bytes site/hero/src/releases/frame-07.jpg | Bin 0 -> 10264 bytes site/hero/src/releases/post.jpg | Bin 0 -> 60715 bytes site/hero/src/releases/replay-tue.jpg | Bin 0 -> 25390 bytes site/hero/src/sunny/boardroom.jpg | Bin 0 -> 26357 bytes site/hero/src/sunny/frame-01.jpg | Bin 0 -> 17320 bytes site/hero/src/sunny/frame-02.jpg | Bin 0 -> 11932 bytes site/hero/src/sunny/frame-05.jpg | Bin 0 -> 14140 bytes site/hero/src/sunny/frame-07.jpg | Bin 0 -> 11205 bytes site/hero/src/sunny/lamp-after.jpg | Bin 0 -> 15972 bytes site/hero/src/sunny/post.jpg | Bin 0 -> 72863 bytes site/hero/src/uploads/comment-pair.jpg | Bin 0 -> 34693 bytes site/hero/src/uploads/file-page-compare.jpg | Bin 0 -> 18757 bytes site/hero/src/uploads/frame-01.jpg | Bin 0 -> 13093 bytes site/hero/src/uploads/frame-02.jpg | Bin 0 -> 11191 bytes site/hero/src/uploads/frame-03.jpg | Bin 0 -> 14128 bytes site/hero/src/uploads/frame-06.jpg | Bin 0 -> 13547 bytes site/hero/src/uploads/post.jpg | Bin 0 -> 67647 bytes site/src/index.html | 49 +- site/worker.mjs | 9 +- wrangler.jsonc | 4 +- 84 files changed, 6690 insertions(+), 11 deletions(-) create mode 100644 site/assets/hero/d/releases/digest-card.jpg create mode 100644 site/assets/hero/d/releases/frame-01.jpg create mode 100644 site/assets/hero/d/releases/frame-03.jpg create mode 100644 site/assets/hero/d/releases/frame-05.jpg create mode 100644 site/assets/hero/d/releases/frame-07.jpg create mode 100644 site/assets/hero/d/releases/post.jpg create mode 100644 site/assets/hero/d/releases/replay-tue.jpg create mode 100644 site/assets/hero/d/sunny/boardroom.jpg create mode 100644 site/assets/hero/d/sunny/frame-01.jpg create mode 100644 site/assets/hero/d/sunny/frame-02.jpg create mode 100644 site/assets/hero/d/sunny/frame-05.jpg create mode 100644 site/assets/hero/d/sunny/frame-07.jpg create mode 100644 site/assets/hero/d/sunny/lamp-after.jpg create mode 100644 site/assets/hero/d/sunny/post.jpg create mode 100644 site/assets/hero/d/uploads/comment-pair.jpg create mode 100644 site/assets/hero/d/uploads/file-page-compare.jpg create mode 100644 site/assets/hero/d/uploads/frame-01.jpg create mode 100644 site/assets/hero/d/uploads/frame-02.jpg create mode 100644 site/assets/hero/d/uploads/frame-03.jpg create mode 100644 site/assets/hero/d/uploads/frame-06.jpg create mode 100644 site/assets/hero/d/uploads/post.jpg create mode 100644 site/assets/hero/hero.js create mode 100644 site/assets/hero/layout.js create mode 100644 site/assets/hero/m/releases/digest-card.jpg create mode 100644 site/assets/hero/m/releases/frame-01.jpg create mode 100644 site/assets/hero/m/releases/frame-03.jpg create mode 100644 site/assets/hero/m/releases/frame-05.jpg create mode 100644 site/assets/hero/m/releases/frame-07.jpg create mode 100644 site/assets/hero/m/releases/post.jpg create mode 100644 site/assets/hero/m/releases/replay-tue.jpg create mode 100644 site/assets/hero/m/sunny/boardroom.jpg create mode 100644 site/assets/hero/m/sunny/frame-01.jpg create mode 100644 site/assets/hero/m/sunny/frame-02.jpg create mode 100644 site/assets/hero/m/sunny/frame-05.jpg create mode 100644 site/assets/hero/m/sunny/frame-07.jpg create mode 100644 site/assets/hero/m/sunny/lamp-after.jpg create mode 100644 site/assets/hero/m/sunny/post.jpg create mode 100644 site/assets/hero/m/uploads/comment-pair.jpg create mode 100644 site/assets/hero/m/uploads/file-page-compare.jpg create mode 100644 site/assets/hero/m/uploads/frame-01.jpg create mode 100644 site/assets/hero/m/uploads/frame-02.jpg create mode 100644 site/assets/hero/m/uploads/frame-03.jpg create mode 100644 site/assets/hero/m/uploads/frame-06.jpg create mode 100644 site/assets/hero/m/uploads/post.jpg create mode 100644 site/assets/hero/poster-phone.jpg create mode 100644 site/assets/hero/poster.jpg create mode 100644 site/assets/hero/releases.mp4 create mode 100644 site/assets/hero/room.glb create mode 100644 site/assets/hero/sunny.mp4 create mode 100644 site/assets/hero/three/LICENSE create mode 100644 site/assets/hero/three/build/three.module.min.js create mode 100644 site/assets/hero/three/examples/jsm/loaders/GLTFLoader.js create mode 100644 site/assets/hero/three/examples/jsm/utils/BufferGeometryUtils.js create mode 100644 site/assets/hero/uploads.mp4 create mode 100644 site/hero.mjs create mode 100644 site/hero/greek.js create mode 100644 site/hero/room.blend create mode 100644 site/hero/src/releases/digest-card.jpg create mode 100644 site/hero/src/releases/frame-01.jpg create mode 100644 site/hero/src/releases/frame-03.jpg create mode 100644 site/hero/src/releases/frame-05.jpg create mode 100644 site/hero/src/releases/frame-07.jpg create mode 100644 site/hero/src/releases/post.jpg create mode 100644 site/hero/src/releases/replay-tue.jpg create mode 100644 site/hero/src/sunny/boardroom.jpg create mode 100644 site/hero/src/sunny/frame-01.jpg create mode 100644 site/hero/src/sunny/frame-02.jpg create mode 100644 site/hero/src/sunny/frame-05.jpg create mode 100644 site/hero/src/sunny/frame-07.jpg create mode 100644 site/hero/src/sunny/lamp-after.jpg create mode 100644 site/hero/src/sunny/post.jpg create mode 100644 site/hero/src/uploads/comment-pair.jpg create mode 100644 site/hero/src/uploads/file-page-compare.jpg create mode 100644 site/hero/src/uploads/frame-01.jpg create mode 100644 site/hero/src/uploads/frame-02.jpg create mode 100644 site/hero/src/uploads/frame-03.jpg create mode 100644 site/hero/src/uploads/frame-06.jpg create mode 100644 site/hero/src/uploads/post.jpg diff --git a/dev/test/site.test.mjs b/dev/test/site.test.mjs index 11462af..604cd6c 100644 --- a/dev/test/site.test.mjs +++ b/dev/test/site.test.mjs @@ -6,6 +6,7 @@ import { tmpdir } from "node:os"; import { join } from "node:path"; import { build, SHARE, EXAMPLES, videoChapters, wrapPost, footer, exampleCard, siteFonts } from "../../site/build.mjs"; import { drawing, NAMES } from "../../site/iso.mjs"; +import { CLUSTERS, CUTS, drawnWidths } from "../../site/assets/hero/layout.js"; test("the site builds: markers filled, files copied, every command copyable", () => { const out = mkdtempSync(join(tmpdir(), "buildnotes-site-")); @@ -98,6 +99,28 @@ test("the site builds: markers filled, files copied, every command copyable", () } }); +test("the hero's table: its scene, model, videos, cut images, posters and three.js are all served", () => { + const out = mkdtempSync(join(tmpdir(), "buildnotes-site-")); + try { + const { html } = build({ out }); + const served = (p) => assert.ok(existsSync(join(out, p)), p); + // three.js is the site's own copy, named by an import map that hero.js's imports go through + const map = JSON.parse(html.match(/