themes.ts

examples/fxedit/themes.ts · raw · open the example · all examples · site home

Exports: ThemeNameMotionPresetThemeTHEMESthemeByName

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// The three looks of the editor: the same behavior with a different skin
// (fxedit.css under body[data-theme]) and different motion and effects.
export type ThemeName = "neon" | "toybox" | "glass";

export interface MotionPreset {
  // Spring constant (1/s^2) and damping ratio (1 = no overshoot)
  stiffness: number;
  damping: number;
  // Degrees of tilt per px/s of horizontal speed while a node moves
  tilt: number;
  // Squash on drop (scale velocity kick)
  squash: number;
  // Delay per world px of x when nodes fly to a new layout (ms)
  stagger: number;
}

export interface Theme {
  name: ThemeName;
  label: string;
  motion: MotionPreset;
  // Rope wires sag and swing (Verlet); bezier wires are drawn exactly
  wire: "bezier" | "rope";
  burst: "sparks" | "confetti" | "ripple";
  // Render full-bleed behind a translucent editor instead of side by side
  overlay: boolean;
  colors: string[];
}

export const THEMES: Record<ThemeName, Theme> = {
  neon: {
    name: "neon",
    label: "Neon Circuit",
    motion: { stiffness: 340, damping: 0.7, tilt: 0.012, squash: 3, stagger: 0.25 },
    wire: "bezier",
    burst: "sparks",
    overlay: false,
    colors: ["#39f3ff", "#ff3df2", "#b8ff3d", "#ffe53d"],
  },
  toybox: {
    name: "toybox",
    label: "Toybox",
    motion: { stiffness: 230, damping: 0.45, tilt: 0.025, squash: 6, stagger: 0.6 },
    wire: "rope",
    burst: "confetti",
    overlay: false,
    colors: ["#ff6b6b", "#ffd93d", "#6bcB77", "#4d96ff", "#c77dff"],
  },
  glass: {
    name: "glass",
    label: "Lab Glass",
    motion: { stiffness: 150, damping: 1, tilt: 0, squash: 0.8, stagger: 0.15 },
    wire: "bezier",
    burst: "ripple",
    overlay: true,
    colors: ["#9fd8ff", "#d3b8ff", "#b8ffe4"],
  },
};

export function themeByName(name: string | null | undefined): Theme | undefined {
  return name && name in THEMES ? THEMES[name as ThemeName] : undefined;
}