返回 CodeWhale
whale-pose.tsx
根目录 / web / components / whale-pose.tsx
1 /**
2 * The v2 whale character's still poses (public/whale/*.svg, exported from
3 * the whale-character-v2 kit by scripts/export-whale-poses.py). The web
4 * shows the reduced-motion pose of each action; it never animates by
5 * swapping posters.
6 *
7 * A pose carries meaning, so pick the one that matches what the page is
8 * about: `search` for "not found", `hmm` for an error, `busy` while loading,
9 * `done` for a finished action, `needs` when the reader must act, and `pod`
10 * only where parallel agents are the subject. Decorative by default (the
11 * surrounding words say the same thing); pass `label` when the pose alone
12 * carries information.
13 */
14 export const WHALE_POSES = [
15 "rest",
16 "listen",
17 "think",
18 "busy",
19 "read",
20 "search",
21 "write",
22 "run",
23 "browse",
24 "talk",
25 "pod",
26 "needs",
27 "done",
28 "hmm",
29 "sleep",
30 "computer",
31 "connect",
32 ] as const;
33
34 export type WhalePoseName = (typeof WHALE_POSES)[number];
35
36 export function WhalePose({
37 pose,
38 label,
39 className = "",
40 priority = false,
41 }: {
42 pose: WhalePoseName;
43 label?: string;
44 className?: string;
45 priority?: boolean;
46 }) {
47 return (
48 // Static, cacheable SVG; next/image adds nothing for a vector file.
49 // eslint-disable-next-line @next/next/no-img-element
50 <img
51 src={`/whale/${pose}.svg`}
52 alt={label ?? ""}
53 aria-hidden={label ? undefined : true}
54 width={124}
55 height={124}
56 className={`whale-pose ${className}`.trim()}
57 data-pose={pose}
58 decoding="async"
59 loading={priority ? "eager" : "lazy"}
60 fetchPriority={priority ? "high" : undefined}
61 draggable={false}
62 />
63 );
64 }
65
65 lines Plain Text