aboutsummaryrefslogtreecommitdiff
path: root/working/retro-stereo-widgets/references/2026-07-18-hotfx-split-flap-reference.org
diff options
context:
space:
mode:
Diffstat (limited to 'working/retro-stereo-widgets/references/2026-07-18-hotfx-split-flap-reference.org')
-rw-r--r--working/retro-stereo-widgets/references/2026-07-18-hotfx-split-flap-reference.org65
1 files changed, 65 insertions, 0 deletions
diff --git a/working/retro-stereo-widgets/references/2026-07-18-hotfx-split-flap-reference.org b/working/retro-stereo-widgets/references/2026-07-18-hotfx-split-flap-reference.org
new file mode 100644
index 0000000..5fa7acd
--- /dev/null
+++ b/working/retro-stereo-widgets/references/2026-07-18-hotfx-split-flap-reference.org
@@ -0,0 +1,65 @@
+#+TITLE: HotFX split-flap web component — technique reference
+#+DATE: [2026-07-18 Sat]
+
+Reference for the split-flap display work (gallery card N20, and any flip/drum
+date-time module the waybar chronograph grows). Craig supplied both links.
+
+- Annotated walkthrough: https://fx.hot.page/split-flap/source
+- Source on GitHub: https://github.com/hot-page/fx/blob/main/hotfx-split-flap/hotfx-split-flap.js
+- Local study copy: [[file:2026-07-18-hotfx-split-flap-source.js]]
+
+LICENSE CAUTION: the fx repo declares NO license (checked via the GitHub API
+2026-07-18), so the code is all-rights-reserved by default. Study the
+technique, re-derive our own implementation in the GW namespace — do not copy
+code or CSS verbatim into the gallery or dotfiles.
+
+* The mechanics worth stealing (as ideas)
+
+** Four-layer character cell
+Each character is four absolutely-stacked half-panels: =.top= / =.bottom=
+(current char) and =.top-next= / =.bottom-next= (incoming char), the tops
+clipped to the upper half and bottoms to the lower half, with a divider line
+at 50%. =transform-style: preserve-3d= on the cell,
+=backface-visibility: hidden= on flaps so a flap's reverse never shows.
+
+** One flip = two synchronized quarter-animations
+Only two elements move per flip, via the Web Animations API with
+=Promise.all= on their =.finished=:
+- current =.top= rotates =rotateX(0deg)= → =rotateX(-180deg)= (falls forward)
+- =.bottom-next= rotates =rotateX(180deg)= → =rotateX(0deg)= (lands)
+Both =ease-in=, default 150ms per flap. After landing, the static halves get
+the new character's text and the cycle repeats. This is the minimal honest
+split-flap kinematic.
+
+** The charset IS the drum
+It never jumps to the target character: it steps =currentIndex + 1= (wrapping)
+through the declared alphabet until it arrives, one flip per step — the
+Solari constraint that a board can only advance one flap at a time. The
+alphabet is a declared attribute (default =' ABC…Z0-9!.,:?"'/$'=), so the
+character order is data, exactly our R58 LAYOUT-as-data pattern: rewrite the
+alphabet and the physical behavior follows.
+
+** Live-update semantics (relevant for a clock)
+A MutationObserver rebuilds the target grid on text change; an in-flight flip
+cascade aborts itself by identity-checking the target grid each step, and the
+new animation starts only after awaiting every running animation's finish.
+That's the answer to "the minute changed while the drum was still spinning" —
+abort-and-retarget, never queue.
+
+** Also noted
+IntersectionObserver defers the animation until the element is half in view;
+=::part(flap-N-M)= attributes expose every flap and divider for external
+styling. ~300 lines total for all of it.
+
+* How it maps to our targets
+
+- Gallery N20 (split-flap board): the four-layer cell + two-animation flip is
+ the web implementation; the step-through-charset rule and abort-on-retarget
+ are behaviors our probe checks can pin regardless of implementation.
+- Waybar chronograph drums (the redesign mock's date/time): our drums are
+ odometer rollers, not flaps — different mechanism — but the charset-as-drum
+ ordering and abort-and-retarget rules carry over unchanged.
+- Emacs svg.el port: no Web Animations API; the flip becomes frame-stepped
+ whole-image regeneration per the render contract, with the same
+ one-step-at-a-time rule. Reduced-motion gate applies (widget-owned
+ animation per the gallery tick contract).