repos
/ orchard main

orchard

mirror

Every site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.

blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics

1.3 KB · 39 lines · JavaScript Raw History
 1// Two pages animate words in and out through the enter / enter-active /
 2// enter-done / exit / exit-active class sequence, and their CSS is written
 3// against exactly those state names.
 4//
 5// The forced reflow matters. Adding the "from" class and the "active" class in
 6// the same frame means the browser only ever computes the end state, and no
 7// transition runs at all.
 8
 9const nextFrame = (fn) => requestAnimationFrame(() => requestAnimationFrame(fn));
10
11/** Play the enter sequence on an element. Classes: {from, active, done}. */
12export const enter = (el, classes, duration) => {
13  el.classList.add(classes.from);
14  void el.offsetWidth;
15
16  nextFrame(() => {
17    el.classList.add(classes.active);
18    window.setTimeout(() => {
19      el.classList.remove(classes.from, classes.active);
20      if (classes.done) el.classList.add(classes.done);
21    }, duration);
22  });
23};
24
25/** Play the exit sequence, then run onDone (usually removing the element). */
26export const exit = (el, classes, duration, onDone) => {
27  if (classes.clear) el.classList.remove(...classes.clear);
28  el.classList.add(classes.from);
29  void el.offsetWidth;
30
31  nextFrame(() => {
32    el.classList.add(classes.active);
33    window.setTimeout(() => {
34      el.classList.remove(classes.from, classes.active);
35      if (onDone) onDone(el);
36    }, duration);
37  });
38};