pr_01m47d15m3e54sn21z27rpy5n9/apps/web/app/lib/art.ts

49 lines1,708 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1/**
2 * The geometry and timing behind g1t's artwork (components/art.tsx). Pure,
3 * so it is tested on its own.
4 */
5
6/** Isometric projection: x runs down-right, y down-left, z up. */
7const COS = Math.cos(Math.PI / 6);
8const SIN = 0.5;
9
10export type Point = [number, number];
11
12/** A point on the floor (or at height `z`), as it is drawn on the page. */
13export function iso(x: number, y: number, z = 0): Point {
14 return [(x - y) * COS, (x + y) * SIN - z];
15}
16
17/** Points for a `<polygon>` or `<polyline>`, to one decimal place. */
18export function pts(points: Point[]): string {
19 return points.map(([x, y]) => `${x.toFixed(1)},${y.toFixed(1)}`).join(" ");
20}
21
22/** A path's `d` through floor points at height `z`. */
23export function isoPath(points: Point[], z = 0): string {
24 return points
25 .map(([x, y], index) => {
26 const [px, py] = iso(x, y, z);
27 return `${index === 0 ? "M" : "L"}${px.toFixed(1)} ${py.toFixed(1)}`;
28 })
29 .join(" ");
30}
31
32/**
33 * When each of `count` things starts within one loop of `period` seconds,
34 * spread evenly from `from` and never past the loop, as CSS delays.
35 */
36export function stagger(count: number, period: number, from = 0): string[] {
37 if (count <= 0) return [];
38 const step = (period - from) / count;
39 return Array.from({ length: count }, (_, index) => `${round(from + index * step)}s`);
40}
41
42/** The CSS custom properties an animated piece reads: its loop and its start. */
43export function timing(dur: number, delay: number | string = 0): Record<string, string> {
44 return { "--dur": `${round(dur)}s`, "--delay": typeof delay === "number" ? `${round(delay)}s` : delay };
45}
46
47function round(value: number): number {
48 return Math.round(value * 100) / 100;
49}