@sarmal/core 0.37.1 → 0.37.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.js.map +1 -1
- package/dist/curves/artemis2.d.cts +1 -1
- package/dist/curves/artemis2.d.ts +1 -1
- package/dist/curves/astroid.d.cts +1 -1
- package/dist/curves/astroid.d.ts +1 -1
- package/dist/curves/deltoid.d.cts +1 -1
- package/dist/curves/deltoid.d.ts +1 -1
- package/dist/curves/epicycloid3.d.cts +1 -1
- package/dist/curves/epicycloid3.d.ts +1 -1
- package/dist/curves/epitrochoid7.d.cts +1 -1
- package/dist/curves/epitrochoid7.d.ts +1 -1
- package/dist/curves/index.d.cts +1 -1
- package/dist/curves/index.d.ts +1 -1
- package/dist/curves/lame.d.cts +1 -1
- package/dist/curves/lame.d.ts +1 -1
- package/dist/curves/lissajous32.d.cts +1 -1
- package/dist/curves/lissajous32.d.ts +1 -1
- package/dist/curves/lissajous43.d.cts +1 -1
- package/dist/curves/lissajous43.d.ts +1 -1
- package/dist/curves/rose3.d.cts +1 -1
- package/dist/curves/rose3.d.ts +1 -1
- package/dist/curves/rose5.d.cts +1 -1
- package/dist/curves/rose5.d.ts +1 -1
- package/dist/curves/rose52.d.cts +1 -1
- package/dist/curves/rose52.d.ts +1 -1
- package/dist/curves/star.d.cts +1 -1
- package/dist/curves/star.d.ts +1 -1
- package/dist/curves/star4.d.cts +1 -1
- package/dist/curves/star4.d.ts +1 -1
- package/dist/curves/star7.d.cts +1 -1
- package/dist/curves/star7.d.ts +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -53
- package/dist/index.d.ts +12 -53
- package/dist/index.js.map +1 -1
- package/dist/{renderer-shared-Bcc_1IaT.d.cts → renderer-shared-9Xf6sIlx.d.cts} +1 -1
- package/dist/{renderer-shared-DWPVHjKZ.d.ts → renderer-shared-DElz98PT.d.ts} +1 -1
- package/dist/terminal.d.cts +2 -2
- package/dist/terminal.d.ts +2 -2
- package/dist/{types-B1XeFpuq.d.cts → types-D_ERoVvi.d.cts} +121 -1
- package/dist/{types-B1XeFpuq.d.ts → types-D_ERoVvi.d.ts} +121 -1
- package/package.json +5 -5
- package/skills/core/SKILL.md +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/engine.ts","../src/renderer-shared.ts","../src/renderer.ts","../src/renderer-svg.ts","../src/renderer-dot-matrix.ts","../src/catmull-rom.ts","../src/curves/artemis2.ts","../src/curves/astroid.ts","../src/curves/deltoid.ts","../src/curves/epicycloid3.ts","../src/curves/epitrochoid7.ts","../src/curves/lissajous32.ts","../src/curves/lissajous43.ts","../src/curves/lame.ts","../src/curves/rose3.ts","../src/curves/rose5.ts","../src/curves/rose52.ts","../src/curves/star.ts","../src/curves/star4.ts","../src/curves/star7.ts","../src/curves/index.ts","../src/index.ts"],"names":["points","dx","dy","len","options","EMPTY_PARAMS","skeleton","TWO_PI"],"mappings":"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","file":"index.js","sourcesContent":["import type { CurveDef, Engine, JumpOptions, MorphStrategy, Point, SeekOptions } from \"./types\";\n\nconst TWO_PI = Math.PI * 2;\nconst POINTS_PER_PERIOD_UNIT = 50;\n\ntype SpeedTransition = {\n from: number;\n to: number;\n elapsed: number;\n duration: number;\n resolve: () => void;\n reject: (err: Error) => void;\n};\n\n/** Linearly interpolate from start to end by factor t (0→1) */\nfunction lerp(start: number, end: number, t: number): number {\n return start + (end - start) * t;\n}\n\n/** Reused across all curve fn calls but params is never populated, allocation is wasteful */\nconst EMPTY_PARAMS: Record<string, number> = {};\n\n/**\n * A fixed-size list of points with first in, last out method\n * The oldest entry is automatically discarded when the list is at capacity\n *\n * Note: `result.length` is *never* changed,\n * so callers use the separate `count` getter to know valid size\n */\nclass CircularBuffer {\n private data: Array<Point>;\n private result: Array<Point>;\n private capacity: number;\n private head: number = 0;\n private count: number = 0;\n\n constructor(capacity: number) {\n this.capacity = capacity;\n this.data = Array.from({ length: capacity }, () => ({ x: 0, y: 0 }));\n this.result = Array.from({ length: capacity }, () => ({ x: 0, y: 0 }));\n }\n\n /** Mutates in-place */\n push(x: number, y: number): void {\n const slot = this.data[this.head]!;\n\n slot.x = x;\n slot.y = y;\n this.head = (this.head + 1) % this.capacity;\n\n if (this.count < this.capacity) {\n this.count++;\n }\n }\n\n /**\n * Copies ordered points into the pre-allocated result buffer and returns it\n * Note: The *same* array reference is returned every call,\n * so `result.length` is also always `capacity`\n */\n toArray(): Array<Point> {\n const start = this.count < this.capacity ? 0 : this.head;\n\n for (let i = 0; i < this.count; i++) {\n const src = this.data[(start + i) % this.capacity]!;\n const dst = this.result[i]!;\n dst.x = src.x;\n dst.y = src.y;\n }\n\n return this.result;\n }\n\n clear(): void {\n this.head = 0;\n this.count = 0;\n }\n\n get length() {\n return this.count;\n }\n}\n\n/**\n * Creates the core simulation engine for a sarmal\n *\n * it runs a clock (`phase`), asks the curve for the current Point position at that time,\n * and remembers the last N positions so the renderer can draw the trail\n *\n * The engine is only responsible for math coordinates,\n * so it is not responsible for drawing or colors\n *\n * @param curveDef A curve definition\n * @param trailLength default: `120`\n */\n/** Normalised resolution of a CurveDef, with required fields filled in */\ntype ResolvedCurve = {\n name: string;\n fn: CurveDef[\"fn\"];\n period: number;\n speed: number;\n skeleton?: CurveDef[\"skeleton\"];\n skeletonFn?: CurveDef[\"skeletonFn\"];\n};\n\nfunction resolveCurve(curveDef: CurveDef): ResolvedCurve {\n const period = curveDef.period ?? TWO_PI;\n\n if (!Number.isFinite(period) || period <= 0) {\n throw new RangeError(`[sarmal] period must be a positive finite number, got ${period}`);\n }\n\n const speed = curveDef.speed ?? 1;\n\n if (!Number.isFinite(speed)) {\n throw new RangeError(`[sarmal] speed must be a finite number, got ${speed}`);\n }\n\n return {\n name: curveDef.name,\n fn: curveDef.fn,\n period,\n speed,\n skeleton: curveDef.skeleton,\n skeletonFn: curveDef.skeletonFn,\n };\n}\n\nexport function createEngine(curveDef: CurveDef, trailLength: number = 120): Engine {\n if (!Number.isFinite(trailLength) || trailLength <= 0) {\n throw new RangeError(\n `[sarmal] trailLength must be a positive finite number, got ${trailLength}`,\n );\n }\n\n let curve = resolveCurve(curveDef);\n const trail = new CircularBuffer(trailLength);\n let phase = 0;\n let actualTime = 0;\n let userSpeedOverride: number | null = null;\n\n // Morph state which is `null` when not morphing\n let morphCurveB: ResolvedCurve | null = null;\n let _morphAlpha: number | null = null;\n let _morphStrategy: MorphStrategy = \"normalized\";\n\n // Speed transition state which is `null` when not transitioning\n let _speedTransition: SpeedTransition | null = null;\n\n /** Samples a resolved curve's skeleton at position `samplePhase` */\n function sampleSkeleton(c: ResolvedCurve, samplePhase: number): Point {\n if (c.skeletonFn) {\n return c.skeletonFn(samplePhase);\n }\n\n if (c.skeleton === \"live\") {\n return c.fn(samplePhase, actualTime, EMPTY_PARAMS);\n }\n\n return c.fn(samplePhase, 0, EMPTY_PARAMS);\n }\n\n return {\n tick(deltaTime: number): Array<Point> {\n if (_speedTransition !== null) {\n // tick() receives dt in seconds, but SpeedTransition.duration is in milliseconds.\n // Convert dt to ms so the elapsed/duration ratio is dimensionless.\n _speedTransition.elapsed += deltaTime * 1000;\n const alpha = Math.min(_speedTransition.elapsed / _speedTransition.duration, 1);\n userSpeedOverride = lerp(_speedTransition.from, _speedTransition.to, alpha);\n if (alpha >= 1) {\n userSpeedOverride = _speedTransition.to;\n _speedTransition.resolve();\n _speedTransition = null;\n }\n }\n\n let effectiveSpeed = userSpeedOverride ?? curve.speed;\n if (morphCurveB !== null && _morphAlpha !== null) {\n effectiveSpeed = lerp(effectiveSpeed, morphCurveB.speed, _morphAlpha);\n }\n phase = (phase + effectiveSpeed * deltaTime) % curve.period;\n actualTime += deltaTime;\n\n if (morphCurveB !== null && _morphAlpha !== null) {\n const a = curve.fn(phase, actualTime, EMPTY_PARAMS);\n const phaseB =\n _morphStrategy === \"normalized\" ? (phase / curve.period) * morphCurveB.period : phase;\n const b = morphCurveB.fn(phaseB, actualTime, EMPTY_PARAMS);\n trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);\n } else {\n const point = curve.fn(phase, actualTime, EMPTY_PARAMS);\n trail.push(point.x, point.y);\n }\n\n return trail.toArray();\n },\n\n get trailCount() {\n return trail.length;\n },\n\n get trailLength() {\n return trailLength;\n },\n\n get isLiveSkeleton() {\n return curve.skeleton === \"live\";\n },\n\n get morphAlpha() {\n return _morphAlpha;\n },\n\n reset() {\n phase = 0;\n actualTime = 0;\n trail.clear();\n },\n\n jump(newPhase: number, { clearTrail = false }: JumpOptions = {}) {\n phase = ((newPhase % curve.period) + curve.period) % curve.period;\n\n if (clearTrail) {\n trail.clear();\n }\n },\n\n seek(\n targetPhase: number,\n { wrap = false, step = curve.period / trailLength }: SeekOptions = {},\n ) {\n const advance = curve.speed * step;\n const target = ((targetPhase % curve.period) + curve.period) % curve.period;\n const targetTime = target / curve.speed;\n\n phase = target;\n actualTime = targetTime;\n trail.clear();\n\n const pointsFromStart = Math.floor(target / advance) + 1;\n const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);\n\n for (let i = count - 1; i >= 0; i--) {\n const samplePhase = target - i * advance;\n const wrappedPhase = ((samplePhase % curve.period) + curve.period) % curve.period;\n const elapsed = targetTime - i * step;\n const point = curve.fn(wrappedPhase, elapsed, EMPTY_PARAMS);\n\n trail.push(point.x, point.y);\n }\n },\n\n startMorph(target: CurveDef, strategy: MorphStrategy = \"normalized\") {\n const resolvedTarget = resolveCurve(target);\n\n if (morphCurveB !== null && _morphAlpha !== null) {\n const frozenAlpha = _morphAlpha;\n const frozenA = curve;\n const frozenB = morphCurveB;\n const frozenStrategy = _morphStrategy;\n\n curve = {\n ...frozenB,\n fn: (samplePhase: number, elapsed: number, params: Record<string, number>) => {\n const a = frozenA.fn(samplePhase, elapsed, params);\n const phaseB =\n frozenStrategy === \"normalized\"\n ? (samplePhase / frozenA.period) * frozenB.period\n : samplePhase;\n const b = frozenB.fn(phaseB, elapsed, params);\n\n return {\n x: a.x + (b.x - a.x) * frozenAlpha,\n y: a.y + (b.y - a.y) * frozenAlpha,\n };\n },\n };\n }\n\n _morphStrategy = strategy;\n morphCurveB = resolvedTarget;\n _morphAlpha = 0;\n },\n\n setMorphAlpha(alpha: number) {\n _morphAlpha = alpha;\n },\n\n completeMorph() {\n if (morphCurveB !== null) {\n // Normalized strategy drives `curveB` at `phaseB` = `(phase / periodA) * periodB`\n // Remap `phase` so the trail continues from the same position on `curveB`,\n // not from a raw `phase` value that belongs to `curveA`'s smaller range.\n if (_morphStrategy === \"normalized\" && curve.period !== morphCurveB.period) {\n phase = (phase / curve.period) * morphCurveB.period;\n }\n curve = morphCurveB;\n }\n morphCurveB = null;\n _morphAlpha = null;\n },\n\n getSarmalSkeleton(): Array<Point> {\n const steps = Math.ceil(curve.period * POINTS_PER_PERIOD_UNIT);\n // oxlint-disable-next-line unicorn/no-new-array -- array is pre-allocated, filled immediately below\n const points: Array<Point> = new Array(steps);\n\n if (morphCurveB !== null && _morphAlpha !== null) {\n for (let i = 0; i < steps; i++) {\n const samplePhase = (i / (steps - 1)) * curve.period;\n const a = sampleSkeleton(curve, samplePhase);\n const phaseB =\n _morphStrategy === \"normalized\"\n ? (samplePhase / curve.period) * morphCurveB.period\n : samplePhase;\n const b = sampleSkeleton(morphCurveB, phaseB);\n\n points[i] = {\n x: a.x + (b.x - a.x) * _morphAlpha,\n y: a.y + (b.y - a.y) * _morphAlpha,\n };\n }\n return points;\n }\n\n for (let i = 0; i < steps; i++) {\n const samplePhase = (i / (steps - 1)) * curve.period;\n points[i] = sampleSkeleton(curve, samplePhase);\n }\n\n return points;\n },\n\n setSpeed(speed: number): void {\n if (!Number.isFinite(speed)) {\n throw new Error(\"speed must be a finite number\");\n }\n if (_speedTransition !== null) {\n _speedTransition.reject(new Error(\"Speed transition cancelled\"));\n _speedTransition = null;\n }\n userSpeedOverride = speed;\n },\n\n getSpeed(): number {\n return userSpeedOverride ?? curve.speed;\n },\n\n resetSpeed(): void {\n userSpeedOverride = null;\n },\n\n setSpeedOver(speed: number, duration: number): Promise<void> {\n if (!Number.isFinite(speed)) {\n throw new Error(\"speed must be a finite number\");\n }\n if (!Number.isFinite(duration) || duration <= 0) {\n throw new Error(\"duration must be a finite number greater than 0\");\n }\n\n if (_speedTransition !== null) {\n _speedTransition.reject(new Error(\"Speed transition cancelled\"));\n _speedTransition = null;\n }\n\n const from = userSpeedOverride ?? curve.speed;\n\n return new Promise<void>((resolve, reject) => {\n _speedTransition = { from, to: speed, elapsed: 0, duration, resolve, reject };\n });\n },\n\n cancelSpeedTransition(): void {\n if (_speedTransition !== null) {\n _speedTransition.reject(new Error(\"Speed transition cancelled\"));\n _speedTransition = null;\n }\n },\n };\n}\n","import type {\n BaseRuntimeRenderOptions,\n Engine,\n Point,\n RuntimeRenderOptions,\n TrailColor,\n TrailStyle,\n} from \"./types\";\n\nexport const DEFAULT_MORPH_DURATION_MS = 300;\nexport const DEFAULT_SKELETON_OPACITY = 0.15;\n/** Fraction of the bounding-box dimension added as proportional padding on each side when fitting the curve. */\nexport const FIT_PADDING = 0.1;\nexport const FIT_PADDING_MIN = 4;\n/** Higher values = sharper fade near the tail, more of the trail appears faint */\nexport const TRAIL_FADE_CURVE = 1.5;\nexport const TRAIL_MAX_OPACITY = 0.88;\n/** Pixel-space stroke/line width at the tail which the SVG renderer overrides with viewBox unit values */\nexport const TRAIL_MIN_WIDTH = 0.5;\n/** Pixel-space stroke/line width at the head which the SVG renderer overrides with viewBox unit values */\nexport const TRAIL_MAX_WIDTH = 2.5;\n\nexport interface TrailPoint {\n x: number;\n y: number;\n}\n\n/**\n * Computes the unit tangent vector at a point on the trail.\n * - Interior points: central difference (previous -> next)\n * - Endpoints: forward/backward difference\n */\nexport function computeTangent(trail: TrailPoint[], i: number): TrailPoint {\n const count = trail.length;\n if (count < 2) {\n return { x: 1, y: 0 };\n }\n\n if (i === 0) {\n const dx = trail[1]!.x - trail[0]!.x;\n const dy = trail[1]!.y - trail[0]!.y;\n const len = Math.sqrt(dx * dx + dy * dy) || 1;\n return { x: dx / len, y: dy / len };\n }\n\n if (i === count - 1) {\n const dx = trail[count - 1]!.x - trail[count - 2]!.x;\n const dy = trail[count - 1]!.y - trail[count - 2]!.y;\n const len = Math.sqrt(dx * dx + dy * dy) || 1;\n return { x: dx / len, y: dy / len };\n }\n\n const dx = trail[i + 1]!.x - trail[i - 1]!.x;\n const dy = trail[i + 1]!.y - trail[i - 1]!.y;\n const len = Math.sqrt(dx * dx + dy * dy) || 1;\n return { x: dx / len, y: dy / len };\n}\n\n/**\n * Computes the unit normal vector at a point on the trail.\n * The normal is perpendicular to the tangent, rotated 90° counter-clockwise\n */\nexport function computeNormal(trail: TrailPoint[], i: number): TrailPoint {\n const tangent = computeTangent(trail, i);\n return { x: -tangent.y, y: tangent.x };\n}\n\n/** The four pixel-space corners and per-segment style values for one ribbon quad */\nexport interface TrailQuad {\n /** Left corner at the tail end of this segment */\n l0x: number;\n l0y: number;\n /** Right corner at the tail end of this segment */\n r0x: number;\n r0y: number;\n /** Left corner at the head end of this segment */\n l1x: number;\n l1y: number;\n /** Right corner at the head end of this segment */\n r1x: number;\n r1y: number;\n /** Fill opacity for this segment (0–1) */\n opacity: number;\n /** Position along the trail (0 = tail, 1 = head) */\n progress: number;\n}\n\n/**\n * Computes the quad corners and style for one ribbon segment in the renderer's coordinate space (pixel-space for canvas, viewBox-space for SVG)\n *\n * @param trail Full trail array\n * @param i Segment index (draws from point i to point i+1)\n * @param trailCount Number of active trail points\n * @param toX Convert a trail point to its pixel X coordinate\n * @param toY Convert a trail point to its pixel Y coordinate\n *\n * @see https://mattdesl.svbtle.com/drawing-lines-is-hard\n * DesLauriers: \"Triangulated Lines\" - expand points outward by half\n * the thickness on either side using normals to create thick lines.\n */\nexport function computeTrailQuad(\n trail: TrailPoint[],\n i: number,\n trailCount: number,\n toX: (p: TrailPoint) => number,\n toY: (p: TrailPoint) => number,\n minWidth = TRAIL_MIN_WIDTH,\n maxWidth = TRAIL_MAX_WIDTH,\n): TrailQuad {\n const progress = i / (trailCount - 1);\n const nextProgress = (i + 1) / (trailCount - 1);\n const opacity = Math.pow(progress, TRAIL_FADE_CURVE) * TRAIL_MAX_OPACITY;\n const w0 = (minWidth + progress * (maxWidth - minWidth)) / 2;\n const w1 = (minWidth + nextProgress * (maxWidth - minWidth)) / 2;\n\n const curr = trail[i]!;\n const next = trail[i + 1]!;\n const n0 = computeNormal(trail, i);\n const n1 = computeNormal(trail, i + 1);\n\n const cx = toX(curr);\n const cy = toY(curr);\n const nx = toX(next);\n const ny = toY(next);\n\n return {\n l0x: cx + n0.x * w0,\n l0y: cy + n0.y * w0,\n r0x: cx - n0.x * w0,\n r0y: cy - n0.y * w0,\n l1x: nx + n1.x * w1,\n l1y: ny + n1.y * w1,\n r1x: nx - n1.x * w1,\n r1y: ny - n1.y * w1,\n opacity,\n progress,\n };\n}\n\nexport interface BoundaryResult {\n scale: number;\n offsetX: number;\n offsetY: number;\n}\n\n/**\n * Computes how to map engine coordinates into a viewport of the given logical size.\n * ! Returns `null` if `pts` is empty\n * ! Throws if all points are identical\n *\n * Padding per side is `max(FIT_PADDING * dim, minPaddingPx)`, so the stricter constraint wins.\n * `minPaddingPx` defaults to `FIT_PADDING_MIN` (4px) for pixel-space callers.\n * Pass `0` when the logical space is itself a normalized viewBox (e.g. SVG export).\n */\nexport function computeBoundaries(\n pts: Point[],\n logicalWidth: number,\n logicalHeight: number,\n minPaddingPx = FIT_PADDING_MIN,\n): BoundaryResult | null {\n if (pts.length === 0) {\n return null;\n }\n\n const first = pts[0]!;\n let minX = first.x,\n maxX = first.x,\n minY = first.y,\n maxY = first.y;\n\n for (const p of pts) {\n if (p.x < minX) {\n minX = p.x;\n }\n if (p.x > maxX) {\n maxX = p.x;\n }\n if (p.y < minY) {\n minY = p.y;\n }\n if (p.y > maxY) {\n maxY = p.y;\n }\n }\n\n const w = maxX - minX;\n const h = maxY - minY;\n\n if (w === 0 && h === 0) {\n throw new Error(\n \"[sarmal] Degenerate curve: all skeleton points are identical. \" +\n \"Check that your curve fn returns distinct points for different values of t.\",\n );\n }\n\n const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));\n const scaleYProportional = logicalHeight / (h * (1 + FIT_PADDING * 2));\n\n const scaleXMinPadding = (logicalWidth - minPaddingPx * 2) / w;\n const scaleYMinPadding = (logicalHeight - minPaddingPx * 2) / h;\n\n const scale = Math.min(\n scaleXProportional,\n scaleYProportional,\n scaleXMinPadding,\n scaleYMinPadding,\n );\n\n return {\n scale,\n offsetX: (logicalWidth - w * scale) / 2 - minX * scale,\n offsetY: (logicalHeight - h * scale) / 2 - minY * scale,\n };\n}\n\n/**\n * Returns the engine methods that are pure pass-throughs on both renderers\n * The engine does not use `this`, so direct assignment is safe\n */\nexport function enginePassthroughs(engine: Engine) {\n return {\n jump: engine.jump,\n seek: engine.seek,\n setSpeed: engine.setSpeed,\n getSpeed: engine.getSpeed,\n resetSpeed: engine.resetSpeed,\n setSpeedOver: engine.setSpeedOver,\n getSarmalSkeleton: engine.getSarmalSkeleton,\n };\n}\n\n/**\n * Can be passed directly to `trailColor`,\n * or can be mixed/sliced before passing as a prop.\n */\nexport const palettes = {\n bard: [\"#a855f7\", \"#3b82f6\", \"#14b8a6\", \"#ec4899\"],\n carnival: [\"#ff6b6b\", \"#4ecdc4\", \"#ffe66d\"],\n ocean: [\"#1e3a8a\", \"#06b6d4\", \"#22d3ee\", \"#e0f2fe\"],\n sunset: [\"#f97316\", \"#dc2626\", \"#9333ea\", \"#f472b6\"],\n ice: [\"#1e3a8a\", \"#67e8f9\"],\n rocketpop: [\"#08b8cd\", \"#ffffff\", \"#ff001f\"],\n neon: [\"#00e5ff\", \"#7c3aed\", \"#e040fb\"],\n vaporwave: [\"#ff71ce\", \"#01cdfe\", \"#b967ff\"],\n pastel: [\"#c4b5fd\", \"#fbcfe8\", \"#bae6fd\"],\n sakura: [\"#fff1f2\", \"#fda4af\", \"#fb7185\"],\n} as const satisfies Record<string, Array<string>>;\nexport type SarmalPalette = keyof typeof palettes; // TODO: reconsider naming convention. Should this represent the value type instead of the key union?\n\n/** RGB color components */\nexport interface Rgb {\n r: number;\n g: number;\n b: number;\n}\n\n/** Converts a hex color string to RGB components */\nexport function hexToRgb(hex: string): Rgb {\n const n = parseInt(hex.slice(1), 16);\n return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };\n}\n\nconst HEX_3_RE = /^#([0-9a-fA-F]{3})$/;\nconst HEX_6_RE = /^#([0-9a-fA-F]{6})$/;\nconst HEX_8_RE = /^#([0-9a-fA-F]{8})$/;\nconst RGB_RE =\n /^rgba?\\(\\s*(-?\\d{1,3})\\s*,\\s*(-?\\d{1,3})\\s*,\\s*(-?\\d{1,3})(?:\\s*,\\s*[\\d.]+)?\\s*\\)$/i;\n\n/**\n * Parses a color string in any supported format into Rgb components.\n * Returns `null` for unrecognized or malformed input.\n *\n * Supported formats:\n * - 3-digit hex: #rgb\n * - 6-digit hex: #rrggbb\n * - 8-digit hex: #rrggbbaa (alpha is silently stripped)\n * - rgb(r, g, b) channels clamped to 0–255\n * - rgba(r, g, b, a) alpha is silently stripped\n */\nexport function parseColorToRgb(s: string): Rgb | null {\n const trimmed = s.trim();\n\n const m3 = HEX_3_RE.exec(trimmed);\n if (m3) {\n const [r, g, b] = m3[1]!;\n return hexToRgb(`#${r}${r}${g}${g}${b}${b}`);\n }\n\n const m6 = HEX_6_RE.exec(trimmed);\n if (m6) {\n return hexToRgb(trimmed);\n }\n\n const m8 = HEX_8_RE.exec(trimmed);\n if (m8) {\n return hexToRgb(`#${trimmed.slice(1, 7)}`);\n }\n\n const mRgb = RGB_RE.exec(trimmed);\n if (mRgb) {\n return {\n r: Math.max(0, Math.min(255, parseInt(mRgb[1]!, 10))),\n g: Math.max(0, Math.min(255, parseInt(mRgb[2]!, 10))),\n b: Math.max(0, Math.min(255, parseInt(mRgb[3]!, 10))),\n };\n }\n\n return null;\n}\n\nconst OKLCH_RE = /^oklch\\(\\s*([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)(?:\\s*\\/\\s*[\\d.]+)?\\s*\\)$/i;\n\n/**\n * Parses an oklch() color string directly to Oklab.\n * Returns `null` for unrecognized or malformed input.\n *\n * Accepted syntax (subset of CSS Color 4):\n * - oklch(L C H) bare floats, L clamped to 0–1, C clamped to 0–0.4, H in degrees\n * - oklch(L C H / alpha) alpha silently stripped\n *\n * ! Not supported: percentages, `none` keyword, negative hues\n */\nexport function parseOklchToOklab(s: string): Oklab | null {\n const m = OKLCH_RE.exec(s.trim());\n if (!m) {\n return null;\n }\n\n const L = parseFloat(m[1]!);\n const C = parseFloat(m[2]!);\n const H = parseFloat(m[3]!);\n\n if (Number.isNaN(L) || Number.isNaN(C) || Number.isNaN(H)) {\n return null;\n }\n\n const clampedL = Math.max(0, Math.min(1, L));\n const clampedC = Math.max(0, Math.min(0.4, C));\n const H_rad = H * (Math.PI / 180);\n\n return {\n L: clampedL,\n a: clampedC * Math.cos(H_rad),\n b: clampedC * Math.sin(H_rad),\n };\n}\n\n/**\n * Unified color-to-Oklab entry point.\n * Tries oklch() first (direct to Oklab), then falls back through the sRGB path.\n */\nexport function parseColorToOklab(s: string): Oklab | null {\n const oklab = parseOklchToOklab(s);\n if (oklab !== null) {\n return oklab;\n }\n\n const rgb = parseColorToRgb(s);\n if (rgb === null) {\n return null;\n }\n\n return rgbToOklab(rgb);\n}\n\n/** Converts any accepted color string to Rgb. Throws if the format is unrecognized. */\nexport function colorToRgb(color: string): Rgb {\n const rgb = parseColorToRgb(color);\n if (rgb !== null) {\n return rgb;\n }\n\n const lab = parseOklchToOklab(color);\n if (lab !== null) {\n return oklabToRgb(lab);\n }\n\n throw new Error(`[sarmal] unrecognized color \"${color}\"`);\n}\n\n/** sRGB byte (0–255) to linear light (0–1)\n * @see {@link https://bottosson.github.io/posts/oklab/}\n */\nfunction srgbByteToLinear(c: number): number {\n const n = c / 255;\n return n <= 0.04045 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);\n}\n\n/** Linear light (0–1) to sRGB byte (0–255), gamma-compressed and clamped */\nfunction linearToSrgbByte(c: number): number {\n const v = Math.max(0, Math.min(1, c));\n return Math.round((v <= 0.0031308 ? 12.92 * v : 1.055 * Math.pow(v, 1 / 2.4) - 0.055) * 255);\n}\n\nexport interface Oklab {\n L: number;\n a: number;\n b: number;\n}\n\n/**\n * sRGB Rgb to OKLab\n * @see {@link https://bottosson.github.io/posts/oklab/}\n */\nexport function rgbToOklab({ r, g, b }: Rgb): Oklab {\n const rl = srgbByteToLinear(r),\n gl = srgbByteToLinear(g),\n bl = srgbByteToLinear(b);\n const l = Math.cbrt(0.4122214708 * rl + 0.5363325363 * gl + 0.0514459929 * bl);\n const m = Math.cbrt(0.2119034982 * rl + 0.6806995451 * gl + 0.1073969566 * bl);\n const s = Math.cbrt(0.0883024619 * rl + 0.2817188376 * gl + 0.6299787005 * bl);\n\n return {\n L: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,\n b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,\n };\n}\n\n/** OKLab to sRGB Rgb, out-of-gamut values clamped to 0–255 */\nexport function oklabToRgb({ L, a, b }: Oklab): Rgb {\n const l_ = L + 0.3963377774 * a + 0.2158037573 * b;\n const m_ = L - 0.1055613458 * a - 0.0638541728 * b;\n const s_ = L - 0.0894841775 * a - 1.29145603 * b;\n const l = l_ * l_ * l_,\n m = m_ * m_ * m_,\n s = s_ * s_ * s_;\n\n return {\n r: linearToSrgbByte(+4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s),\n g: linearToSrgbByte(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s),\n b: linearToSrgbByte(-0.0041960863 * l - 0.7034186147 * m + 1.6076099202 * s),\n };\n}\n\n/** Interpolates between two OKLab colors without any gray dead zone */\nexport const lerpOklab = (a: Oklab, b: Oklab, t: number): Oklab => {\n if (t <= 0) {\n return a;\n }\n\n if (t >= 1) {\n return b;\n }\n\n return {\n L: a.L + (b.L - a.L) * t,\n a: a.a + (b.a - a.a) * t,\n b: a.b + (b.b - a.b) * t,\n };\n};\n\n/**\n * Gets a color from a palette based on position (0-1) with optional time-based cycling\n * @param palette Array of Oklab colors\n * @param position Position along the gradient (0 = start, 1 = end)\n * @param timeOffset Optional time offset for animated gradients\n */\nexport function getPaletteColor(palette: Oklab[], position: number, timeOffset: number = 0): Oklab {\n if (palette.length === 0) {\n return { L: 1, a: 0, b: 0 };\n }\n\n if (palette.length === 1) {\n return palette[0]!;\n }\n\n const cyclePos = (((position + timeOffset) % 1) + 1) % 1;\n const scaled = cyclePos * palette.length;\n const idx = Math.floor(scaled);\n const t = scaled - idx;\n\n const c1 = palette[idx % palette.length]!;\n const c2 = palette[(idx + 1) % palette.length]!;\n\n return lerpOklab(c1, c2, t);\n}\n\n// TODO: maybe should infer the union type from the variable instead of making the variable respect the predefined union type\nconst TRAIL_STYLES: readonly TrailStyle[] = [\"default\", \"gradient-static\", \"gradient-animated\"];\n\n// FIXME: Should inherit from the actual render option object to avoid drift\nconst BASE_RENDER_OPTION_KEYS: ReadonlySet<string> = new Set([\n \"trailColor\",\n \"trailStyle\",\n \"skeletonColor\",\n]);\n\nconst RENDER_OPTION_KEYS: ReadonlySet<string> = new Set([\n \"trailColor\",\n \"headColor\",\n \"skeletonColor\",\n \"trailStyle\",\n \"headRadius\",\n \"trailWidth\",\n]);\n\n/**\n * Validates options for renderers that support `trailColor`, `trailStyle`, and `skeletonColor`.\n * Throws a `TypeError` if any canvas-only field (`headColor`, `headRadius`, `trailWidth`) is passed.\n */\nexport function validateBaseRenderOptions(partial: BaseRuntimeRenderOptions) {\n for (const key of Object.keys(partial)) {\n if (!BASE_RENDER_OPTION_KEYS.has(key)) {\n throw new TypeError(`[sarmal] setRenderOptions: unsupported key \"${key}\" for this renderer`);\n }\n }\n if (partial.trailColor !== undefined) {\n assertTrailColor(partial.trailColor);\n }\n if (partial.trailStyle !== undefined) {\n assertTrailStyle(partial.trailStyle);\n }\n if (partial.skeletonColor !== undefined) {\n assertSkeletonColor(partial.skeletonColor);\n }\n}\n\n/**\n * Checks a `RuntimeRenderOptions` payload against the library's acceptance criteria.\n *\n * If this throws, no field has been assigned yet on the caller side,\n * so the renderer continues on the previous valid state.\n *\n * Rules:\n * - Unknown keys throw for runtime type safety\n * - `trailColor` must match expected string/Array<string> format\n * - `headColor` must match expected color string format OR `null`\n * - `skeletonColor` must match expected color string format OR the literal `\"transparent\"`.\n * - `trailStyle` must match one of the accepted modes\n *\n * ! Field combinations like `trailColor=\"#ffffff\"` with `trailStyle=\"gradient-animated\"` are NOT rejected\n * They only produce a console warning at the renderer to indicate an unexpected outcome\n */\nexport function validateRenderOptions(partial: RuntimeRenderOptions) {\n for (const key of Object.keys(partial)) {\n if (!RENDER_OPTION_KEYS.has(key)) {\n throw new TypeError(`[sarmal] setRenderOptions: unknown key \"${key}\"`);\n }\n }\n\n if (partial.trailColor !== undefined) {\n assertTrailColor(partial.trailColor);\n }\n if (partial.headColor !== undefined) {\n assertHeadColor(partial.headColor);\n }\n if (partial.skeletonColor !== undefined) {\n assertSkeletonColor(partial.skeletonColor);\n }\n if (partial.trailStyle !== undefined) {\n assertTrailStyle(partial.trailStyle);\n }\n if (partial.headRadius !== undefined) {\n assertHeadRadius(partial.headRadius);\n }\n if (partial.trailWidth !== undefined) {\n assertTrailWidth(partial.trailWidth);\n }\n}\n\nfunction assertTrailColor(value: TrailColor) {\n if (typeof value === \"string\") {\n if (parseColorToOklab(value) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()), got \"${value}\"`,\n );\n }\n return;\n }\n\n if (Array.isArray(value)) {\n if (value.length < 2) {\n throw new RangeError(\n `[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`,\n );\n }\n\n for (let i = 0; i < value.length; i++) {\n const entry = value[i];\n if (typeof entry !== \"string\" || parseColorToOklab(entry) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor[${i}] must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()), got ${JSON.stringify(entry)}`,\n );\n }\n }\n return;\n }\n\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or an array of color strings, got ${JSON.stringify(value)}`,\n );\n}\n\nfunction assertHeadColor(value: string | null) {\n if (value === null) {\n return;\n }\n\n if (typeof value !== \"string\" || parseColorToOklab(value) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: headColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or null, got ${JSON.stringify(value)}`,\n );\n }\n}\n\nfunction assertSkeletonColor(value: string) {\n if (value === \"transparent\") {\n return;\n }\n\n if (typeof value !== \"string\" || parseColorToOklab(value) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: skeletonColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or \"transparent\", got ${JSON.stringify(value)}`,\n );\n }\n}\n\nfunction assertTrailStyle(value: TrailStyle) {\n if (!TRAIL_STYLES.includes(value)) {\n // TODO: perhaps make Trail Style inferred from a variable so it can be spread here to keep it dynamic.\n throw new RangeError(\n `[sarmal] setRenderOptions: trailStyle must be one of \"default\", \"gradient-static\", \"gradient-animated\", got ${JSON.stringify(value)}`,\n );\n }\n}\n\nfunction assertHeadRadius(value: number) {\n if (typeof value !== \"number\") {\n throw new TypeError(\n `[sarmal] setRenderOptions: headRadius must be a number, got ${JSON.stringify(value)}`,\n );\n }\n if (!Number.isFinite(value) || value <= 0) {\n throw new TypeError(\n `[sarmal] setRenderOptions: headRadius must be a finite positive number, got ${value}`,\n );\n }\n}\n\nfunction assertTrailWidth(value: number) {\n if (typeof value !== \"number\") {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailWidth must be a number, got ${JSON.stringify(value)}`,\n );\n }\n\n if (!Number.isFinite(value) || value <= 0) {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailWidth must be a finite positive number, got ${value}`,\n );\n }\n}\n\n/**\n * Resolves the effective solid fill color used by the `\"default\"` trail style.\n * If the caller passed an array, the first entry is used.\n *\n * This is to avoid errors when an array of colors are passed for `trailStyle=\"default\"`\n */\nexport function resolveTrailMainColor(trailColor: TrailColor) {\n return typeof trailColor === \"string\" ? trailColor : trailColor[0]!;\n}\n\n/**\n * Resolves the effective palette used by gradient trail styles.\n *\n * This is to avoid errors when a single color string is passed for gradient trail styles\n */\nexport function resolveTrailPalette(trailColor: TrailColor): string[] {\n return typeof trailColor === \"string\" ? [trailColor] : trailColor;\n}\n\n/**\n * Computes the head color automatically from the current `trailColor` and `trailStyle` pair.\n *\n * Rules:\n * - `\"default\"` style: the head matches the solid trail color.\n * - Gradient styles: the head matches the *last* stop of the palette\n *\n * @returns a CSS-valid color string\n */\nexport function resolveHeadColor(trailColor: TrailColor, trailStyle: TrailStyle): string {\n if (trailStyle === \"default\") {\n return resolveTrailMainColor(trailColor);\n }\n\n const palette = resolveTrailPalette(trailColor);\n const last = palette[palette.length - 1]!;\n const { r, g, b } = colorToRgb(last);\n return `rgb(${r},${g},${b})`;\n}\n\n/**\n * Emits a console warning when `trailColor` and `trailStyle` don't *semantically* match up\n *\n * For example, an array passed with `\"default\"` style (only the first color is used) or\n * a single string passed with a gradient style (the trail renders as a solid color)\n *\n * ! This is only a warning, so the renderer will still produce a valid output\n */\nexport function warnIfTrailColorMismatch(trailColor: TrailColor, trailStyle: TrailStyle): void {\n if (trailStyle === \"default\" && Array.isArray(trailColor)) {\n // biome-ignore lint/suspicious/noConsole: advisory for developer feedback\n console.warn(\n '[sarmal] trailColor is an array but trailStyle is \"default\"; only the first color will be used. Pass a gradient trailStyle to use the whole palette.',\n );\n\n return;\n }\n\n if (trailStyle !== \"default\" && typeof trailColor === \"string\") {\n // biome-ignore lint/suspicious/noConsole: advisory for developer feedback\n console.warn(\n `[sarmal] trailColor is a single color but trailStyle is \"${trailStyle}\"; the trail will render as a solid color. Pass an array of hex colors to use a real gradient.`,\n );\n }\n}\n","import type {\n CurveDef,\n MorphOptions,\n Point,\n RendererOptions,\n RuntimeRenderOptions,\n SarmalInstance,\n TrailColor,\n TrailStyle,\n} from \"./types\";\nexport type { TrailPoint } from \"./renderer-shared\";\nexport type { Rgb } from \"./renderer-shared\";\nexport type { Oklab } from \"./renderer-shared\";\n\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n TRAIL_MIN_WIDTH,\n TRAIL_MAX_WIDTH,\n computeBoundaries,\n computeTrailQuad,\n enginePassthroughs,\n colorToRgb,\n getPaletteColor,\n parseColorToOklab,\n resolveHeadColor,\n resolveTrailPalette,\n resolveTrailMainColor,\n oklabToRgb,\n Oklab,\n validateRenderOptions,\n warnIfTrailColorMismatch,\n} from \"./renderer-shared\";\n\nconst getHeadDotRadius = (w: number, h: number) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160));\n\nexport { computeTangent, computeNormal } from \"./renderer-shared\";\nexport { palettes, lerpOklab, getPaletteColor, parseColorToRgb } from \"./renderer-shared\";\n\nconst WHITE_HEX = \"#ffffff\";\n\nexport function colorToRgbComponents(color: string): string {\n const { r, g, b } = colorToRgb(color);\n return `${r},${g},${b}`;\n}\n\n/**\n * ! Exported purely so `applyDprSizing` can be unit-tested without a DOM\n */\nexport interface DprSizingTarget {\n width: number;\n height: number;\n style: { width: string; height: string };\n}\n\n/**\n * Applies DPR sizing to a target\n *\n * ! DO NOT REMOVE THE `style.width` and `style.height` ASSIGNMENTS\n *\n * A canvas with only `width`/`height` HTML attributes and no CSS derives\n * its displayed size from those attributes.\n * If we set `canvas.width = logicalWidth * dpr` to scale the drawing buffer for \"crispness\",\n * the element ALSO visually grows by the DPR factor\n * ! The bug is silent and sneaky. It just resulsts in a broken render without any obvious reasons\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas\n * MDN: \"If you don't set the CSS attributes, the intrinsic size of the canvas will be used as its display size\"\n *\n * @see https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html\n * \"Every canvas has 2 sizes: the drawingbuffer (pixels) and the display\n * size (CSS). If no CSS affects display size, it equals drawingbuffer.\"\n *\n * @see https://stackoverflow.com/questions/4938346/canvas-width-and-height-in-html5\n * Phrogz: \"If you don't set the CSS attributes, the intrinsic size of\n * the canvas will be used as its display size.\"\n *\n * The regression test for this lives in **renderer.test.ts**\n */\nexport function applyDprSizing(\n target: DprSizingTarget,\n logicalWidth: number,\n logicalHeight: number,\n dpr: number,\n): void {\n // Pin the CSS display size FIRST so changing the attributes below\n // cannot resize the element.\n target.style.width = `${logicalWidth}px`;\n target.style.height = `${logicalHeight}px`;\n\n target.width = logicalWidth * dpr;\n target.height = logicalHeight * dpr;\n}\n\n/**\n * Creates a Canvas 2D renderer for sarmal animations\n * Renders the skeleton and the trail\n */\nexport function createRenderer(options: RendererOptions): SarmalInstance {\n const canvas = options.canvas;\n if (!canvas.getContext(\"2d\")) {\n throw new Error(\"Could not get 2d context from canvas\");\n }\n const ctx = canvas.getContext(\"2d\")!;\n\n const engine = options.engine;\n\n // ! Mutated only by `setRenderOptions`.\n let trailStyle: TrailStyle = options.trailStyle ?? \"default\";\n let trailColor: TrailColor = options.trailColor ?? WHITE_HEX;\n let skeletonColor: string = options.skeletonColor ?? WHITE_HEX;\n // `null` means that head color is derived from `trailColor` & `trailStyle` and refreshed whenever either changes.\n let userHeadColor: string | null = options.headColor ?? null;\n let headColor: string = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);\n\n let trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));\n let trailPalette = resolveTrailPalette(trailColor);\n let trailPaletteOklab: Array<Oklab> = trailPalette.map((c) => parseColorToOklab(c)!);\n\n warnIfTrailColorMismatch(trailColor, trailStyle);\n\n /**\n * Device pixel ratio for high-DPI displays.\n * We scale the canvas buffer size by DPR and apply a transform scale\n */\n const dpr = typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1;\n\n /**\n * Sets up the canvas for DPR scaling\n */\n function setupCanvas() {\n // TODO: attach a ResizeObserver so this function can be called again for the right scale of canvas\n const lw = canvas.offsetWidth || 200;\n const lh = canvas.offsetHeight || 200;\n applyDprSizing(canvas, lw, lh, dpr);\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n }\n\n setupCanvas();\n\n // Store logical dimensions for boundary calculations\n let logicalWidth = canvas.width / dpr;\n let logicalHeight = canvas.height / dpr;\n if (options.headRadius !== undefined) {\n validateRenderOptions({ headRadius: options.headRadius });\n }\n\n if (options.trailWidth !== undefined) {\n validateRenderOptions({ trailWidth: options.trailWidth });\n }\n\n let headRadius = options.headRadius ?? getHeadDotRadius(logicalWidth, logicalHeight);\n let trailWidth = options.trailWidth ?? 1;\n\n let skeleton: Array<Point> = [];\n let skeletonCanvas: OffscreenCanvas | null = null;\n let trail: Array<Point> = [];\n let trailCount = 0;\n let head: Point | null = null;\n let scale = 1;\n let offsetX = 0;\n let offsetY = 0;\n let animationId: number | null = null;\n let lastTime = 0;\n let pausedByVisibility = false;\n\n let morphResolve: (() => void) | null = null;\n let morphReject: ((error: Error) => void) | null = null;\n let morphDurationMs = DEFAULT_MORPH_DURATION_MS;\n let morphAlpha = 0;\n\n /** Accumulated time for \"gradient-animated\" trail style */\n let gradientAnimTime = 0;\n\n function calculateBoundaries() {\n const b = computeBoundaries(skeleton, logicalWidth, logicalHeight);\n if (b) {\n scale = b.scale;\n offsetX = b.offsetX;\n offsetY = b.offsetY;\n }\n }\n\n /**\n * Draws the skeleton once into an OffscreenCanvas so that every frame\n * only needs a single ctx.drawImage() instead of rebuilding the full path.\n */\n function buildSkeletonCanvas() {\n if (skeleton.length < 2) {\n return;\n }\n\n skeletonCanvas = new OffscreenCanvas(canvas.width, canvas.height);\n const skeletonCtx = skeletonCanvas.getContext(\"2d\")!;\n\n // Apply DPR scale to draw in logical coordinates\n skeletonCtx.setTransform(dpr, 0, 0, dpr, 0, 0);\n\n skeletonCtx.strokeStyle = `rgba(${colorToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;\n skeletonCtx.lineWidth = 1.5;\n skeletonCtx.beginPath();\n\n const first = skeleton[0]!;\n skeletonCtx.moveTo(first.x * scale + offsetX, first.y * scale + offsetY);\n\n for (let i = 1; i < skeleton.length; i++) {\n const p = skeleton[i]!;\n skeletonCtx.lineTo(p.x * scale + offsetX, p.y * scale + offsetY);\n }\n\n skeletonCtx.stroke();\n }\n\n function drawSkeletonPath(pts: Array<Point>, opacity: number) {\n if (pts.length < 2) {\n return;\n }\n\n ctx.strokeStyle = `rgba(${colorToRgbComponents(skeletonColor)},${opacity})`;\n ctx.lineWidth = 1.5;\n ctx.beginPath();\n ctx.moveTo(pts[0]!.x * scale + offsetX, pts[0]!.y * scale + offsetY);\n for (let i = 1; i < pts.length; i++) {\n ctx.lineTo(pts[i]!.x * scale + offsetX, pts[i]!.y * scale + offsetY);\n }\n ctx.stroke();\n }\n\n function drawSkeleton() {\n if (skeletonColor === \"transparent\") {\n return;\n }\n\n if (engine.morphAlpha !== null) {\n // Draw the live lerped skeleton every frame so it always matches the current\n // scale/offset and correctly tracks live curves that change with actualTime\n drawSkeletonPath(engine.getSarmalSkeleton(), DEFAULT_SKELETON_OPACITY);\n return;\n }\n\n if (engine.isLiveSkeleton) {\n if (skeleton.length < 2) {\n return;\n }\n\n ctx.strokeStyle = `rgba(${colorToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;\n ctx.lineWidth = 1.5;\n ctx.beginPath();\n\n const first = skeleton[0]!;\n ctx.moveTo(first.x * scale + offsetX, first.y * scale + offsetY);\n\n for (let i = 1; i < skeleton.length; i++) {\n const p = skeleton[i]!;\n ctx.lineTo(p.x * scale + offsetX, p.y * scale + offsetY);\n }\n\n ctx.stroke();\n } else if (skeletonCanvas) {\n /**\n * ! The offscreen buffer is *already* DPR-scaled, but the main ctx also has a DPR transform applied,\n * ! so passing natural pixel size would **double-scale** it.\n */\n ctx.drawImage(skeletonCanvas, 0, 0, logicalWidth, logicalHeight);\n }\n }\n\n function drawTrail() {\n if (trailCount < 2) {\n return;\n }\n\n /**\n * Ribbon approach: draw the trail as a sequence of filled quads.\n * Each quad connects two consecutive trail points with left/right offsets\n * based on the width at that position. Quads are drawn from tail to head\n * so later quads naturally overlay earlier ones.\n *\n * @see https://cesium.com/blog/2013/04/22/robust-polyline-rendering-with-webgl\n * Cesium: \"draw a screen-aligned quad for each segment... extrude them\n * in screen space in the direction normal to the line.\"\n */\n const toX = (p: { x: number }) => p.x * scale + offsetX;\n const toY = (p: { y: number }) => p.y * scale + offsetY;\n for (let i = 0; i < trailCount - 1; i++) {\n const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity, progress } = computeTrailQuad(\n trail,\n i,\n trailCount,\n toX,\n toY,\n TRAIL_MIN_WIDTH * trailWidth,\n TRAIL_MAX_WIDTH * trailWidth,\n );\n\n // Determine fill color based on trail style\n if (trailStyle === \"default\") {\n ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;\n } else {\n const timeOffset = trailStyle === \"gradient-animated\" ? gradientAnimTime * 0.0005 : 0;\n const { r, g, b } = oklabToRgb(getPaletteColor(trailPaletteOklab, progress, timeOffset));\n ctx.fillStyle = `rgba(${r},${g},${b},${opacity})`;\n }\n\n ctx.beginPath();\n ctx.moveTo(l0x, l0y);\n ctx.lineTo(l1x, l1y);\n ctx.lineTo(r1x, r1y);\n ctx.lineTo(r0x, r0y);\n ctx.closePath();\n ctx.fill();\n }\n }\n\n function drawHead() {\n if (!head) {\n return;\n }\n\n const x = head.x * scale + offsetX;\n const y = head.y * scale + offsetY;\n const r = headRadius;\n\n ctx.fillStyle = headColor;\n ctx.beginPath();\n ctx.arc(x, y, r, 0, Math.PI * 2);\n ctx.fill();\n }\n\n function renderFrame(deltaTime: number) {\n // Update gradient animation time for animated trail style\n if (trailStyle === \"gradient-animated\") {\n gradientAnimTime += deltaTime * 1000; // Convert to ms for consistent speed\n }\n\n if (engine.morphAlpha !== null) {\n morphAlpha = Math.min(1, morphAlpha + deltaTime / (morphDurationMs / 1000));\n engine.setMorphAlpha(morphAlpha);\n\n /**\n * Compute bounds from the actual interpolated skeleton during morph\n * ! This ensures the curve stays properly centered and scaled\n */\n const interpolatedSkeleton = engine.getSarmalSkeleton();\n const bounds = computeBoundaries(interpolatedSkeleton, logicalWidth, logicalHeight);\n\n if (bounds) {\n scale = bounds.scale;\n offsetX = bounds.offsetX;\n offsetY = bounds.offsetY;\n }\n\n if (morphAlpha >= 1) {\n engine.completeMorph();\n morphResolve?.();\n morphResolve = null;\n morphReject = null;\n morphAlpha = 0;\n\n skeleton = engine.getSarmalSkeleton();\n if (!engine.isLiveSkeleton && skeletonColor !== \"transparent\") {\n buildSkeletonCanvas();\n }\n }\n }\n\n trail = engine.tick(deltaTime);\n trailCount = engine.trailCount;\n head = trailCount > 0 ? trail[trailCount - 1]! : null;\n\n ctx.clearRect(0, 0, logicalWidth, logicalHeight);\n\n if (engine.isLiveSkeleton && engine.morphAlpha === null) {\n skeleton = engine.getSarmalSkeleton();\n calculateBoundaries();\n }\n\n drawSkeleton();\n drawTrail();\n drawHead();\n }\n\n function loop() {\n const now = performance.now();\n const deltaTime = Math.min((now - lastTime) / 1000, 1 / 30);\n lastTime = now;\n\n renderFrame(deltaTime);\n animationId = requestAnimationFrame(loop);\n }\n\n // Initialize skeleton and offscreen canvas on creation\n skeleton = engine.getSarmalSkeleton();\n calculateBoundaries();\n\n if (!engine.isLiveSkeleton && skeletonColor !== \"transparent\") {\n buildSkeletonCanvas();\n }\n\n // Handle initialPhase option: seek to the specified position before first frame\n if (options.initialPhase !== undefined) {\n engine.seek(options.initialPhase);\n }\n\n // Draw initial frame unconditionally (shows skeleton and initial position)\n renderFrame(0);\n\n // Handle autoStart option: start the animation loop unless explicitly disabled\n const shouldAutoStart = options.autoStart !== false;\n\n const instance = {\n play() {\n if (animationId !== null) {\n return;\n }\n\n lastTime = performance.now();\n loop();\n },\n\n pause() {\n if (animationId === null) {\n return;\n }\n\n cancelAnimationFrame(animationId);\n animationId = null;\n engine.cancelSpeedTransition();\n },\n\n reset() {\n engine.reset();\n trail = [];\n head = null;\n },\n\n destroy() {\n if (animationId !== null) {\n cancelAnimationFrame(animationId);\n animationId = null;\n }\n\n document.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\n if (morphReject !== null) {\n morphReject(new Error(\"Instance destroyed during morph\"));\n morphResolve = null;\n morphReject = null;\n }\n },\n\n ...enginePassthroughs(engine),\n\n morphTo(target: CurveDef, options?: MorphOptions): Promise<void> {\n if (morphResolve !== null) {\n engine.completeMorph();\n morphResolve();\n morphResolve = null;\n morphReject = null;\n morphAlpha = 0;\n }\n\n morphDurationMs = options?.duration ?? DEFAULT_MORPH_DURATION_MS;\n morphAlpha = 0;\n\n engine.startMorph(target, options?.morphStrategy);\n\n return new Promise<void>((resolve, reject) => {\n morphResolve = resolve;\n morphReject = reject;\n });\n },\n\n setRenderOptions(partial: RuntimeRenderOptions): void {\n validateRenderOptions(partial);\n\n if (partial.trailColor !== undefined) {\n trailColor = partial.trailColor;\n trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));\n trailPalette = resolveTrailPalette(trailColor);\n trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c)!);\n }\n\n if (partial.skeletonColor !== undefined) {\n skeletonColor = partial.skeletonColor;\n\n if (skeletonColor !== \"transparent\" && !engine.isLiveSkeleton) {\n buildSkeletonCanvas();\n }\n }\n\n if (partial.trailStyle !== undefined) {\n trailStyle = partial.trailStyle;\n }\n\n if (partial.headColor !== undefined) {\n userHeadColor = partial.headColor;\n }\n\n if (partial.headRadius !== undefined) {\n headRadius = partial.headRadius;\n }\n\n if (partial.trailWidth !== undefined) {\n trailWidth = partial.trailWidth;\n }\n\n if (userHeadColor === null) {\n headColor = resolveHeadColor(trailColor, trailStyle);\n } else {\n headColor = userHeadColor;\n }\n\n if (partial.trailColor !== undefined || partial.trailStyle !== undefined) {\n warnIfTrailColorMismatch(trailColor, trailStyle);\n }\n },\n };\n\n const pauseOnHidden = options.pauseOnHidden !== false;\n\n function handleVisibilityChange() {\n if (document.hidden) {\n if (animationId !== null) {\n instance.pause();\n pausedByVisibility = true;\n }\n } else {\n if (pausedByVisibility) {\n pausedByVisibility = false;\n instance.play();\n }\n }\n }\n\n if (pauseOnHidden) {\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n }\n\n // If the tab is already hidden at construction time, skip auto-start.\n // The visibilitychange listener will resume when the tab becomes visible.\n const actuallyAutoStart = shouldAutoStart && !(pauseOnHidden && document.hidden);\n if (actuallyAutoStart) {\n instance.play();\n } else if (shouldAutoStart) {\n pausedByVisibility = true;\n }\n\n return instance;\n}\n","import type {\n BaseRendererOptions,\n CurveDef,\n Engine,\n MorphOptions,\n Point,\n RuntimeRenderOptions,\n SarmalInstance,\n TrailColor,\n TrailStyle,\n} from \"./types\";\n\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n TRAIL_MIN_WIDTH,\n TRAIL_MAX_WIDTH,\n computeBoundaries,\n computeTrailQuad,\n enginePassthroughs,\n colorToRgb,\n getPaletteColor,\n parseColorToOklab,\n resolveHeadColor,\n resolveTrailPalette,\n resolveTrailMainColor,\n oklabToRgb,\n Oklab,\n validateRenderOptions,\n warnIfTrailColorMismatch,\n} from \"./renderer-shared\";\nimport { createEngine } from \"./engine\";\n\nexport interface SVGRendererOptions extends BaseRendererOptions {\n /** SVG element the renderer draws into directly */\n container: SVGSVGElement;\n engine: Engine;\n /** @default 'Loading' */\n ariaLabel?: string;\n}\n\nexport interface SVGSarmalOptions extends Omit<SVGRendererOptions, \"container\" | \"engine\"> {\n /** @default 120 */\n trailLength?: number;\n}\nconst EMPTY_PARAMS: Record<string, number> = {};\nconst SVG_DEFAULT_HEAD_RADIUS = 0.5; // viewBox units\n/** Pixel-space skeleton stroke width calibrated to viewBox units at construction like TRAIL_MIN/MAX_WIDTH. */\nconst SKELETON_STROKE_WIDTH_PX = 1.5;\n\n/**\n * Threshold above which a console.warn suggests canvas for long SVG trails\n * The value is based on results from `playwright test e2e/tests/svg-trail-benchmark.spec.ts --project=chromium-dpr1 --reporter=list`\n */\nconst HIGH_TRAIL_LENGTH_THRESHOLD = 5000;\n\nfunction pointsToPathString(pts: Point[], scale: number, offsetX: number, offsetY: number): string {\n if (pts.length < 2) {\n return \"\";\n }\n\n const px = (p: Point) => (p.x * scale + offsetX).toFixed(2);\n const py = (p: Point) => (p.y * scale + offsetY).toFixed(2);\n let d = `M${px(pts[0]!)} ${py(pts[0]!)}`;\n\n for (let i = 1; i < pts.length; i++) {\n d += ` L${px(pts[i]!)} ${py(pts[i]!)}`;\n }\n\n return d + \" Z\";\n}\n\nfunction sampleCurveSkeleton(curveDef: CurveDef): Point[] {\n const period = curveDef.period ?? Math.PI * 2;\n const samples = Math.ceil(period * 50); // match engine's POINTS_PER_PERIOD_UNIT\n const pts: Point[] = Array.from({ length: samples });\n\n for (let i = 0; i < samples; i++) {\n const phase = (i / (samples - 1)) * period;\n pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(phase) : curveDef.fn(phase, 0, EMPTY_PARAMS);\n }\n\n return pts;\n}\n\nfunction el(tag: string): SVGElement {\n return document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n}\n\nfunction colorToRgbAttr(color: string): string {\n const { r, g, b } = colorToRgb(color);\n return `rgb(${r},${g},${b})`;\n}\n\n/**\n * Creates a live SVG renderer for sarmal animations\n * The SVG is appended into `container` and updated each frame via **requestAnimationFrame**\n */\nexport function createSVGRenderer(options: SVGRendererOptions): SarmalInstance {\n const { container, engine } = options;\n const poolSize = engine.trailLength;\n\n if (poolSize > HIGH_TRAIL_LENGTH_THRESHOLD) {\n console.warn(\n `[sarmal] High trailLength in SVG renderer (${poolSize}). Consider using the canvas renderer for long trails.`,\n );\n }\n\n // TODO: duplicate let variables. maybe a better way to share these too?\n // ! Mutated only by `setRenderOptions`.\n let trailStyle: TrailStyle = options.trailStyle ?? \"default\";\n let trailColor: TrailColor = options.trailColor ?? \"#ffffff\";\n let skeletonColor: string = options.skeletonColor ?? \"#ffffff\";\n // `null` means that head color is derived from `trailColor` & `trailStyle` and refreshed whenever either changes.\n let userHeadColor: string | null = options.headColor ?? null;\n let headColor: string = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);\n let headRadius: number; // assigned below after container size is read\n\n let trailSolid: string = colorToRgbAttr(resolveTrailMainColor(trailColor));\n let trailPalette: string[] = resolveTrailPalette(trailColor);\n let trailPaletteOklab: Oklab[] = trailPalette.map((c) => parseColorToOklab(c)!);\n\n const ariaLabel = options.ariaLabel ?? \"Loading\";\n\n warnIfTrailColorMismatch(trailColor, trailStyle);\n\n const viewSize = 100;\n\n function getContainerPixelSize(): number {\n const rect = container.getBoundingClientRect();\n return rect.width && rect.height ? Math.min(rect.width, rect.height) : 200;\n }\n\n /**\n * Trail widths and skeleton stroke are calibrated from pixel-space shared constants so that\n * strokes render at a consistent physical thickness regardless of container dimensions.\n * ! headRadius is NOT calibrated. It is native viewBox units (see SVG_DEFAULT_HEAD_RADIUS).\n */\n const containerPx = getContainerPixelSize();\n const svgTrailMinWidth = (TRAIL_MIN_WIDTH * viewSize) / containerPx;\n const svgTrailMaxWidth = (TRAIL_MAX_WIDTH * viewSize) / containerPx;\n const svgSkeletonStrokeWidth = String((SKELETON_STROKE_WIDTH_PX * viewSize) / containerPx);\n\n if (options.headRadius !== undefined) {\n validateRenderOptions({ headRadius: options.headRadius });\n }\n\n if (options.trailWidth !== undefined) {\n validateRenderOptions({ trailWidth: options.trailWidth });\n }\n headRadius = options.headRadius ?? SVG_DEFAULT_HEAD_RADIUS;\n let trailWidth = options.trailWidth ?? 1;\n\n container.setAttribute(\"viewBox\", `0 0 ${viewSize} ${viewSize}`);\n container.setAttribute(\"role\", \"img\");\n container.setAttribute(\"aria-label\", ariaLabel);\n\n const group = el(\"g\") as SVGGElement;\n\n const titleEl = el(\"title\");\n titleEl.textContent = ariaLabel;\n group.appendChild(titleEl);\n\n const skeletonPath = el(\"path\") as SVGPathElement;\n skeletonPath.setAttribute(\"data-sarmal-role\", \"skeleton\");\n skeletonPath.setAttribute(\"fill\", \"none\");\n skeletonPath.setAttribute(\n \"stroke\",\n skeletonColor === \"transparent\" ? \"transparent\" : colorToRgbAttr(skeletonColor),\n );\n skeletonPath.setAttribute(\"stroke-opacity\", String(DEFAULT_SKELETON_OPACITY));\n skeletonPath.setAttribute(\"stroke-width\", svgSkeletonStrokeWidth);\n if (skeletonColor === \"transparent\") {\n skeletonPath.setAttribute(\"visibility\", \"hidden\");\n }\n group.appendChild(skeletonPath);\n\n const skeletonPathA = el(\"path\") as SVGPathElement;\n skeletonPathA.setAttribute(\"fill\", \"none\");\n skeletonPathA.setAttribute(\n \"stroke\",\n skeletonColor === \"transparent\" ? \"transparent\" : colorToRgbAttr(skeletonColor),\n );\n skeletonPathA.setAttribute(\"stroke-width\", svgSkeletonStrokeWidth);\n skeletonPathA.setAttribute(\"visibility\", \"hidden\");\n group.appendChild(skeletonPathA);\n\n const skeletonPathB = el(\"path\") as SVGPathElement;\n skeletonPathB.setAttribute(\"fill\", \"none\");\n skeletonPathB.setAttribute(\n \"stroke\",\n skeletonColor === \"transparent\" ? \"transparent\" : colorToRgbAttr(skeletonColor),\n );\n skeletonPathB.setAttribute(\"stroke-width\", svgSkeletonStrokeWidth);\n skeletonPathB.setAttribute(\"visibility\", \"hidden\");\n group.appendChild(skeletonPathB);\n\n let morphPathABuilt = \"\";\n let morphPathBBuilt = \"\";\n\n const trailPaths: SVGPathElement[] = [];\n for (let i = 0; i < poolSize; i++) {\n const path = el(\"path\") as SVGPathElement;\n path.setAttribute(\"fill\", trailSolid);\n group.appendChild(path);\n trailPaths.push(path);\n }\n\n const headCircle = el(\"circle\") as SVGCircleElement;\n headCircle.setAttribute(\"data-sarmal-role\", \"head\");\n headCircle.setAttribute(\"fill\", colorToRgbAttr(headColor));\n headCircle.setAttribute(\"r\", String(headRadius));\n group.appendChild(headCircle);\n\n container.appendChild(group);\n\n let gradientAnimTime = 0;\n let scale = 1;\n let offsetX = 0;\n let offsetY = 0;\n\n function applyBoundaries(skeleton: Point[]) {\n const b = computeBoundaries(skeleton, viewSize, viewSize);\n if (b) {\n scale = b.scale;\n offsetX = b.offsetX;\n offsetY = b.offsetY;\n }\n }\n\n // Coordinate transform helpers: numeric (for math)\n function px(p: Point): number {\n return p.x * scale + offsetX;\n }\n function py(p: Point): number {\n return p.y * scale + offsetY;\n }\n\n function updateSkeleton(skeleton: Point[]) {\n skeletonPath.setAttribute(\"d\", pointsToPathString(skeleton, scale, offsetX, offsetY));\n }\n\n const skeleton = engine.getSarmalSkeleton();\n applyBoundaries(skeleton);\n\n if (!engine.isLiveSkeleton) {\n updateSkeleton(skeleton);\n }\n\n function updateTrail(trail: Point[], trailCount: number) {\n if (trailCount < 2) {\n for (const p of trailPaths) {\n p.setAttribute(\"d\", \"\");\n }\n\n return;\n }\n\n /**\n * Ribbon approach: each segment is a filled quad with its own opacity.\n * Quads are drawn from tail to head, with later quads overlaying earlier ones.\n */\n const drawnCount = trailCount - 1;\n\n for (let i = 0; i < drawnCount; i++) {\n const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity, progress } = computeTrailQuad(\n trail,\n i,\n trailCount,\n px,\n py,\n svgTrailMinWidth * trailWidth,\n svgTrailMaxWidth * trailWidth,\n );\n\n const d = `M${l0x.toFixed(2)} ${l0y.toFixed(2)} L${l1x.toFixed(2)} ${l1y.toFixed(2)} L${r1x.toFixed(2)} ${r1y.toFixed(2)} L${r0x.toFixed(2)} ${r0y.toFixed(2)} Z`;\n\n trailPaths[i]!.setAttribute(\"d\", d);\n trailPaths[i]!.setAttribute(\"fill-opacity\", opacity.toFixed(3));\n\n if (trailStyle !== \"default\") {\n const timeOffset = trailStyle === \"gradient-animated\" ? gradientAnimTime * 0.0005 : 0;\n const { r, g, b } = oklabToRgb(getPaletteColor(trailPaletteOklab, progress, timeOffset));\n trailPaths[i]!.setAttribute(\"fill\", `rgb(${r},${g},${b})`);\n }\n }\n\n // Hide unused paths\n for (let i = drawnCount; i < trailPaths.length; i++) {\n trailPaths[i]!.setAttribute(\"d\", \"\");\n }\n }\n\n function updateHead(trail: Point[], trailCount: number) {\n if (trailCount === 0) {\n return;\n }\n\n const head = trail[trailCount - 1]!;\n const x = px(head);\n const y = py(head);\n\n headCircle.setAttribute(\"cx\", String(x));\n headCircle.setAttribute(\"cy\", String(y));\n }\n\n let animationId: number | null = null;\n let lastTime = 0;\n let pausedByVisibility = false;\n const prefersReducedMotion =\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n\n let morphResolve: (() => void) | null = null;\n let morphReject: ((error: Error) => void) | null = null;\n let morphDurationMs = DEFAULT_MORPH_DURATION_MS;\n let morphTarget: CurveDef | null = null;\n let morphAlpha = 0;\n\n function renderFrame(deltaTime: number) {\n if (trailStyle === \"gradient-animated\") {\n gradientAnimTime += deltaTime * 1000;\n }\n\n if (engine.morphAlpha !== null) {\n morphAlpha = Math.min(1, morphAlpha + deltaTime / (morphDurationMs / 1000));\n engine.setMorphAlpha(morphAlpha);\n\n if (morphPathABuilt) {\n skeletonPathA.setAttribute(\"d\", morphPathABuilt);\n skeletonPathA.setAttribute(\"visibility\", \"visible\");\n skeletonPathA.setAttribute(\n \"stroke-opacity\",\n String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY),\n );\n }\n\n if (morphPathBBuilt) {\n skeletonPathB.setAttribute(\"d\", morphPathBBuilt);\n skeletonPathB.setAttribute(\"visibility\", \"visible\");\n skeletonPathB.setAttribute(\"stroke-opacity\", String(morphAlpha * DEFAULT_SKELETON_OPACITY));\n }\n\n if (morphAlpha >= 1) {\n engine.completeMorph();\n morphResolve?.();\n morphResolve = null;\n morphReject = null;\n morphTarget = null;\n morphAlpha = 0;\n morphPathABuilt = \"\";\n morphPathBBuilt = \"\";\n skeletonPathA.setAttribute(\"visibility\", \"hidden\");\n skeletonPathB.setAttribute(\"visibility\", \"hidden\");\n // Snap coordinate space to `curveB` and update skeleton path\n const newSkeleton = engine.getSarmalSkeleton();\n applyBoundaries(newSkeleton);\n updateSkeleton(newSkeleton);\n }\n }\n\n const trail = engine.tick(deltaTime);\n const trailCount = engine.trailCount;\n\n if (engine.isLiveSkeleton && engine.morphAlpha === null) {\n const liveSkeleton = engine.getSarmalSkeleton();\n applyBoundaries(liveSkeleton);\n updateSkeleton(liveSkeleton);\n }\n\n updateTrail(trail, trailCount);\n updateHead(trail, trailCount);\n }\n\n function loop() {\n const now = performance.now();\n const deltaTime = Math.min((now - lastTime) / 1000, 1 / 30);\n lastTime = now;\n\n renderFrame(deltaTime);\n\n if (!prefersReducedMotion) {\n animationId = requestAnimationFrame(loop);\n }\n }\n\n // Handle initialPhase option: seek to the specified position before first frame\n if (options.initialPhase !== undefined) {\n engine.seek(options.initialPhase);\n }\n\n // Draw initial frame unconditionally (shows skeleton and initial position)\n renderFrame(0);\n\n // Handle autoStart option: start the animation loop unless explicitly disabled\n const shouldAutoStart = options.autoStart !== false;\n\n const instance = {\n play() {\n if (animationId !== null) {\n return;\n }\n lastTime = performance.now();\n loop();\n },\n\n pause() {\n if (animationId === null) {\n return;\n }\n cancelAnimationFrame(animationId);\n animationId = null;\n engine.cancelSpeedTransition();\n },\n\n reset() {\n engine.reset();\n },\n\n destroy() {\n if (animationId !== null) {\n cancelAnimationFrame(animationId);\n animationId = null;\n }\n\n document.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\n if (morphReject !== null) {\n morphReject(new Error(\"Instance destroyed during morph\"));\n morphResolve = null;\n morphReject = null;\n }\n\n group.remove();\n },\n\n ...enginePassthroughs(engine),\n\n morphTo(target: CurveDef, options?: MorphOptions): Promise<void> {\n if (morphResolve !== null) {\n engine.completeMorph();\n morphResolve();\n morphResolve = null;\n morphReject = null;\n morphAlpha = 0;\n skeletonPathA.setAttribute(\"visibility\", \"hidden\");\n skeletonPathB.setAttribute(\"visibility\", \"hidden\");\n }\n\n morphDurationMs = options?.duration ?? DEFAULT_MORPH_DURATION_MS;\n morphTarget = target;\n morphAlpha = 0;\n\n const currentSkeleton = engine.getSarmalSkeleton();\n morphPathABuilt = pointsToPathString(currentSkeleton, scale, offsetX, offsetY);\n\n engine.startMorph(target, options?.morphStrategy);\n\n if (morphTarget) {\n const targetSkeleton = sampleCurveSkeleton(target);\n morphPathBBuilt = pointsToPathString(targetSkeleton, scale, offsetX, offsetY);\n }\n\n return new Promise<void>((resolve, reject) => {\n morphResolve = resolve;\n morphReject = reject;\n });\n },\n\n setRenderOptions(partial: RuntimeRenderOptions): void {\n validateRenderOptions(partial);\n\n const prevTrailStyle = trailStyle;\n\n if (partial.trailColor !== undefined) {\n trailColor = partial.trailColor;\n trailSolid = colorToRgbAttr(resolveTrailMainColor(trailColor));\n trailPalette = resolveTrailPalette(trailColor);\n trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c)!);\n\n // Only the \"default\" style paints trail paths at setter time, whereas gradient styles repaint per-segment fills every frame in `updateTrail`,\n // so they would already overwrite any fill operation made here\n if (trailStyle === \"default\") {\n for (const p of trailPaths) {\n p.setAttribute(\"fill\", trailSolid);\n }\n }\n }\n\n if (partial.skeletonColor !== undefined) {\n skeletonColor = partial.skeletonColor;\n\n if (skeletonColor === \"transparent\") {\n skeletonPath.setAttribute(\"visibility\", \"hidden\");\n } else {\n skeletonPath.setAttribute(\"stroke\", colorToRgbAttr(skeletonColor));\n skeletonPath.removeAttribute(\"visibility\");\n skeletonPathA.setAttribute(\"stroke\", colorToRgbAttr(skeletonColor));\n skeletonPathB.setAttribute(\"stroke\", colorToRgbAttr(skeletonColor));\n }\n }\n\n if (partial.trailStyle !== undefined) {\n trailStyle = partial.trailStyle;\n\n // When transitioning from gradient to default, the whole trail needs to be filled with the color\n // Transitioning from default to gradient does not require this as it already does per-segment color fills\n if (prevTrailStyle !== \"default\" && trailStyle === \"default\") {\n for (const p of trailPaths) {\n p.setAttribute(\"fill\", trailSolid);\n }\n }\n }\n if (partial.headColor !== undefined) {\n userHeadColor = partial.headColor;\n }\n\n if (partial.headRadius !== undefined) {\n headRadius = partial.headRadius;\n headCircle.setAttribute(\"r\", String(headRadius));\n }\n\n if (partial.trailWidth !== undefined) {\n trailWidth = partial.trailWidth;\n }\n\n if (userHeadColor === null) {\n headColor = resolveHeadColor(trailColor, trailStyle);\n } else {\n headColor = userHeadColor;\n }\n headCircle.setAttribute(\"fill\", colorToRgbAttr(headColor));\n\n if (partial.trailColor !== undefined || partial.trailStyle !== undefined) {\n warnIfTrailColorMismatch(trailColor, trailStyle);\n }\n },\n };\n\n const pauseOnHidden = options.pauseOnHidden !== false;\n\n function handleVisibilityChange() {\n if (document.hidden) {\n if (animationId !== null) {\n instance.pause();\n pausedByVisibility = true;\n }\n } else {\n if (pausedByVisibility) {\n pausedByVisibility = false;\n instance.play();\n }\n }\n }\n\n if (pauseOnHidden) {\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n }\n\n // If the tab is already hidden at construction time, skip auto-start.\n // The visibilitychange listener will resume when the tab becomes visible.\n const actuallyAutoStart = shouldAutoStart && !(pauseOnHidden && document.hidden);\n if (actuallyAutoStart) {\n instance.play();\n } else if (shouldAutoStart) {\n pausedByVisibility = true;\n }\n\n return instance;\n}\n\n/**\n * Creates a sarmal animation directly inside an `<svg>` element using an SVG renderer.\n * The passed `<svg>` element is set to `viewBox=\"0 0 100 100\"` and animated via requestAnimationFrame\n *\n * @example\n * ```ts\n * import { createSarmalSVG, epitrochoid7 } from '@sarmal/core'\n *\n * // <svg id=\"spinner\"></svg> in your HTML\n * const svg = document.getElementById('spinner')\n * const sarmal = createSarmalSVG(svg, epitrochoid7)\n *\n * // To control manually, use autoStart: false\n * const controlled = createSarmalSVG(svg, rose5, { autoStart: false })\n * controlled.play() // Start when ready\n * controlled.pause() // Pause later\n * ```\n */\nexport function createSarmalSVG(\n container: SVGSVGElement,\n curveDef: CurveDef,\n options?: SVGSarmalOptions,\n): SarmalInstance {\n const { trailLength, ...rendererOpts } = options ?? {};\n const engine = createEngine(curveDef, trailLength);\n return createSVGRenderer({ container, engine, ...rendererOpts });\n}\n","import type {\n BaseRendererOptions,\n CurveDef,\n DotMatrixRuntimeRenderOptions,\n MorphOptions,\n SarmalInstance,\n TrailColor,\n TrailStyle,\n} from \"./types\";\nimport type { Oklab, Rgb } from \"./renderer-shared\";\n\nimport { createEngine } from \"./engine\";\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n colorToRgb,\n computeBoundaries,\n enginePassthroughs,\n getPaletteColor,\n oklabToRgb,\n parseColorToOklab,\n resolveTrailMainColor,\n resolveTrailPalette,\n validateBaseRenderOptions,\n warnIfTrailColorMismatch,\n} from \"./renderer-shared\";\n\nexport interface DotMatrixSarmalOptions extends Pick<\n BaseRendererOptions,\n \"autoStart\" | \"pauseOnHidden\" | \"initialPhase\" | \"skeletonColor\"\n> {\n /**\n * Number of dot columns in the grid.\n * @default 32\n */\n cols?: number;\n /**\n * Number of dot rows in the grid.\n * @default 32\n */\n rows?: number;\n /**\n * Controls the corner rounding of each dot.\n * `0` renders as a sharp-cornered square,\n * `1` renders as a full circle.\n * Values between `0` and `1` give rounded rectangles.\n * @default 1\n */\n roundness?: number;\n /**\n * Number of trail points to keep.\n * Larger values mean the trail extends further back from the head.\n * @default cols * 3\n */\n trailLength?: number;\n /**\n * Color of lit dots. Single color string for solid mode; array of two or more colors for gradient mode.\n * Gradient mode samples a color per dot based on its position in the trail (tail → head).\n * Background dots always use the first color at 5% opacity.\n * @default '#ffffff'\n */\n trailColor?: TrailColor;\n /**\n * Trail rendering style.\n * - `'default'` — solid color, alpha varies by intensity.\n * - `'gradient-static'` — each dot's color is sampled from the `trailColor` gradient. Requires `trailColor` array.\n * - `'gradient-animated'` — same as `gradient-static` but the gradient phase shifts over time.\n * @default 'default'\n */\n trailStyle?: TrailStyle;\n}\n\n/**\n * Creates a dot matrix renderer for a sarmal animation on a canvas element.\n *\n * The renderer maps the animation's trail to a grid of dots.\n * Each frame, the grid is cleared and rebuilt: dots near the head of the trail are bright,\n * dots near the tail are dim, and dots with no trail activity are barely visible (5% opacity).\n *\n * Grid geometry is derived from `cols` and `rows`.\n * For example, a 240x240 canvas with `cols: 32, rows: 32` produces 1024 dots with cells approximately 7.5x7.5 px each.\n *\n * At init, a pixel mask is computed that records which canvas pixels belong to each dot.\n * Each frame, RGBA values are written directly into a typed array (one entry per lit pixel)\n * and flushed to the canvas with a single `ctx.putImageData` call.\n * Frame cost is flat regardless of how many dots are lit or what grid size is used.\n *\n * @param canvas - The canvas element to draw into.\n * Its `width` and `height` HTML attributes determine the rendering area.\n * CSS display size is not read.\n * @param curveDef - The curve to animate.\n * @param options - Optional configuration for grid size, color, roundness, and lifecycle.\n * @returns A `SarmalInstance` with the standard `play` / `pause` / `destroy` / `morphTo` interface.\n *\n * @example\n * ```ts\n * import { createSarmalDotMatrix, curves } from '@sarmal/core'\n *\n * const instance = createSarmalDotMatrix(canvas, curves.lissajous43, {\n * cols: 32,\n * rows: 32,\n * trailColor: '#2dd4bf',\n * })\n * ```\n */\nexport function createSarmalDotMatrix(\n canvas: HTMLCanvasElement,\n curveDef: CurveDef,\n options?: DotMatrixSarmalOptions,\n): SarmalInstance<DotMatrixRuntimeRenderOptions> {\n const {\n cols = 32,\n rows = 32,\n roundness = 1,\n trailLength: trailLengthOpt,\n trailColor: initialColor = \"#ffffff\",\n trailStyle: initialTrailStyle = \"default\",\n skeletonColor: skeletonColorOpt = \"#ffffff\",\n autoStart = true,\n pauseOnHidden: pauseOnHiddenOpt = true,\n initialPhase,\n } = options ?? {};\n\n const trailLength = trailLengthOpt ?? cols * 3;\n const engine = createEngine(curveDef, trailLength);\n\n if (!canvas.getContext(\"2d\")) {\n throw new Error(\"[sarmal] Could not get 2d context from canvas\");\n }\n const ctx = canvas.getContext(\"2d\")!;\n\n const W = canvas.width;\n const H = canvas.height;\n const cellW = W / cols;\n const cellH = H / rows;\n // Dot radius is 36% of the smaller cell dimension.\n // It is large enough to be clearly visible without adjacent dots overlapping even at coarse grid densities\n const dotR = Math.min(cellW, cellH) * 0.36;\n\n // Oklab palette: always populated by `applyColor()`, used only when `trailStyle !== \"default\"`.\n // Oklab interpolation avoids the gray dead zone that sRGB gradients produce.\n let gradientOklab: Array<Oklab> = [];\n // Primary color in Rgb: always the first (or only) stop of `trailColor`.\n // Used for solid mode and as the background dot hue. Initialized by `applyColor()` in the init block below.\n let colorRgb: Rgb = { r: 255, g: 255, b: 255 };\n let trailStyle: TrailStyle = initialTrailStyle;\n let trailColor: TrailColor = initialColor;\n // Accumulated milliseconds; incremented each frame only in 'gradient-animated' mode.\n let gradientAnimTime = 0;\n\n // Flat buffer: one intensity value (0–1) per grid cell, indexed as row * cols + col.\n // 0 means the trail is not touching this cell,\n // >0 means the trail passes through it,\n // with 1 being the brightest (head of trail) and small values being the dimmest (tail).\n const grid = new Float32Array(cols * rows);\n\n // Coordinate mapping: engine math space to pixel space.\n // Recomputed from the skeleton so the curve fits within the canvas regardless of its range.\n let scale = 1;\n let offsetX = 0;\n let offsetY = 0;\n\n // Pixel mask: flat-packed arrays mapping each dot index to its RGBA byte offsets in canvas pixel space.\n // Computed once at init so `draw()` never needs to do geometry math.\n let pixelMaskStarts: Uint32Array = new Uint32Array(0);\n let pixelMaskLengths: Uint32Array = new Uint32Array(0);\n let pixelMaskIndices: Uint32Array = new Uint32Array(0);\n // Per-pixel antialiasing coverage (0.0–1.0),\n // precomputed through 4x4 SSAA.\n // Interior pixels = 1.0\n // edge pixels have a fraction that fades alpha smoothly.\n let pixelMaskCoverages: Float32Array = new Float32Array(0);\n // bgImageData: all dots at 5% opacity which are restored at the start of every frame. Rebuilt on color change.\n // frameImageData: working buffer, overwritten completely each frame. Allocated once at init.\n let bgImageData: ImageData | null = null;\n let frameImageData: ImageData | null = null;\n\n // Skeleton state: which dots are \"on\" the skeleton, and the parsed skeleton color.\n // `skeletonDotGrid` is a flat boolean mask (0 or 1) over the grid, updated whenever boundaries change.\n // `skeletonColorOklab` is null when skeleton is 'transparent' (disabled)\n let skeletonColorOklab: Oklab | null = null;\n const skeletonDotGrid = new Uint8Array(cols * rows);\n\n let animationId: number | null = null;\n let lastTime = 0;\n let pausedByVisibility = false;\n\n // Morph state: same pattern as the canvas renderer\n let morphResolve: (() => void) | null = null;\n let morphReject: ((error: Error) => void) | null = null;\n let morphDurationMs = DEFAULT_MORPH_DURATION_MS;\n let morphProgress = 0;\n\n /**\n * Pre-computes which canvas pixels belong to each dot using a rounded-rectangle SDF,\n * with 4x4 supersampled antialiasing coverage.\n *\n * For each pixel in every dot's bounding box, 16 sub-sample points are tested against the SDF.\n * The fraction that pass (0.0625–1.0) is stored as that pixel's coverage.\n * Edge pixels fade out smoothly instead of snapping to binary inside/outside,\n * so all dot shapes look correctly antialiased regardless of radius.\n *\n * Results are stored in TypedArrays for cache friendly access in draw().\n * ! Must be called once before `buildBgImageData()`\n */\n function computePixelMask() {\n const starts = new Uint32Array(cols * rows);\n const lengths = new Uint32Array(cols * rows);\n const allIndices: number[] = [];\n const allCoverages: number[] = [];\n const cornerR = roundness * dotR;\n const cornerR2 = cornerR * cornerR;\n // 4x4 SSAA: 16 sub-samples per pixel, each offset by (i+0.5)/4 within the pixel\n const SSAA = 4;\n const SSAA2 = SSAA * SSAA;\n\n for (let row = 0; row < rows; row++) {\n for (let col = 0; col < cols; col++) {\n const dotIdx = row * cols + col;\n const cx = (col + 0.5) * cellW;\n const cy = (row + 0.5) * cellH;\n // Extend bounding box by one pixel so edge sub-samples are captured\n const x0 = Math.max(0, Math.floor(cx - dotR - 1));\n const x1 = Math.min(W - 1, Math.ceil(cx + dotR + 1));\n const y0 = Math.max(0, Math.floor(cy - dotR - 1));\n const y1 = Math.min(H - 1, Math.ceil(cy + dotR + 1));\n\n starts[dotIdx] = allIndices.length;\n let count = 0;\n for (let py = y0; py <= y1; py++) {\n for (let px = x0; px <= x1; px++) {\n let hits = 0;\n for (let sy = 0; sy < SSAA; sy++) {\n const spyCenter = py + (sy + 0.5) / SSAA;\n for (let sx = 0; sx < SSAA; sx++) {\n const spxCenter = px + (sx + 0.5) / SSAA;\n // Generalized rounded-rect SDF:\n // roundness=0 (square), roundness=1 (full circle)\n const dx = Math.max(Math.abs(spxCenter - cx) - (dotR - cornerR), 0);\n const dy = Math.max(Math.abs(spyCenter - cy) - (dotR - cornerR), 0);\n if (dx * dx + dy * dy <= cornerR2) {\n hits++;\n }\n }\n }\n\n if (hits > 0) {\n allIndices.push((py * W + px) * 4);\n allCoverages.push(hits / SSAA2);\n count++;\n }\n }\n }\n lengths[dotIdx] = count;\n }\n }\n\n pixelMaskStarts = starts;\n pixelMaskLengths = lengths;\n pixelMaskIndices = new Uint32Array(allIndices);\n pixelMaskCoverages = new Float32Array(allCoverages);\n }\n\n /**\n * Builds the background ImageData (all dots at 5% opacity).\n * Rebuilt whenever trailColor changes since background dots share the trail hue.\n * ! Must be called after `computePixelMask()`\n */\n function buildBgImageData() {\n bgImageData = new ImageData(W, H);\n\n const bg = colorRgb;\n const baseAlpha = 0.05 * 255;\n const { data } = bgImageData;\n const n = cols * rows;\n\n for (let dotIdx = 0; dotIdx < n; dotIdx++) {\n const start = pixelMaskStarts[dotIdx]!;\n const len = pixelMaskLengths[dotIdx]!;\n\n for (let k = 0; k < len; k++) {\n const px = pixelMaskIndices[start + k]!;\n const coverage = pixelMaskCoverages[start + k]!;\n data[px] = bg.r;\n data[px + 1] = bg.g;\n data[px + 2] = bg.b;\n data[px + 3] = Math.round(baseAlpha * coverage);\n }\n }\n }\n\n function applyColor(color: TrailColor) {\n colorRgb = colorToRgb(resolveTrailMainColor(color));\n gradientOklab = resolveTrailPalette(color).map((c) => parseColorToOklab(c)!);\n }\n\n function applySkeletonColor(color: string) {\n skeletonColorOklab = color === \"transparent\" ? null : parseColorToOklab(color)!;\n }\n\n /**\n * Marks which grid cells the skeleton path passes through.\n * Uses the same `mapPt` + gap-fill logic as `buildGrid` so the skeleton\n * traces the same cells the trail would trace over a full period.\n * Mutates `skeletonDotGrid`. Called at init and whenever boundaries change.\n */\n function computeSkeletonGrid(skel: Array<{ x: number; y: number }>) {\n skeletonDotGrid.fill(0);\n const count = skel.length;\n for (let i = 0; i < count; i++) {\n const pt = skel[i]!;\n const [c, r] = mapPt(pt.x, pt.y);\n skeletonDotGrid[r * cols + c] = 1;\n\n if (i < count - 1) {\n const next = skel[i + 1]!;\n const [nc, nr] = mapPt(next.x, next.y);\n const steps = Math.ceil(Math.max(Math.abs(nc - c), Math.abs(nr - r))) * 2;\n\n for (let s = 1; s < steps; s++) {\n const t = s / steps;\n const ix = pt.x + (next.x - pt.x) * t;\n const iy = pt.y + (next.y - pt.y) * t;\n const [ic, ir] = mapPt(ix, iy);\n skeletonDotGrid[ir * cols + ic] = 1;\n }\n }\n }\n }\n\n /**\n * Writes skeleton dot pixels into `data` at `DEFAULT_SKELETON_OPACITY`, coverage-weighted.\n * If `skeletonColorOklab` is `null` (transparent), nothing happens\n * Called every frame in `draw()` before the trail pass so trail always overwrites skeleton.\n */\n function writeSkeletonPixels(data: Uint8ClampedArray) {\n if (skeletonColorOklab === null) {\n return;\n }\n\n const { r, g, b } = oklabToRgb(skeletonColorOklab);\n const skelBaseAlpha = DEFAULT_SKELETON_OPACITY * 255;\n const n = cols * rows;\n\n for (let dotIdx = 0; dotIdx < n; dotIdx++) {\n if (!skeletonDotGrid[dotIdx]) {\n continue;\n }\n\n const start = pixelMaskStarts[dotIdx]!;\n const len = pixelMaskLengths[dotIdx]!;\n\n for (let k = 0; k < len; k++) {\n const px = pixelMaskIndices[start + k]!;\n const coverage = pixelMaskCoverages[start + k]!;\n data[px] = r;\n data[px + 1] = g;\n data[px + 2] = b;\n data[px + 3] = Math.round(skelBaseAlpha * coverage);\n }\n }\n }\n\n /**\n * Recomputes the scale and offset needed to map engine coordinates into this canvas.\n * The engine produces coordinates in math space (roughly [-1, 1] for most curves, but not always).\n * `computeBoundaries` finds the bounding box of the full curve and\n * returns a uniform scale + centering offset so the curve fills the canvas with consistent padding.\n */\n function calculateBoundaries(skel: Array<{ x: number; y: number }>) {\n const b = computeBoundaries(skel, W, H);\n\n if (b) {\n scale = b.scale;\n offsetX = b.offsetX;\n offsetY = b.offsetY;\n }\n }\n\n /**\n * Maps a point in engine math space to a grid cell index [col, row].\n *\n * The flow is: engine coords to pixel coords (by scale + offset) to grid cell index.\n * The result is clamped so it always falls within the grid bounds.\n */\n function mapPt(x: number, y: number): [number, number] {\n const px = x * scale + offsetX;\n const py = y * scale + offsetY;\n\n return [\n Math.max(0, Math.min(cols - 1, Math.round((px / W) * (cols - 1)))),\n Math.max(0, Math.min(rows - 1, Math.round((py / H) * (rows - 1)))),\n ];\n }\n\n /**\n * Writes an intensity value to a grid cell, keeping whichever is higher.\n * A single cell can be stamped multiple times. The brightest value wins.\n */\n function stamp(c: number, r: number, intensity: number) {\n const idx = r * cols + c;\n\n if (intensity > grid[idx]!) {\n grid[idx] = intensity;\n }\n }\n\n /**\n * Clears the grid and rebuilds it from the current trail.\n *\n * Tail points get low intensity (near 0),\n * the head gets intensity 1\n *\n * Gap fill: consecutive trail points can skip grid cells when the curve moves fast\n * relative to the grid density.\n * This is visible as gaps in the trail at coarse grids.\n *\n * We prevent this by linearly interpolating between adjacent trail points at sub-cell\n * resolution and stamping every intermediate cell.\n */\n function buildGrid(deltaTime: number) {\n const trail = engine.tick(deltaTime);\n const count = engine.trailCount;\n\n grid.fill(0);\n\n for (let i = 0; i < count; i++) {\n const pt = trail[i]!;\n const intensity = (i + 1) / count;\n const [c, r] = mapPt(pt.x, pt.y);\n stamp(c, r, intensity);\n\n if (i < count - 1) {\n const next = trail[i + 1]!;\n const [nc, nr] = mapPt(next.x, next.y);\n // Number of interpolated steps scales with how far apart the two cells are.\n // Multiplying by 2 ensures we never skip a cell even on diagonal moves.\n const steps = Math.ceil(Math.max(Math.abs(nc - c), Math.abs(nr - r))) * 2;\n\n for (let s = 1; s < steps; s++) {\n const t = s / steps;\n const ix = pt.x + (next.x - pt.x) * t;\n const iy = pt.y + (next.y - pt.y) * t;\n const ii = intensity + (1 / count) * t;\n const [ic, ir] = mapPt(ix, iy);\n stamp(ic, ir, ii);\n }\n }\n }\n }\n\n /**\n * Draws the current grid state to the canvas.\n *\n * Restores the background ImageData (all dim dots at 5% opacity),\n * then writes lit dot pixels directly into the frame buffer at their exact intensity and color,\n * flushing once with `putImageData`\n * Total canvas API calls per frame: 1\n */\n function draw() {\n if (!bgImageData || !frameImageData) {\n return;\n }\n\n frameImageData.data.set(bgImageData.data);\n const { data } = frameImageData;\n\n writeSkeletonPixels(data);\n\n const timeOffset = trailStyle === \"gradient-animated\" ? gradientAnimTime * 0.0005 : 0;\n\n const n = cols * rows;\n for (let dotIdx = 0; dotIdx < n; dotIdx++) {\n const intensity = grid[dotIdx]!;\n if (intensity <= 0) {\n continue;\n }\n\n let r: number, g: number, b: number;\n if (trailStyle !== \"default\") {\n ({ r, g, b } = oklabToRgb(getPaletteColor(gradientOklab, intensity, timeOffset)));\n } else {\n ({ r, g, b } = colorRgb);\n }\n // Skeleton dots act as a brightness floor: trail tail (min 8% alpha) must not dim a\n // skeleton dot (15% alpha) since pixels are raw overwrites, not alpha-composited.\n const skelFloor =\n skeletonColorOklab !== null && skeletonDotGrid[dotIdx] === 1\n ? DEFAULT_SKELETON_OPACITY * 255\n : 0;\n const baseA = Math.max(skelFloor, (0.08 + intensity * 0.92) * 255);\n\n const start = pixelMaskStarts[dotIdx]!;\n const len = pixelMaskLengths[dotIdx]!;\n for (let k = 0; k < len; k++) {\n const px = pixelMaskIndices[start + k]!;\n const coverage = pixelMaskCoverages[start + k]!;\n data[px] = r;\n data[px + 1] = g;\n data[px + 2] = b;\n data[px + 3] = Math.round(baseA * coverage);\n }\n }\n\n ctx.putImageData(frameImageData, 0, 0);\n }\n\n function completeMorphNow() {\n engine.completeMorph();\n morphResolve?.();\n morphResolve = null;\n morphReject = null;\n morphProgress = 0;\n }\n\n /**\n * Advances the simulation by `deltaTime` seconds and redraws the canvas.\n * Handles morph progress and live-skeleton boundary updates the same way the canvas renderer does.\n */\n function renderFrame(deltaTime: number) {\n if (engine.morphAlpha !== null) {\n morphProgress = Math.min(1, morphProgress + deltaTime / (morphDurationMs / 1000));\n engine.setMorphAlpha(morphProgress);\n // Boundaries must track the interpolated skeleton during morph so the curve stays centered\n calculateBoundaries(engine.getSarmalSkeleton());\n\n if (morphProgress >= 1) {\n completeMorphNow();\n calculateBoundaries(engine.getSarmalSkeleton());\n }\n computeSkeletonGrid(engine.getSarmalSkeleton());\n } else if (engine.isLiveSkeleton) {\n calculateBoundaries(engine.getSarmalSkeleton());\n computeSkeletonGrid(engine.getSarmalSkeleton());\n }\n\n if (trailStyle === \"gradient-animated\") {\n gradientAnimTime += deltaTime * 1000;\n }\n\n buildGrid(deltaTime);\n draw();\n }\n\n // Accept the rAF timestamp so tests can drive time manually by passing a controlled value.\n // Falls back to performance.now() when called directly (e.g. from play()).\n function loop(timestamp: number = performance.now()) {\n // Cap dt at 1/30s to prevent large jumps after the tab was backgrounded\n const deltaTime = Math.min((timestamp - lastTime) / 1000, 1 / 30);\n lastTime = timestamp;\n renderFrame(deltaTime);\n animationId = requestAnimationFrame(loop);\n }\n\n // ── Init ────────────────────────────────────────────────────────────────────\n\n validateBaseRenderOptions({ trailColor: initialColor, skeletonColor: skeletonColorOpt });\n applyColor(initialColor);\n applySkeletonColor(skeletonColorOpt);\n warnIfTrailColorMismatch(trailColor, trailStyle);\n calculateBoundaries(engine.getSarmalSkeleton());\n computePixelMask();\n computeSkeletonGrid(engine.getSarmalSkeleton());\n frameImageData = new ImageData(W, H);\n buildBgImageData();\n\n if (initialPhase !== undefined) {\n engine.seek(initialPhase);\n }\n\n renderFrame(0);\n\n // ── Instance ─────────────────────────────────────────────────────────────────\n\n const instance: SarmalInstance<DotMatrixRuntimeRenderOptions> = {\n /** Starts the animation loop. Does nothing if already running. */\n play() {\n if (animationId !== null) {\n return;\n }\n\n lastTime = performance.now();\n loop();\n },\n\n /** Pauses the animation loop. Preserves current trail state. */\n pause() {\n if (animationId === null) {\n return;\n }\n\n cancelAnimationFrame(animationId);\n animationId = null;\n engine.cancelSpeedTransition();\n },\n\n /** Resets the animation to the start of the curve and clears the grid. */\n reset() {\n engine.reset();\n grid.fill(0);\n },\n\n /** Stops the animation and removes all event listeners. */\n destroy() {\n if (animationId !== null) {\n cancelAnimationFrame(animationId);\n animationId = null;\n }\n document.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n if (morphReject !== null) {\n morphReject(new Error(\"[sarmal] Instance destroyed during morph\"));\n morphResolve = null;\n morphReject = null;\n }\n },\n\n ...enginePassthroughs(engine),\n\n /**\n * Smoothly transitions from the current curve to `target`.\n * If a morph is already in progress, it is snapped to completion before the new one starts.\n * @returns A Promise that resolves when the transition finishes.\n */\n morphTo(target: CurveDef, opts?: MorphOptions): Promise<void> {\n if (morphResolve !== null) {\n completeMorphNow();\n }\n\n morphDurationMs = opts?.duration ?? DEFAULT_MORPH_DURATION_MS;\n morphProgress = 0;\n engine.startMorph(target, opts?.morphStrategy);\n\n return new Promise<void>((resolve, reject) => {\n morphResolve = resolve;\n morphReject = reject;\n });\n },\n\n /**\n * Updates render options on a live instance without stopping the animation.\n *\n * Supported: `trailColor`, `trailStyle`, and `skeletonColor`.\n * ! Unsupported fields (`headColor`, `headRadius`, `trailWidth`) throw.\n * ! Validation fails the entire call if any field is invalid, leaving options unchanged.\n */\n setRenderOptions(partial: DotMatrixRuntimeRenderOptions): void {\n validateBaseRenderOptions(partial);\n\n let needsRebuildBg = false;\n\n if (partial.trailColor !== undefined) {\n trailColor = partial.trailColor;\n applyColor(trailColor);\n needsRebuildBg = true;\n }\n\n if (partial.skeletonColor !== undefined) {\n applySkeletonColor(partial.skeletonColor);\n }\n\n if (partial.trailStyle !== undefined) {\n trailStyle = partial.trailStyle;\n if (trailStyle === \"default\") {\n gradientAnimTime = 0;\n }\n }\n\n if (needsRebuildBg) {\n buildBgImageData();\n }\n\n if (partial.trailColor !== undefined || partial.trailStyle !== undefined) {\n warnIfTrailColorMismatch(trailColor, trailStyle);\n }\n },\n };\n\n // ── Visibility handling ──────────────────────────────────────────────────────\n\n function handleVisibilityChange() {\n if (document.hidden) {\n if (animationId !== null) {\n instance.pause();\n pausedByVisibility = true;\n }\n } else {\n if (pausedByVisibility) {\n pausedByVisibility = false;\n instance.play();\n }\n }\n }\n\n if (pauseOnHiddenOpt) {\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n }\n\n const shouldAutoStart = autoStart !== false;\n // Skip auto-start if the tab is already hidden. The visibilitychange listener will resume it\n const actuallyAutoStart = shouldAutoStart && !(pauseOnHiddenOpt && document.hidden);\n\n if (actuallyAutoStart) {\n instance.play();\n } else if (shouldAutoStart) {\n pausedByVisibility = true;\n }\n\n return instance;\n}\n","import type { ControlPoint, Point, CurveDef } from \"./types\";\n\n/**\n * One full loop around the spline maps to the parametric interval `[0, 2π)`,\n * matching the convention for built-in curves.\n */\nconst PERIOD = 2 * Math.PI;\n\n/**\n * Evaluates a one-dimensional Catmull-Rom spline segment given four control values.\n * The parameter `u` ranges from 0 (at `p1`) to 1 (at `p2`).\n * `p0` and `p3` are the phantom neighbours that influence the tangent at each endpoint.\n */\nfunction catmullRom1D(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const u2 = u * u;\n const u3 = u2 * u;\n\n // The standard Catmull-Rom matrix form\n return (\n 0.5 *\n (2 * p1 +\n (-p0 + p2) * u +\n (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 +\n (-p0 + 3 * p1 - 3 * p2 + p3) * u3)\n );\n}\n\n/**\n * Evaluates a closed Catmull-Rom spline through every point in `points`\n *\n * The spline treats `points` as a **closed loop**\n * The last point wraps back to the first,\n * and each segment uses a phantom predecessor / successor so the\n * curve passes exactly through every control point.\n *\n * @param points At least 1 point. An empty array yields `(0, 0)`. A single point returns that point for every `phase`\n * @param phase Parametric position along the closed loop. Wraps into `[0, 2π)` automatically, so values outside that range are remapped rather than rejected\n * @returns The `(x, y)` position on the spline at position `phase`\n */\nexport function evaluateCatmullRom(points: Array<ControlPoint>, phase: number): Point {\n const N = points.length;\n\n if (N === 0) {\n return { x: 0, y: 0 };\n }\n\n if (N === 1) {\n return { x: points[0]![0], y: points[0]![1] };\n }\n\n phase = ((phase % PERIOD) + PERIOD) % PERIOD;\n\n const segmentSize = PERIOD / N;\n let i = Math.floor(phase / segmentSize);\n if (i >= N) {\n i = N - 1;\n }\n\n let u = (phase - i * segmentSize) / segmentSize;\n u = Math.max(0, Math.min(1, u));\n\n const p0 = points[(i - 1 + N) % N]!;\n const p1 = points[i]!;\n const p2 = points[(i + 1) % N]!;\n const p3 = points[(i + 2) % N]!;\n\n return {\n x: catmullRom1D(p0[0], p1[0], p2[0], p3[0], u),\n y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u),\n };\n}\n\n/**\n * The returned curve definition produces a closed Catmull-Rom spline that\n * passes through every point in order, looping back from the last point to the first.\n *\n * @param points Array of control points in **normalized `[−1, 1]` space**,\n * matching the playground's draw-mode coordinate system.\n * ! Must contain at least 3 points.\n * @param opts Optional overrides for the returned `CurveDef`.\n * @param opts.name Display name for the curve. Defaults to `\"drawn\"`.\n * @returns A `CurveDef` with `period: 2π` and the spline evaluator as its `fn`.\n * @throws If `points` has fewer than 3 entries.\n *\n * @example\n * ```ts\n * import { createSarmal, drawCurve } from '@sarmal/core'\n *\n * const curve = drawCurve([\n * [-0.5, 0.3],\n * [ 0.2, -0.8],\n * [ 0.7, 0.4],\n * ])\n *\n * createSarmal(canvas, curve)\n * ```\n */\nexport function drawCurve(points: Array<ControlPoint>, opts?: { name?: string }): CurveDef {\n if (points.length < 3) {\n throw new Error(`drawCurve requires at least 3 points, received ${points.length}.`);\n }\n\n const first = points[0]!;\n if (points.every((p) => p[0] === first[0] && p[1] === first[1])) {\n console.warn(\n \"[sarmal].drawCurve: all control points are identical. The curve will be a single point.\",\n );\n }\n\n const maxAbs = points.reduce((m, p) => Math.max(m, Math.abs(p[0]), Math.abs(p[1])), 0);\n if (maxAbs > 2) {\n console.warn(\n `[sarmal].drawCurve: control points extend to ±${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1].`,\n );\n }\n\n const pts = points.map(([x, y]) => [x, y] as ControlPoint);\n\n return {\n name: opts?.name ?? \"drawn\",\n fn: (phase: number) => evaluateCatmullRom(pts, phase),\n period: PERIOD,\n };\n}\n","import type { ControlPoint, CurveDef } from \"../types\";\n\nimport { drawCurve } from \"../catmull-rom\";\n\nconst points: Array<ControlPoint> = [\n [-0.44, -0.45],\n [-0.53, -0.77],\n [-0.82, -0.66],\n [-0.82, -0.18],\n [-0.25, -0.04],\n [0.16, -0.49],\n [-0.03, -0.87],\n [-0.68, -0.94],\n [-0.95, -0.61],\n [-0.87, -0.0],\n [-0.34, 0.21],\n [0.27, -0.04],\n [0.87, 0.06],\n [0.87, 0.57],\n [0.32, 0.66],\n [-0.21, -0.43],\n [-0.43, -0.81],\n [-0.69, -0.84],\n [-0.87, -0.66],\n [-0.9, -0.47],\n [-0.76, -0.35],\n];\n\nexport const artemis2: CurveDef = {\n ...drawCurve(points, { name: \"Artemis II\" }),\n speed: 0.7,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction astroidFn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const c = Math.cos(phase);\n const s = Math.sin(phase);\n return {\n x: c * c * c,\n y: s * s * s,\n };\n}\n\n/**\n * Astroid curve - a 4-cusped hypocycloid\n * Creates a star-like shape with four sharp corners\n */\nexport const astroid: CurveDef = {\n name: \"Astroid\",\n fn: astroidFn,\n period: TWO_PI,\n speed: 1.1,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction deltoidFn(phase: number, _elapsed: number, _params: Record<string, number>) {\n return {\n x: 2 * Math.cos(phase) + Math.cos(2 * phase),\n y: 2 * Math.sin(phase) - Math.sin(2 * phase),\n };\n}\n\n/**\n * Deltoid curve - a 3-cusped hypocycloid\n * Creates a triangular shape with curved sides\n */\nexport const deltoid: CurveDef = {\n name: \"Deltoid\",\n fn: deltoidFn,\n period: TWO_PI,\n speed: 0.9,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction epicycloid3Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n return {\n x: 4 * Math.cos(phase) - Math.cos(4 * phase),\n y: 4 * Math.sin(phase) - Math.sin(4 * phase),\n };\n}\n\n/**\n * Epicycloid with 3 cusps\n * Creates a three-pointed star shape\n */\nexport const epicycloid3: CurveDef = {\n name: \"Epicycloid (n=3)\",\n fn: epicycloid3Fn,\n period: TWO_PI,\n speed: 0.75,\n};\n","import type { CurveDef, Point } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction epitrochoid7Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const d = 1.0 + 0.55 * Math.sin(phase * 0.5);\n return {\n x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),\n y: 7 * Math.sin(phase) - d * Math.sin(7 * phase),\n };\n}\n\nfunction epitrochoid7SkeletonFn(phase: number): Point {\n // average of the oscillating range for a stable base shape\n const d = 1.275;\n return {\n x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),\n y: 7 * Math.sin(phase) - d * Math.sin(7 * phase),\n };\n}\n\n/**\n * Epitrochoid with 7 lobes and dynamic variation\n * Creates a flower-like pattern with undulating petals\n */\nexport const epitrochoid7: CurveDef = {\n name: \"Epitrochoid\",\n fn: epitrochoid7Fn,\n period: TWO_PI,\n speed: 1.4,\n skeletonFn: epitrochoid7SkeletonFn,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction lissajous32Fn(phase: number, elapsed: number, _params: Record<string, number>) {\n const phi = elapsed * 0.45;\n return {\n x: Math.sin(3 * phase + phi),\n y: Math.sin(2 * phase),\n };\n}\n\n/**\n * Lissajous curve with frequency ratio 3:2\n * Creates a figure-eight-like pattern with live skeleton\n */\nexport const lissajous32: CurveDef = {\n name: \"Lissajous 3:2\",\n fn: lissajous32Fn,\n period: TWO_PI,\n speed: 2.0,\n skeleton: \"live\",\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction lissajous43Fn(phase: number, elapsed: number, _params: Record<string, number>) {\n const phi = elapsed * 0.38;\n return {\n x: Math.sin(4 * phase + phi),\n y: Math.sin(3 * phase),\n };\n}\n\n/**\n * Lissajous curve with frequency ratio 4:3\n * Creates a complex interweaving pattern with live skeleton\n */\nexport const lissajous43: CurveDef = {\n name: \"Lissajous 4:3\",\n fn: lissajous43Fn,\n period: TWO_PI,\n speed: 1.8,\n skeleton: \"live\",\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction lameFn(phase: number, elapsed: number, _params: Record<string, number>) {\n const p = 1.75 + 1.25 * Math.sin(elapsed * 0.48);\n const c = Math.cos(phase),\n s = Math.sin(phase);\n return {\n x: Math.sign(c) * Math.pow(Math.abs(c), p),\n y: Math.sign(s) * Math.pow(Math.abs(s), p),\n };\n}\n\n/**\n * Lamé curve (superellipse) with time-varying exponent\n * Creates a squircle-like shape that morphs over time\n */\nexport const lame: CurveDef = {\n name: \"Lamé Curve\",\n fn: lameFn,\n period: TWO_PI,\n speed: 1.0,\n skeleton: \"live\",\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction rose3Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r = Math.cos(3 * phase);\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * Rose curve with 3 petals\n * Creates a three-petaled flower pattern\n */\nexport const rose3: CurveDef = {\n name: \"Rose (n=3)\",\n fn: rose3Fn,\n period: TWO_PI,\n speed: 1.15,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction rose5Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r = Math.cos(5 * phase);\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * Rose curve with 5 petals\n * Creates a five-petaled flower pattern\n */\nexport const rose5: CurveDef = {\n name: \"Rose (n=5)\",\n fn: rose5Fn,\n period: TWO_PI,\n speed: 1.0,\n};\n","import type { CurveDef } from \"../types\";\n\nconst FOUR_PI = Math.PI * 4;\n\nfunction rose52Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r = Math.cos((5 / 2) * phase);\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * Rose curve with n=5/2 that traces 5 petals over two full revolutions\n * The head passes through the center between petals, creating elegant crossing trails.\n */\nexport const rose52: CurveDef = {\n name: \"Rose (n=5/2)\",\n fn: rose52Fn,\n period: FOUR_PI,\n speed: 0.8,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction starFn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r =\n Math.abs(Math.cos((5 / 2) * phase)) +\n 0.35 * Math.abs(Math.cos((15 / 2) * phase)) +\n 0.15 * Math.abs(Math.cos((25 / 2) * phase));\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * 5-pointed star based on Fourier harmonics.\n */\nexport const star: CurveDef = {\n name: \"Star\",\n fn: starFn,\n period: TWO_PI,\n speed: 1.0,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction star4Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r =\n Math.abs(Math.cos(2 * phase)) +\n 0.35 * Math.abs(Math.cos(6 * phase)) +\n 0.15 * Math.abs(Math.cos(10 * phase));\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * 4-pointed star based on Fourier harmonics.\n * Same construction as `star` but with base frequency `2*phase`, producing 4 tips.\n */\nexport const star4: CurveDef = {\n name: \"Star (4-arm)\",\n fn: star4Fn,\n period: TWO_PI,\n speed: 1.0,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction star7Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r =\n Math.abs(Math.cos((7 / 2) * phase)) +\n 0.35 * Math.abs(Math.cos((21 / 2) * phase)) +\n 0.15 * Math.abs(Math.cos((35 / 2) * phase));\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * 7-pointed star based on Fourier harmonics.\n * Same construction as `star` but with base frequency `7*phase/2`, producing 7 tips.\n */\nexport const star7: CurveDef = {\n name: \"Star (7-arm)\",\n fn: star7Fn,\n period: TWO_PI,\n speed: 1.0,\n};\n","// Individual curve exports for tree-shaking\nexport { artemis2 } from \"./artemis2\";\nexport { astroid } from \"./astroid\";\nexport { deltoid } from \"./deltoid\";\nexport { epicycloid3 } from \"./epicycloid3\";\nexport { epitrochoid7 } from \"./epitrochoid7\";\nexport { lissajous32 } from \"./lissajous32\";\nexport { lissajous43 } from \"./lissajous43\";\nexport { lame } from \"./lame\";\nexport { rose3 } from \"./rose3\";\nexport { rose5 } from \"./rose5\";\nexport { rose52 } from \"./rose52\";\nexport { star } from \"./star\";\nexport { star4 } from \"./star4\";\nexport { star7 } from \"./star7\";\n\n// Bulk export for convenience\n// >> Standard\nimport { rose3 } from \"./rose3\";\nimport { rose5 } from \"./rose5\";\nimport { rose52 } from \"./rose52\";\nimport { star } from \"./star\";\nimport { star4 } from \"./star4\";\nimport { star7 } from \"./star7\";\nimport { astroid } from \"./astroid\";\nimport { deltoid } from \"./deltoid\";\nimport { epicycloid3 } from \"./epicycloid3\";\nimport { epitrochoid7 } from \"./epitrochoid7\";\nimport { lissajous32 } from \"./lissajous32\";\nimport { lissajous43 } from \"./lissajous43\";\nimport { lame } from \"./lame\";\n// >> Iconic\nimport { artemis2 } from \"./artemis2\";\n\n/**\n * Collection of all built-in sarmal curves\n * Import individual curves for better tree-shaking\n */\nexport const curves = {\n artemis2,\n epitrochoid7,\n astroid,\n deltoid,\n rose3,\n rose5,\n rose52,\n star,\n star4,\n star7,\n lissajous32,\n lissajous43,\n epicycloid3,\n lame,\n} as const;\nexport type CurveName = keyof typeof curves;\n","import type { CurveDef, SarmalInstance, SarmalOptions } from \"./types\";\nexport type { SVGRendererOptions, SVGSarmalOptions } from \"./renderer-svg\";\nexport type {\n BaseRendererOptions,\n BaseRuntimeRenderOptions,\n Point,\n CurveDef,\n Engine,\n SarmalInstance,\n JumpOptions,\n SeekOptions,\n RendererOptions,\n SarmalOptions,\n TrailStyle,\n TrailColor,\n MorphStrategy,\n RuntimeRenderOptions,\n DotMatrixRuntimeRenderOptions,\n} from \"./types\";\nexport type { CurveName } from \"./curves\";\nexport type { SarmalPalette, BoundaryResult } from \"./renderer-shared\";\nexport type { DotMatrixSarmalOptions } from \"./renderer-dot-matrix\";\n\nexport { createEngine } from \"./engine\";\nexport { createRenderer } from \"./renderer\";\nexport { createSVGRenderer, createSarmalSVG } from \"./renderer-svg\";\nexport { createSarmalDotMatrix } from \"./renderer-dot-matrix\";\nexport { curves } from \"./curves\";\nexport { palettes, computeBoundaries } from \"./renderer-shared\";\nexport { drawCurve, evaluateCatmullRom } from \"./catmull-rom\";\nexport {\n artemis2,\n epitrochoid7,\n astroid,\n deltoid,\n rose5,\n rose3,\n lissajous32,\n lissajous43,\n epicycloid3,\n lame,\n} from \"./curves\";\n\nimport { createEngine } from \"./engine\";\nimport { createRenderer } from \"./renderer\";\n\n/**\n * Creates a sarmal animation on a canvas element\n *\n * @example\n * ```ts\n * import { createSarmal, rose3 } from '@sarmal/core'\n * const sarmal = createSarmal(canvas, rose3)\n *\n * // To control manually, use autoStart: false\n * const controlled = createSarmal(canvas, rose3, { autoStart: false })\n * controlled.play() // Start when ready\n * controlled.pause() // Pause later\n * ```\n */\nexport function createSarmal(\n canvas: HTMLCanvasElement,\n curveDef: CurveDef,\n options?: SarmalOptions,\n): SarmalInstance {\n const { trailLength, ...rendererOpts } = options ?? {};\n const engine = createEngine(curveDef, trailLength);\n\n return createRenderer({ canvas, engine, ...rendererOpts });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/engine.ts","../src/renderer-shared.ts","../src/renderer.ts","../src/renderer-svg.ts","../src/renderer-dot-matrix.ts","../src/catmull-rom.ts","../src/curves/artemis2.ts","../src/curves/astroid.ts","../src/curves/deltoid.ts","../src/curves/epicycloid3.ts","../src/curves/epitrochoid7.ts","../src/curves/lissajous32.ts","../src/curves/lissajous43.ts","../src/curves/lame.ts","../src/curves/rose3.ts","../src/curves/rose5.ts","../src/curves/rose52.ts","../src/curves/star.ts","../src/curves/star4.ts","../src/curves/star7.ts","../src/curves/index.ts","../src/index.ts"],"names":["points","dx","dy","len","options","EMPTY_PARAMS","skeleton","TWO_PI"],"mappings":"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","file":"index.js","sourcesContent":["import type { CurveDef, Engine, JumpOptions, MorphStrategy, Point, SeekOptions } from \"./types\";\n\nconst TWO_PI = Math.PI * 2;\nconst POINTS_PER_PERIOD_UNIT = 50;\n\ntype SpeedTransition = {\n from: number;\n to: number;\n elapsed: number;\n duration: number;\n resolve: () => void;\n reject: (err: Error) => void;\n};\n\n/** Linearly interpolate from start to end by factor t (0→1) */\nfunction lerp(start: number, end: number, t: number): number {\n return start + (end - start) * t;\n}\n\n/** Reused across all curve fn calls but params is never populated, allocation is wasteful */\nconst EMPTY_PARAMS: Record<string, number> = {};\n\n/**\n * A fixed-size list of points with first in, last out method\n * The oldest entry is automatically discarded when the list is at capacity\n *\n * Note: `result.length` is *never* changed,\n * so callers use the separate `count` getter to know valid size\n */\nclass CircularBuffer {\n private data: Array<Point>;\n private result: Array<Point>;\n private capacity: number;\n private head: number = 0;\n private count: number = 0;\n\n constructor(capacity: number) {\n this.capacity = capacity;\n this.data = Array.from({ length: capacity }, () => ({ x: 0, y: 0 }));\n this.result = Array.from({ length: capacity }, () => ({ x: 0, y: 0 }));\n }\n\n /** Mutates in-place */\n push(x: number, y: number): void {\n const slot = this.data[this.head]!;\n\n slot.x = x;\n slot.y = y;\n this.head = (this.head + 1) % this.capacity;\n\n if (this.count < this.capacity) {\n this.count++;\n }\n }\n\n /**\n * Copies ordered points into the pre-allocated result buffer and returns it\n * Note: The *same* array reference is returned every call,\n * so `result.length` is also always `capacity`\n */\n toArray(): Array<Point> {\n const start = this.count < this.capacity ? 0 : this.head;\n\n for (let i = 0; i < this.count; i++) {\n const src = this.data[(start + i) % this.capacity]!;\n const dst = this.result[i]!;\n dst.x = src.x;\n dst.y = src.y;\n }\n\n return this.result;\n }\n\n clear(): void {\n this.head = 0;\n this.count = 0;\n }\n\n get length() {\n return this.count;\n }\n}\n\n/**\n * Creates the core simulation engine for a sarmal\n *\n * it runs a clock (`phase`), asks the curve for the current Point position at that time,\n * and remembers the last N positions so the renderer can draw the trail\n *\n * The engine is only responsible for math coordinates,\n * so it is not responsible for drawing or colors\n *\n * @param curveDef A curve definition\n * @param trailLength default: `120`\n */\n/** Normalised resolution of a CurveDef, with required fields filled in */\ntype ResolvedCurve = {\n name: string;\n fn: CurveDef[\"fn\"];\n period: number;\n speed: number;\n skeleton?: CurveDef[\"skeleton\"];\n skeletonFn?: CurveDef[\"skeletonFn\"];\n};\n\nfunction resolveCurve(curveDef: CurveDef): ResolvedCurve {\n const period = curveDef.period ?? TWO_PI;\n\n if (!Number.isFinite(period) || period <= 0) {\n throw new RangeError(`[sarmal] period must be a positive finite number, got ${period}`);\n }\n\n const speed = curveDef.speed ?? 1;\n\n if (!Number.isFinite(speed)) {\n throw new RangeError(`[sarmal] speed must be a finite number, got ${speed}`);\n }\n\n return {\n name: curveDef.name,\n fn: curveDef.fn,\n period,\n speed,\n skeleton: curveDef.skeleton,\n skeletonFn: curveDef.skeletonFn,\n };\n}\n\nexport function createEngine(curveDef: CurveDef, trailLength: number = 120): Engine {\n if (!Number.isFinite(trailLength) || trailLength <= 0) {\n throw new RangeError(\n `[sarmal] trailLength must be a positive finite number, got ${trailLength}`,\n );\n }\n\n let curve = resolveCurve(curveDef);\n const trail = new CircularBuffer(trailLength);\n let phase = 0;\n let actualTime = 0;\n let userSpeedOverride: number | null = null;\n\n // Morph state which is `null` when not morphing\n let morphCurveB: ResolvedCurve | null = null;\n let _morphAlpha: number | null = null;\n let _morphStrategy: MorphStrategy = \"normalized\";\n\n // Speed transition state which is `null` when not transitioning\n let _speedTransition: SpeedTransition | null = null;\n\n /** Samples a resolved curve's skeleton at position `samplePhase` */\n function sampleSkeleton(c: ResolvedCurve, samplePhase: number): Point {\n if (c.skeletonFn) {\n return c.skeletonFn(samplePhase);\n }\n\n if (c.skeleton === \"live\") {\n return c.fn(samplePhase, actualTime, EMPTY_PARAMS);\n }\n\n return c.fn(samplePhase, 0, EMPTY_PARAMS);\n }\n\n return {\n tick(deltaTime: number): Array<Point> {\n if (_speedTransition !== null) {\n // tick() receives dt in seconds, but SpeedTransition.duration is in milliseconds.\n // Convert dt to ms so the elapsed/duration ratio is dimensionless.\n _speedTransition.elapsed += deltaTime * 1000;\n const alpha = Math.min(_speedTransition.elapsed / _speedTransition.duration, 1);\n userSpeedOverride = lerp(_speedTransition.from, _speedTransition.to, alpha);\n if (alpha >= 1) {\n userSpeedOverride = _speedTransition.to;\n _speedTransition.resolve();\n _speedTransition = null;\n }\n }\n\n let effectiveSpeed = userSpeedOverride ?? curve.speed;\n if (morphCurveB !== null && _morphAlpha !== null) {\n effectiveSpeed = lerp(effectiveSpeed, morphCurveB.speed, _morphAlpha);\n }\n phase = (phase + effectiveSpeed * deltaTime) % curve.period;\n actualTime += deltaTime;\n\n if (morphCurveB !== null && _morphAlpha !== null) {\n const a = curve.fn(phase, actualTime, EMPTY_PARAMS);\n const phaseB =\n _morphStrategy === \"normalized\" ? (phase / curve.period) * morphCurveB.period : phase;\n const b = morphCurveB.fn(phaseB, actualTime, EMPTY_PARAMS);\n trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);\n } else {\n const point = curve.fn(phase, actualTime, EMPTY_PARAMS);\n trail.push(point.x, point.y);\n }\n\n return trail.toArray();\n },\n\n get trailCount() {\n return trail.length;\n },\n\n get trailLength() {\n return trailLength;\n },\n\n get isLiveSkeleton() {\n return curve.skeleton === \"live\";\n },\n\n get morphAlpha() {\n return _morphAlpha;\n },\n\n reset() {\n phase = 0;\n actualTime = 0;\n trail.clear();\n },\n\n jump(newPhase: number, { clearTrail = false }: JumpOptions = {}) {\n phase = ((newPhase % curve.period) + curve.period) % curve.period;\n\n if (clearTrail) {\n trail.clear();\n }\n },\n\n seek(\n targetPhase: number,\n { wrap = false, step = curve.period / trailLength }: SeekOptions = {},\n ) {\n const advance = curve.speed * step;\n const target = ((targetPhase % curve.period) + curve.period) % curve.period;\n const targetTime = target / curve.speed;\n\n phase = target;\n actualTime = targetTime;\n trail.clear();\n\n const pointsFromStart = Math.floor(target / advance) + 1;\n const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);\n\n for (let i = count - 1; i >= 0; i--) {\n const samplePhase = target - i * advance;\n const wrappedPhase = ((samplePhase % curve.period) + curve.period) % curve.period;\n const elapsed = targetTime - i * step;\n const point = curve.fn(wrappedPhase, elapsed, EMPTY_PARAMS);\n\n trail.push(point.x, point.y);\n }\n },\n\n startMorph(target: CurveDef, strategy: MorphStrategy = \"normalized\") {\n const resolvedTarget = resolveCurve(target);\n\n if (morphCurveB !== null && _morphAlpha !== null) {\n const frozenAlpha = _morphAlpha;\n const frozenA = curve;\n const frozenB = morphCurveB;\n const frozenStrategy = _morphStrategy;\n\n curve = {\n ...frozenB,\n fn: (samplePhase: number, elapsed: number, params: Record<string, number>) => {\n const a = frozenA.fn(samplePhase, elapsed, params);\n const phaseB =\n frozenStrategy === \"normalized\"\n ? (samplePhase / frozenA.period) * frozenB.period\n : samplePhase;\n const b = frozenB.fn(phaseB, elapsed, params);\n\n return {\n x: a.x + (b.x - a.x) * frozenAlpha,\n y: a.y + (b.y - a.y) * frozenAlpha,\n };\n },\n };\n }\n\n _morphStrategy = strategy;\n morphCurveB = resolvedTarget;\n _morphAlpha = 0;\n },\n\n setMorphAlpha(alpha: number) {\n _morphAlpha = alpha;\n },\n\n completeMorph() {\n if (morphCurveB !== null) {\n // Normalized strategy drives `curveB` at `phaseB` = `(phase / periodA) * periodB`\n // Remap `phase` so the trail continues from the same position on `curveB`,\n // not from a raw `phase` value that belongs to `curveA`'s smaller range.\n if (_morphStrategy === \"normalized\" && curve.period !== morphCurveB.period) {\n phase = (phase / curve.period) * morphCurveB.period;\n }\n curve = morphCurveB;\n }\n morphCurveB = null;\n _morphAlpha = null;\n },\n\n getSarmalSkeleton(): Array<Point> {\n const steps = Math.ceil(curve.period * POINTS_PER_PERIOD_UNIT);\n // oxlint-disable-next-line unicorn/no-new-array -- array is pre-allocated, filled immediately below\n const points: Array<Point> = new Array(steps);\n\n if (morphCurveB !== null && _morphAlpha !== null) {\n for (let i = 0; i < steps; i++) {\n const samplePhase = (i / (steps - 1)) * curve.period;\n const a = sampleSkeleton(curve, samplePhase);\n const phaseB =\n _morphStrategy === \"normalized\"\n ? (samplePhase / curve.period) * morphCurveB.period\n : samplePhase;\n const b = sampleSkeleton(morphCurveB, phaseB);\n\n points[i] = {\n x: a.x + (b.x - a.x) * _morphAlpha,\n y: a.y + (b.y - a.y) * _morphAlpha,\n };\n }\n return points;\n }\n\n for (let i = 0; i < steps; i++) {\n const samplePhase = (i / (steps - 1)) * curve.period;\n points[i] = sampleSkeleton(curve, samplePhase);\n }\n\n return points;\n },\n\n setSpeed(speed: number): void {\n if (!Number.isFinite(speed)) {\n throw new Error(\"speed must be a finite number\");\n }\n if (_speedTransition !== null) {\n _speedTransition.reject(new Error(\"Speed transition cancelled\"));\n _speedTransition = null;\n }\n userSpeedOverride = speed;\n },\n\n getSpeed(): number {\n return userSpeedOverride ?? curve.speed;\n },\n\n resetSpeed(): void {\n userSpeedOverride = null;\n },\n\n setSpeedOver(speed: number, duration: number): Promise<void> {\n if (!Number.isFinite(speed)) {\n throw new Error(\"speed must be a finite number\");\n }\n if (!Number.isFinite(duration) || duration <= 0) {\n throw new Error(\"duration must be a finite number greater than 0\");\n }\n\n if (_speedTransition !== null) {\n _speedTransition.reject(new Error(\"Speed transition cancelled\"));\n _speedTransition = null;\n }\n\n const from = userSpeedOverride ?? curve.speed;\n\n return new Promise<void>((resolve, reject) => {\n _speedTransition = { from, to: speed, elapsed: 0, duration, resolve, reject };\n });\n },\n\n cancelSpeedTransition(): void {\n if (_speedTransition !== null) {\n _speedTransition.reject(new Error(\"Speed transition cancelled\"));\n _speedTransition = null;\n }\n },\n };\n}\n","import type {\n BaseRuntimeRenderOptions,\n Engine,\n Point,\n RuntimeRenderOptions,\n TrailColor,\n TrailStyle,\n} from \"./types\";\n\nexport const DEFAULT_MORPH_DURATION_MS = 300;\nexport const DEFAULT_SKELETON_OPACITY = 0.15;\n/** Fraction of the bounding-box dimension added as proportional padding on each side when fitting the curve. */\nexport const FIT_PADDING = 0.1;\nexport const FIT_PADDING_MIN = 4;\n/** Higher values = sharper fade near the tail, more of the trail appears faint */\nexport const TRAIL_FADE_CURVE = 1.5;\nexport const TRAIL_MAX_OPACITY = 0.88;\n/** Pixel-space stroke/line width at the tail which the SVG renderer overrides with viewBox unit values */\nexport const TRAIL_MIN_WIDTH = 0.5;\n/** Pixel-space stroke/line width at the head which the SVG renderer overrides with viewBox unit values */\nexport const TRAIL_MAX_WIDTH = 2.5;\n\nexport interface TrailPoint {\n x: number;\n y: number;\n}\n\n/**\n * Computes the unit tangent vector at a point on the trail.\n * - Interior points: central difference (previous -> next)\n * - Endpoints: forward/backward difference\n */\nexport function computeTangent(trail: TrailPoint[], i: number): TrailPoint {\n const count = trail.length;\n if (count < 2) {\n return { x: 1, y: 0 };\n }\n\n if (i === 0) {\n const dx = trail[1]!.x - trail[0]!.x;\n const dy = trail[1]!.y - trail[0]!.y;\n const len = Math.sqrt(dx * dx + dy * dy) || 1;\n return { x: dx / len, y: dy / len };\n }\n\n if (i === count - 1) {\n const dx = trail[count - 1]!.x - trail[count - 2]!.x;\n const dy = trail[count - 1]!.y - trail[count - 2]!.y;\n const len = Math.sqrt(dx * dx + dy * dy) || 1;\n return { x: dx / len, y: dy / len };\n }\n\n const dx = trail[i + 1]!.x - trail[i - 1]!.x;\n const dy = trail[i + 1]!.y - trail[i - 1]!.y;\n const len = Math.sqrt(dx * dx + dy * dy) || 1;\n return { x: dx / len, y: dy / len };\n}\n\n/**\n * Computes the unit normal vector at a point on the trail.\n * The normal is perpendicular to the tangent, rotated 90° counter-clockwise\n */\nexport function computeNormal(trail: TrailPoint[], i: number): TrailPoint {\n const tangent = computeTangent(trail, i);\n return { x: -tangent.y, y: tangent.x };\n}\n\n/** The four pixel-space corners and per-segment style values for one ribbon quad */\nexport interface TrailQuad {\n /** Left corner at the tail end of this segment */\n l0x: number;\n l0y: number;\n /** Right corner at the tail end of this segment */\n r0x: number;\n r0y: number;\n /** Left corner at the head end of this segment */\n l1x: number;\n l1y: number;\n /** Right corner at the head end of this segment */\n r1x: number;\n r1y: number;\n /** Fill opacity for this segment (0–1) */\n opacity: number;\n /** Position along the trail (0 = tail, 1 = head) */\n progress: number;\n}\n\n/**\n * Computes the quad corners and style for one ribbon segment in the renderer's coordinate space (pixel-space for canvas, viewBox-space for SVG)\n *\n * @param trail Full trail array\n * @param i Segment index (draws from point i to point i+1)\n * @param trailCount Number of active trail points\n * @param toX Convert a trail point to its pixel X coordinate\n * @param toY Convert a trail point to its pixel Y coordinate\n *\n * @see https://mattdesl.svbtle.com/drawing-lines-is-hard\n * DesLauriers: \"Triangulated Lines\" - expand points outward by half\n * the thickness on either side using normals to create thick lines.\n */\nexport function computeTrailQuad(\n trail: TrailPoint[],\n i: number,\n trailCount: number,\n toX: (p: TrailPoint) => number,\n toY: (p: TrailPoint) => number,\n minWidth = TRAIL_MIN_WIDTH,\n maxWidth = TRAIL_MAX_WIDTH,\n): TrailQuad {\n const progress = i / (trailCount - 1);\n const nextProgress = (i + 1) / (trailCount - 1);\n const opacity = Math.pow(progress, TRAIL_FADE_CURVE) * TRAIL_MAX_OPACITY;\n const w0 = (minWidth + progress * (maxWidth - minWidth)) / 2;\n const w1 = (minWidth + nextProgress * (maxWidth - minWidth)) / 2;\n\n const curr = trail[i]!;\n const next = trail[i + 1]!;\n const n0 = computeNormal(trail, i);\n const n1 = computeNormal(trail, i + 1);\n\n const cx = toX(curr);\n const cy = toY(curr);\n const nx = toX(next);\n const ny = toY(next);\n\n return {\n l0x: cx + n0.x * w0,\n l0y: cy + n0.y * w0,\n r0x: cx - n0.x * w0,\n r0y: cy - n0.y * w0,\n l1x: nx + n1.x * w1,\n l1y: ny + n1.y * w1,\n r1x: nx - n1.x * w1,\n r1y: ny - n1.y * w1,\n opacity,\n progress,\n };\n}\n\nexport interface BoundaryResult {\n scale: number;\n offsetX: number;\n offsetY: number;\n}\n\n/**\n * Computes how to map engine coordinates into a viewport of the given logical size.\n * ! Returns `null` if `pts` is empty\n * ! Throws if all points are identical\n *\n * Padding per side is `max(FIT_PADDING * dim, minPaddingPx)`, so the stricter constraint wins.\n * `minPaddingPx` defaults to `FIT_PADDING_MIN` (4px) for pixel-space callers.\n * Pass `0` when the logical space is itself a normalized viewBox (e.g. SVG export).\n */\nexport function computeBoundaries(\n pts: Point[],\n logicalWidth: number,\n logicalHeight: number,\n minPaddingPx = FIT_PADDING_MIN,\n): BoundaryResult | null {\n if (pts.length === 0) {\n return null;\n }\n\n const first = pts[0]!;\n let minX = first.x,\n maxX = first.x,\n minY = first.y,\n maxY = first.y;\n\n for (const p of pts) {\n if (p.x < minX) {\n minX = p.x;\n }\n if (p.x > maxX) {\n maxX = p.x;\n }\n if (p.y < minY) {\n minY = p.y;\n }\n if (p.y > maxY) {\n maxY = p.y;\n }\n }\n\n const w = maxX - minX;\n const h = maxY - minY;\n\n if (w === 0 && h === 0) {\n throw new Error(\n \"[sarmal] Degenerate curve: all skeleton points are identical. \" +\n \"Check that your curve fn returns distinct points for different values of t.\",\n );\n }\n\n const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));\n const scaleYProportional = logicalHeight / (h * (1 + FIT_PADDING * 2));\n\n const scaleXMinPadding = (logicalWidth - minPaddingPx * 2) / w;\n const scaleYMinPadding = (logicalHeight - minPaddingPx * 2) / h;\n\n const scale = Math.min(\n scaleXProportional,\n scaleYProportional,\n scaleXMinPadding,\n scaleYMinPadding,\n );\n\n return {\n scale,\n offsetX: (logicalWidth - w * scale) / 2 - minX * scale,\n offsetY: (logicalHeight - h * scale) / 2 - minY * scale,\n };\n}\n\n/**\n * Returns the engine methods that are pure pass-throughs on both renderers\n * The engine does not use `this`, so direct assignment is safe\n */\nexport function enginePassthroughs(engine: Engine) {\n return {\n jump: engine.jump,\n seek: engine.seek,\n setSpeed: engine.setSpeed,\n getSpeed: engine.getSpeed,\n resetSpeed: engine.resetSpeed,\n setSpeedOver: engine.setSpeedOver,\n getSarmalSkeleton: engine.getSarmalSkeleton,\n };\n}\n\n/**\n * Can be passed directly to `trailColor`,\n * or can be mixed/sliced before passing as a prop.\n */\nexport const palettes = {\n bard: [\"#a855f7\", \"#3b82f6\", \"#14b8a6\", \"#ec4899\"],\n carnival: [\"#ff6b6b\", \"#4ecdc4\", \"#ffe66d\"],\n ocean: [\"#1e3a8a\", \"#06b6d4\", \"#22d3ee\", \"#e0f2fe\"],\n sunset: [\"#f97316\", \"#dc2626\", \"#9333ea\", \"#f472b6\"],\n ice: [\"#1e3a8a\", \"#67e8f9\"],\n rocketpop: [\"#08b8cd\", \"#ffffff\", \"#ff001f\"],\n neon: [\"#00e5ff\", \"#7c3aed\", \"#e040fb\"],\n vaporwave: [\"#ff71ce\", \"#01cdfe\", \"#b967ff\"],\n pastel: [\"#c4b5fd\", \"#fbcfe8\", \"#bae6fd\"],\n sakura: [\"#fff1f2\", \"#fda4af\", \"#fb7185\"],\n} as const satisfies Record<string, Array<string>>;\nexport type SarmalPalette = keyof typeof palettes; // TODO: reconsider naming convention. Should this represent the value type instead of the key union?\n\n/** RGB color components */\nexport interface Rgb {\n r: number;\n g: number;\n b: number;\n}\n\n/** Converts a hex color string to RGB components */\nexport function hexToRgb(hex: string): Rgb {\n const n = parseInt(hex.slice(1), 16);\n return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };\n}\n\nconst HEX_3_RE = /^#([0-9a-fA-F]{3})$/;\nconst HEX_6_RE = /^#([0-9a-fA-F]{6})$/;\nconst HEX_8_RE = /^#([0-9a-fA-F]{8})$/;\nconst RGB_RE =\n /^rgba?\\(\\s*(-?\\d{1,3})\\s*,\\s*(-?\\d{1,3})\\s*,\\s*(-?\\d{1,3})(?:\\s*,\\s*[\\d.]+)?\\s*\\)$/i;\n\n/**\n * Parses a color string in any supported format into Rgb components.\n * Returns `null` for unrecognized or malformed input.\n *\n * Supported formats:\n * - 3-digit hex: #rgb\n * - 6-digit hex: #rrggbb\n * - 8-digit hex: #rrggbbaa (alpha is silently stripped)\n * - rgb(r, g, b) channels clamped to 0–255\n * - rgba(r, g, b, a) alpha is silently stripped\n */\nexport function parseColorToRgb(s: string): Rgb | null {\n const trimmed = s.trim();\n\n const m3 = HEX_3_RE.exec(trimmed);\n if (m3) {\n const [r, g, b] = m3[1]!;\n return hexToRgb(`#${r}${r}${g}${g}${b}${b}`);\n }\n\n const m6 = HEX_6_RE.exec(trimmed);\n if (m6) {\n return hexToRgb(trimmed);\n }\n\n const m8 = HEX_8_RE.exec(trimmed);\n if (m8) {\n return hexToRgb(`#${trimmed.slice(1, 7)}`);\n }\n\n const mRgb = RGB_RE.exec(trimmed);\n if (mRgb) {\n return {\n r: Math.max(0, Math.min(255, parseInt(mRgb[1]!, 10))),\n g: Math.max(0, Math.min(255, parseInt(mRgb[2]!, 10))),\n b: Math.max(0, Math.min(255, parseInt(mRgb[3]!, 10))),\n };\n }\n\n return null;\n}\n\nconst OKLCH_RE = /^oklch\\(\\s*([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)(?:\\s*\\/\\s*[\\d.]+)?\\s*\\)$/i;\n\n/**\n * Parses an oklch() color string directly to Oklab.\n * Returns `null` for unrecognized or malformed input.\n *\n * Accepted syntax (subset of CSS Color 4):\n * - oklch(L C H) bare floats, L clamped to 0–1, C clamped to 0–0.4, H in degrees\n * - oklch(L C H / alpha) alpha silently stripped\n *\n * ! Not supported: percentages, `none` keyword, negative hues\n */\nexport function parseOklchToOklab(s: string): Oklab | null {\n const m = OKLCH_RE.exec(s.trim());\n if (!m) {\n return null;\n }\n\n const L = parseFloat(m[1]!);\n const C = parseFloat(m[2]!);\n const H = parseFloat(m[3]!);\n\n if (Number.isNaN(L) || Number.isNaN(C) || Number.isNaN(H)) {\n return null;\n }\n\n const clampedL = Math.max(0, Math.min(1, L));\n const clampedC = Math.max(0, Math.min(0.4, C));\n const H_rad = H * (Math.PI / 180);\n\n return {\n L: clampedL,\n a: clampedC * Math.cos(H_rad),\n b: clampedC * Math.sin(H_rad),\n };\n}\n\n/**\n * Unified color-to-Oklab entry point.\n * Tries oklch() first (direct to Oklab), then falls back through the sRGB path.\n */\nexport function parseColorToOklab(s: string): Oklab | null {\n const oklab = parseOklchToOklab(s);\n if (oklab !== null) {\n return oklab;\n }\n\n const rgb = parseColorToRgb(s);\n if (rgb === null) {\n return null;\n }\n\n return rgbToOklab(rgb);\n}\n\n/** Converts any accepted color string to Rgb. Throws if the format is unrecognized. */\nexport function colorToRgb(color: string): Rgb {\n const rgb = parseColorToRgb(color);\n if (rgb !== null) {\n return rgb;\n }\n\n const lab = parseOklchToOklab(color);\n if (lab !== null) {\n return oklabToRgb(lab);\n }\n\n throw new Error(`[sarmal] unrecognized color \"${color}\"`);\n}\n\n/** sRGB byte (0–255) to linear light (0–1)\n * @see {@link https://bottosson.github.io/posts/oklab/}\n */\nfunction srgbByteToLinear(c: number): number {\n const n = c / 255;\n return n <= 0.04045 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);\n}\n\n/** Linear light (0–1) to sRGB byte (0–255), gamma-compressed and clamped */\nfunction linearToSrgbByte(c: number): number {\n const v = Math.max(0, Math.min(1, c));\n return Math.round((v <= 0.0031308 ? 12.92 * v : 1.055 * Math.pow(v, 1 / 2.4) - 0.055) * 255);\n}\n\nexport interface Oklab {\n L: number;\n a: number;\n b: number;\n}\n\n/**\n * sRGB Rgb to OKLab\n * @see {@link https://bottosson.github.io/posts/oklab/}\n */\nexport function rgbToOklab({ r, g, b }: Rgb): Oklab {\n const rl = srgbByteToLinear(r),\n gl = srgbByteToLinear(g),\n bl = srgbByteToLinear(b);\n const l = Math.cbrt(0.4122214708 * rl + 0.5363325363 * gl + 0.0514459929 * bl);\n const m = Math.cbrt(0.2119034982 * rl + 0.6806995451 * gl + 0.1073969566 * bl);\n const s = Math.cbrt(0.0883024619 * rl + 0.2817188376 * gl + 0.6299787005 * bl);\n\n return {\n L: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,\n b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,\n };\n}\n\n/** OKLab to sRGB Rgb, out-of-gamut values clamped to 0–255 */\nexport function oklabToRgb({ L, a, b }: Oklab): Rgb {\n const l_ = L + 0.3963377774 * a + 0.2158037573 * b;\n const m_ = L - 0.1055613458 * a - 0.0638541728 * b;\n const s_ = L - 0.0894841775 * a - 1.29145603 * b;\n const l = l_ * l_ * l_,\n m = m_ * m_ * m_,\n s = s_ * s_ * s_;\n\n return {\n r: linearToSrgbByte(+4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s),\n g: linearToSrgbByte(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s),\n b: linearToSrgbByte(-0.0041960863 * l - 0.7034186147 * m + 1.6076099202 * s),\n };\n}\n\n/** Interpolates between two OKLab colors without any gray dead zone */\nexport const lerpOklab = (a: Oklab, b: Oklab, t: number): Oklab => {\n if (t <= 0) {\n return a;\n }\n\n if (t >= 1) {\n return b;\n }\n\n return {\n L: a.L + (b.L - a.L) * t,\n a: a.a + (b.a - a.a) * t,\n b: a.b + (b.b - a.b) * t,\n };\n};\n\n/**\n * Gets a color from a palette based on position (0-1) with optional time-based cycling\n * @param palette Array of Oklab colors\n * @param position Position along the gradient (0 = start, 1 = end)\n * @param timeOffset Optional time offset for animated gradients\n */\nexport function getPaletteColor(palette: Oklab[], position: number, timeOffset: number = 0): Oklab {\n if (palette.length === 0) {\n return { L: 1, a: 0, b: 0 };\n }\n\n if (palette.length === 1) {\n return palette[0]!;\n }\n\n const cyclePos = (((position + timeOffset) % 1) + 1) % 1;\n const scaled = cyclePos * palette.length;\n const idx = Math.floor(scaled);\n const t = scaled - idx;\n\n const c1 = palette[idx % palette.length]!;\n const c2 = palette[(idx + 1) % palette.length]!;\n\n return lerpOklab(c1, c2, t);\n}\n\n// TODO: maybe should infer the union type from the variable instead of making the variable respect the predefined union type\nconst TRAIL_STYLES: readonly TrailStyle[] = [\"default\", \"gradient-static\", \"gradient-animated\"];\n\n// FIXME: Should inherit from the actual render option object to avoid drift\nconst BASE_RENDER_OPTION_KEYS: ReadonlySet<string> = new Set([\n \"trailColor\",\n \"trailStyle\",\n \"skeletonColor\",\n]);\n\nconst RENDER_OPTION_KEYS: ReadonlySet<string> = new Set([\n \"trailColor\",\n \"headColor\",\n \"skeletonColor\",\n \"trailStyle\",\n \"headRadius\",\n \"trailWidth\",\n]);\n\n/**\n * Validates options for renderers that support `trailColor`, `trailStyle`, and `skeletonColor`.\n * Throws a `TypeError` if any canvas-only field (`headColor`, `headRadius`, `trailWidth`) is passed.\n */\nexport function validateBaseRenderOptions(partial: BaseRuntimeRenderOptions) {\n for (const key of Object.keys(partial)) {\n if (!BASE_RENDER_OPTION_KEYS.has(key)) {\n throw new TypeError(`[sarmal] setRenderOptions: unsupported key \"${key}\" for this renderer`);\n }\n }\n if (partial.trailColor !== undefined) {\n assertTrailColor(partial.trailColor);\n }\n if (partial.trailStyle !== undefined) {\n assertTrailStyle(partial.trailStyle);\n }\n if (partial.skeletonColor !== undefined) {\n assertSkeletonColor(partial.skeletonColor);\n }\n}\n\n/**\n * Checks a `RuntimeRenderOptions` payload against the library's acceptance criteria.\n *\n * If this throws, no field has been assigned yet on the caller side,\n * so the renderer continues on the previous valid state.\n *\n * Rules:\n * - Unknown keys throw for runtime type safety\n * - `trailColor` must match expected string/Array<string> format\n * - `headColor` must match expected color string format OR `null`\n * - `skeletonColor` must match expected color string format OR the literal `\"transparent\"`.\n * - `trailStyle` must match one of the accepted modes\n *\n * ! Field combinations like `trailColor=\"#ffffff\"` with `trailStyle=\"gradient-animated\"` are NOT rejected\n * They only produce a console warning at the renderer to indicate an unexpected outcome\n */\nexport function validateRenderOptions(partial: RuntimeRenderOptions) {\n for (const key of Object.keys(partial)) {\n if (!RENDER_OPTION_KEYS.has(key)) {\n throw new TypeError(`[sarmal] setRenderOptions: unknown key \"${key}\"`);\n }\n }\n\n if (partial.trailColor !== undefined) {\n assertTrailColor(partial.trailColor);\n }\n if (partial.headColor !== undefined) {\n assertHeadColor(partial.headColor);\n }\n if (partial.skeletonColor !== undefined) {\n assertSkeletonColor(partial.skeletonColor);\n }\n if (partial.trailStyle !== undefined) {\n assertTrailStyle(partial.trailStyle);\n }\n if (partial.headRadius !== undefined) {\n assertHeadRadius(partial.headRadius);\n }\n if (partial.trailWidth !== undefined) {\n assertTrailWidth(partial.trailWidth);\n }\n}\n\nfunction assertTrailColor(value: TrailColor) {\n if (typeof value === \"string\") {\n if (parseColorToOklab(value) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()), got \"${value}\"`,\n );\n }\n return;\n }\n\n if (Array.isArray(value)) {\n if (value.length < 2) {\n throw new RangeError(\n `[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`,\n );\n }\n\n for (let i = 0; i < value.length; i++) {\n const entry = value[i];\n if (typeof entry !== \"string\" || parseColorToOklab(entry) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor[${i}] must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()), got ${JSON.stringify(entry)}`,\n );\n }\n }\n return;\n }\n\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or an array of color strings, got ${JSON.stringify(value)}`,\n );\n}\n\nfunction assertHeadColor(value: string | null) {\n if (value === null) {\n return;\n }\n\n if (typeof value !== \"string\" || parseColorToOklab(value) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: headColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or null, got ${JSON.stringify(value)}`,\n );\n }\n}\n\nfunction assertSkeletonColor(value: string) {\n if (value === \"transparent\") {\n return;\n }\n\n if (typeof value !== \"string\" || parseColorToOklab(value) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: skeletonColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or \"transparent\", got ${JSON.stringify(value)}`,\n );\n }\n}\n\nfunction assertTrailStyle(value: TrailStyle) {\n if (!TRAIL_STYLES.includes(value)) {\n // TODO: perhaps make Trail Style inferred from a variable so it can be spread here to keep it dynamic.\n throw new RangeError(\n `[sarmal] setRenderOptions: trailStyle must be one of \"default\", \"gradient-static\", \"gradient-animated\", got ${JSON.stringify(value)}`,\n );\n }\n}\n\nfunction assertHeadRadius(value: number) {\n if (typeof value !== \"number\") {\n throw new TypeError(\n `[sarmal] setRenderOptions: headRadius must be a number, got ${JSON.stringify(value)}`,\n );\n }\n if (!Number.isFinite(value) || value <= 0) {\n throw new TypeError(\n `[sarmal] setRenderOptions: headRadius must be a finite positive number, got ${value}`,\n );\n }\n}\n\nfunction assertTrailWidth(value: number) {\n if (typeof value !== \"number\") {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailWidth must be a number, got ${JSON.stringify(value)}`,\n );\n }\n\n if (!Number.isFinite(value) || value <= 0) {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailWidth must be a finite positive number, got ${value}`,\n );\n }\n}\n\n/**\n * Resolves the effective solid fill color used by the `\"default\"` trail style.\n * If the caller passed an array, the first entry is used.\n *\n * This is to avoid errors when an array of colors are passed for `trailStyle=\"default\"`\n */\nexport function resolveTrailMainColor(trailColor: TrailColor) {\n return typeof trailColor === \"string\" ? trailColor : trailColor[0]!;\n}\n\n/**\n * Resolves the effective palette used by gradient trail styles.\n *\n * This is to avoid errors when a single color string is passed for gradient trail styles\n */\nexport function resolveTrailPalette(trailColor: TrailColor): string[] {\n return typeof trailColor === \"string\" ? [trailColor] : trailColor;\n}\n\n/**\n * Computes the head color automatically from the current `trailColor` and `trailStyle` pair.\n *\n * Rules:\n * - `\"default\"` style: the head matches the solid trail color.\n * - Gradient styles: the head matches the *last* stop of the palette\n *\n * @returns a CSS-valid color string\n */\nexport function resolveHeadColor(trailColor: TrailColor, trailStyle: TrailStyle): string {\n if (trailStyle === \"default\") {\n return resolveTrailMainColor(trailColor);\n }\n\n const palette = resolveTrailPalette(trailColor);\n const last = palette[palette.length - 1]!;\n const { r, g, b } = colorToRgb(last);\n return `rgb(${r},${g},${b})`;\n}\n\n/**\n * Emits a console warning when `trailColor` and `trailStyle` don't *semantically* match up\n *\n * For example, an array passed with `\"default\"` style (only the first color is used) or\n * a single string passed with a gradient style (the trail renders as a solid color)\n *\n * ! This is only a warning, so the renderer will still produce a valid output\n */\nexport function warnIfTrailColorMismatch(trailColor: TrailColor, trailStyle: TrailStyle): void {\n if (trailStyle === \"default\" && Array.isArray(trailColor)) {\n // biome-ignore lint/suspicious/noConsole: advisory for developer feedback\n console.warn(\n '[sarmal] trailColor is an array but trailStyle is \"default\"; only the first color will be used. Pass a gradient trailStyle to use the whole palette.',\n );\n\n return;\n }\n\n if (trailStyle !== \"default\" && typeof trailColor === \"string\") {\n // biome-ignore lint/suspicious/noConsole: advisory for developer feedback\n console.warn(\n `[sarmal] trailColor is a single color but trailStyle is \"${trailStyle}\"; the trail will render as a solid color. Pass an array of hex colors to use a real gradient.`,\n );\n }\n}\n","import type {\n CurveDef,\n MorphOptions,\n Point,\n RendererOptions,\n RuntimeRenderOptions,\n SarmalInstance,\n TrailColor,\n TrailStyle,\n} from \"./types\";\nexport type { TrailPoint } from \"./renderer-shared\";\nexport type { Rgb } from \"./renderer-shared\";\nexport type { Oklab } from \"./renderer-shared\";\n\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n TRAIL_MIN_WIDTH,\n TRAIL_MAX_WIDTH,\n computeBoundaries,\n computeTrailQuad,\n enginePassthroughs,\n colorToRgb,\n getPaletteColor,\n parseColorToOklab,\n resolveHeadColor,\n resolveTrailPalette,\n resolveTrailMainColor,\n oklabToRgb,\n Oklab,\n validateRenderOptions,\n warnIfTrailColorMismatch,\n} from \"./renderer-shared\";\n\nconst getHeadDotRadius = (w: number, h: number) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160));\n\nexport { computeTangent, computeNormal } from \"./renderer-shared\";\nexport { palettes, lerpOklab, getPaletteColor, parseColorToRgb } from \"./renderer-shared\";\n\nconst WHITE_HEX = \"#ffffff\";\n\nexport function colorToRgbComponents(color: string): string {\n const { r, g, b } = colorToRgb(color);\n return `${r},${g},${b}`;\n}\n\n/**\n * ! Exported purely so `applyDprSizing` can be unit-tested without a DOM\n */\nexport interface DprSizingTarget {\n width: number;\n height: number;\n style: { width: string; height: string };\n}\n\n/**\n * Applies DPR sizing to a target\n *\n * ! DO NOT REMOVE THE `style.width` and `style.height` ASSIGNMENTS\n *\n * A canvas with only `width`/`height` HTML attributes and no CSS derives\n * its displayed size from those attributes.\n * If we set `canvas.width = logicalWidth * dpr` to scale the drawing buffer for \"crispness\",\n * the element ALSO visually grows by the DPR factor\n * ! The bug is silent and sneaky. It just resulsts in a broken render without any obvious reasons\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas\n * MDN: \"If you don't set the CSS attributes, the intrinsic size of the canvas will be used as its display size\"\n *\n * @see https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html\n * \"Every canvas has 2 sizes: the drawingbuffer (pixels) and the display\n * size (CSS). If no CSS affects display size, it equals drawingbuffer.\"\n *\n * @see https://stackoverflow.com/questions/4938346/canvas-width-and-height-in-html5\n * Phrogz: \"If you don't set the CSS attributes, the intrinsic size of\n * the canvas will be used as its display size.\"\n *\n * The regression test for this lives in **renderer.test.ts**\n */\nexport function applyDprSizing(\n target: DprSizingTarget,\n logicalWidth: number,\n logicalHeight: number,\n dpr: number,\n): void {\n // Pin the CSS display size FIRST so changing the attributes below\n // cannot resize the element.\n target.style.width = `${logicalWidth}px`;\n target.style.height = `${logicalHeight}px`;\n\n target.width = logicalWidth * dpr;\n target.height = logicalHeight * dpr;\n}\n\n/**\n * Creates a Canvas 2D renderer for sarmal animations\n * Renders the skeleton and the trail\n */\nexport function createRenderer(options: RendererOptions): SarmalInstance {\n const canvas = options.canvas;\n if (!canvas.getContext(\"2d\")) {\n throw new Error(\"Could not get 2d context from canvas\");\n }\n const ctx = canvas.getContext(\"2d\")!;\n\n const engine = options.engine;\n\n // ! Mutated only by `setRenderOptions`.\n let trailStyle: TrailStyle = options.trailStyle ?? \"default\";\n let trailColor: TrailColor = options.trailColor ?? WHITE_HEX;\n let skeletonColor: string = options.skeletonColor ?? WHITE_HEX;\n // `null` means that head color is derived from `trailColor` & `trailStyle` and refreshed whenever either changes.\n let userHeadColor: string | null = options.headColor ?? null;\n let headColor: string = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);\n\n let trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));\n let trailPalette = resolveTrailPalette(trailColor);\n let trailPaletteOklab: Array<Oklab> = trailPalette.map((c) => parseColorToOklab(c)!);\n\n warnIfTrailColorMismatch(trailColor, trailStyle);\n\n /**\n * Device pixel ratio for high-DPI displays.\n * We scale the canvas buffer size by DPR and apply a transform scale\n */\n const dpr = typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1;\n\n /**\n * Sets up the canvas for DPR scaling\n */\n function setupCanvas() {\n // TODO: attach a ResizeObserver so this function can be called again for the right scale of canvas\n const lw = canvas.offsetWidth || 200;\n const lh = canvas.offsetHeight || 200;\n applyDprSizing(canvas, lw, lh, dpr);\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n }\n\n setupCanvas();\n\n // Store logical dimensions for boundary calculations\n let logicalWidth = canvas.width / dpr;\n let logicalHeight = canvas.height / dpr;\n if (options.headRadius !== undefined) {\n validateRenderOptions({ headRadius: options.headRadius });\n }\n\n if (options.trailWidth !== undefined) {\n validateRenderOptions({ trailWidth: options.trailWidth });\n }\n\n let headRadius = options.headRadius ?? getHeadDotRadius(logicalWidth, logicalHeight);\n let trailWidth = options.trailWidth ?? 1;\n\n let skeleton: Array<Point> = [];\n let skeletonCanvas: OffscreenCanvas | null = null;\n let trail: Array<Point> = [];\n let trailCount = 0;\n let head: Point | null = null;\n let scale = 1;\n let offsetX = 0;\n let offsetY = 0;\n let animationId: number | null = null;\n let lastTime = 0;\n let pausedByVisibility = false;\n\n let morphResolve: (() => void) | null = null;\n let morphReject: ((error: Error) => void) | null = null;\n let morphDurationMs = DEFAULT_MORPH_DURATION_MS;\n let morphAlpha = 0;\n\n /** Accumulated time for \"gradient-animated\" trail style */\n let gradientAnimTime = 0;\n\n function calculateBoundaries() {\n const b = computeBoundaries(skeleton, logicalWidth, logicalHeight);\n if (b) {\n scale = b.scale;\n offsetX = b.offsetX;\n offsetY = b.offsetY;\n }\n }\n\n /**\n * Draws the skeleton once into an OffscreenCanvas so that every frame\n * only needs a single ctx.drawImage() instead of rebuilding the full path.\n */\n function buildSkeletonCanvas() {\n if (skeleton.length < 2) {\n return;\n }\n\n skeletonCanvas = new OffscreenCanvas(canvas.width, canvas.height);\n const skeletonCtx = skeletonCanvas.getContext(\"2d\")!;\n\n // Apply DPR scale to draw in logical coordinates\n skeletonCtx.setTransform(dpr, 0, 0, dpr, 0, 0);\n\n skeletonCtx.strokeStyle = `rgba(${colorToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;\n skeletonCtx.lineWidth = 1.5;\n skeletonCtx.beginPath();\n\n const first = skeleton[0]!;\n skeletonCtx.moveTo(first.x * scale + offsetX, first.y * scale + offsetY);\n\n for (let i = 1; i < skeleton.length; i++) {\n const p = skeleton[i]!;\n skeletonCtx.lineTo(p.x * scale + offsetX, p.y * scale + offsetY);\n }\n\n skeletonCtx.stroke();\n }\n\n function drawSkeletonPath(pts: Array<Point>, opacity: number) {\n if (pts.length < 2) {\n return;\n }\n\n ctx.strokeStyle = `rgba(${colorToRgbComponents(skeletonColor)},${opacity})`;\n ctx.lineWidth = 1.5;\n ctx.beginPath();\n ctx.moveTo(pts[0]!.x * scale + offsetX, pts[0]!.y * scale + offsetY);\n for (let i = 1; i < pts.length; i++) {\n ctx.lineTo(pts[i]!.x * scale + offsetX, pts[i]!.y * scale + offsetY);\n }\n ctx.stroke();\n }\n\n function drawSkeleton() {\n if (skeletonColor === \"transparent\") {\n return;\n }\n\n if (engine.morphAlpha !== null) {\n // Draw the live lerped skeleton every frame so it always matches the current\n // scale/offset and correctly tracks live curves that change with actualTime\n drawSkeletonPath(engine.getSarmalSkeleton(), DEFAULT_SKELETON_OPACITY);\n return;\n }\n\n if (engine.isLiveSkeleton) {\n if (skeleton.length < 2) {\n return;\n }\n\n ctx.strokeStyle = `rgba(${colorToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;\n ctx.lineWidth = 1.5;\n ctx.beginPath();\n\n const first = skeleton[0]!;\n ctx.moveTo(first.x * scale + offsetX, first.y * scale + offsetY);\n\n for (let i = 1; i < skeleton.length; i++) {\n const p = skeleton[i]!;\n ctx.lineTo(p.x * scale + offsetX, p.y * scale + offsetY);\n }\n\n ctx.stroke();\n } else if (skeletonCanvas) {\n /**\n * ! The offscreen buffer is *already* DPR-scaled, but the main ctx also has a DPR transform applied,\n * ! so passing natural pixel size would **double-scale** it.\n */\n ctx.drawImage(skeletonCanvas, 0, 0, logicalWidth, logicalHeight);\n }\n }\n\n function drawTrail() {\n if (trailCount < 2) {\n return;\n }\n\n /**\n * Ribbon approach: draw the trail as a sequence of filled quads.\n * Each quad connects two consecutive trail points with left/right offsets\n * based on the width at that position. Quads are drawn from tail to head\n * so later quads naturally overlay earlier ones.\n *\n * @see https://cesium.com/blog/2013/04/22/robust-polyline-rendering-with-webgl\n * Cesium: \"draw a screen-aligned quad for each segment... extrude them\n * in screen space in the direction normal to the line.\"\n */\n const toX = (p: { x: number }) => p.x * scale + offsetX;\n const toY = (p: { y: number }) => p.y * scale + offsetY;\n for (let i = 0; i < trailCount - 1; i++) {\n const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity, progress } = computeTrailQuad(\n trail,\n i,\n trailCount,\n toX,\n toY,\n TRAIL_MIN_WIDTH * trailWidth,\n TRAIL_MAX_WIDTH * trailWidth,\n );\n\n // Determine fill color based on trail style\n if (trailStyle === \"default\") {\n ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;\n } else {\n const timeOffset = trailStyle === \"gradient-animated\" ? gradientAnimTime * 0.0005 : 0;\n const { r, g, b } = oklabToRgb(getPaletteColor(trailPaletteOklab, progress, timeOffset));\n ctx.fillStyle = `rgba(${r},${g},${b},${opacity})`;\n }\n\n ctx.beginPath();\n ctx.moveTo(l0x, l0y);\n ctx.lineTo(l1x, l1y);\n ctx.lineTo(r1x, r1y);\n ctx.lineTo(r0x, r0y);\n ctx.closePath();\n ctx.fill();\n }\n }\n\n function drawHead() {\n if (!head) {\n return;\n }\n\n const x = head.x * scale + offsetX;\n const y = head.y * scale + offsetY;\n const r = headRadius;\n\n ctx.fillStyle = headColor;\n ctx.beginPath();\n ctx.arc(x, y, r, 0, Math.PI * 2);\n ctx.fill();\n }\n\n function renderFrame(deltaTime: number) {\n // Update gradient animation time for animated trail style\n if (trailStyle === \"gradient-animated\") {\n gradientAnimTime += deltaTime * 1000; // Convert to ms for consistent speed\n }\n\n if (engine.morphAlpha !== null) {\n morphAlpha = Math.min(1, morphAlpha + deltaTime / (morphDurationMs / 1000));\n engine.setMorphAlpha(morphAlpha);\n\n /**\n * Compute bounds from the actual interpolated skeleton during morph\n * ! This ensures the curve stays properly centered and scaled\n */\n const interpolatedSkeleton = engine.getSarmalSkeleton();\n const bounds = computeBoundaries(interpolatedSkeleton, logicalWidth, logicalHeight);\n\n if (bounds) {\n scale = bounds.scale;\n offsetX = bounds.offsetX;\n offsetY = bounds.offsetY;\n }\n\n if (morphAlpha >= 1) {\n engine.completeMorph();\n morphResolve?.();\n morphResolve = null;\n morphReject = null;\n morphAlpha = 0;\n\n skeleton = engine.getSarmalSkeleton();\n if (!engine.isLiveSkeleton && skeletonColor !== \"transparent\") {\n buildSkeletonCanvas();\n }\n }\n }\n\n trail = engine.tick(deltaTime);\n trailCount = engine.trailCount;\n head = trailCount > 0 ? trail[trailCount - 1]! : null;\n\n ctx.clearRect(0, 0, logicalWidth, logicalHeight);\n\n if (engine.isLiveSkeleton && engine.morphAlpha === null) {\n skeleton = engine.getSarmalSkeleton();\n calculateBoundaries();\n }\n\n drawSkeleton();\n drawTrail();\n drawHead();\n }\n\n function loop() {\n const now = performance.now();\n const deltaTime = Math.min((now - lastTime) / 1000, 1 / 30);\n lastTime = now;\n\n renderFrame(deltaTime);\n animationId = requestAnimationFrame(loop);\n }\n\n // Initialize skeleton and offscreen canvas on creation\n skeleton = engine.getSarmalSkeleton();\n calculateBoundaries();\n\n if (!engine.isLiveSkeleton && skeletonColor !== \"transparent\") {\n buildSkeletonCanvas();\n }\n\n // Handle initialPhase option: seek to the specified position before first frame\n if (options.initialPhase !== undefined) {\n engine.seek(options.initialPhase);\n }\n\n // Draw initial frame unconditionally (shows skeleton and initial position)\n renderFrame(0);\n\n // Handle autoStart option: start the animation loop unless explicitly disabled\n const shouldAutoStart = options.autoStart !== false;\n\n const instance = {\n play() {\n if (animationId !== null) {\n return;\n }\n\n lastTime = performance.now();\n loop();\n },\n\n pause() {\n if (animationId === null) {\n return;\n }\n\n cancelAnimationFrame(animationId);\n animationId = null;\n engine.cancelSpeedTransition();\n },\n\n reset() {\n engine.reset();\n trail = [];\n head = null;\n },\n\n destroy() {\n if (animationId !== null) {\n cancelAnimationFrame(animationId);\n animationId = null;\n }\n\n document.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\n if (morphReject !== null) {\n morphReject(new Error(\"Instance destroyed during morph\"));\n morphResolve = null;\n morphReject = null;\n }\n },\n\n ...enginePassthroughs(engine),\n\n morphTo(target: CurveDef, options?: MorphOptions): Promise<void> {\n if (morphResolve !== null) {\n engine.completeMorph();\n morphResolve();\n morphResolve = null;\n morphReject = null;\n morphAlpha = 0;\n }\n\n morphDurationMs = options?.duration ?? DEFAULT_MORPH_DURATION_MS;\n morphAlpha = 0;\n\n engine.startMorph(target, options?.morphStrategy);\n\n return new Promise<void>((resolve, reject) => {\n morphResolve = resolve;\n morphReject = reject;\n });\n },\n\n setRenderOptions(partial: RuntimeRenderOptions): void {\n validateRenderOptions(partial);\n\n if (partial.trailColor !== undefined) {\n trailColor = partial.trailColor;\n trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));\n trailPalette = resolveTrailPalette(trailColor);\n trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c)!);\n }\n\n if (partial.skeletonColor !== undefined) {\n skeletonColor = partial.skeletonColor;\n\n if (skeletonColor !== \"transparent\" && !engine.isLiveSkeleton) {\n buildSkeletonCanvas();\n }\n }\n\n if (partial.trailStyle !== undefined) {\n trailStyle = partial.trailStyle;\n }\n\n if (partial.headColor !== undefined) {\n userHeadColor = partial.headColor;\n }\n\n if (partial.headRadius !== undefined) {\n headRadius = partial.headRadius;\n }\n\n if (partial.trailWidth !== undefined) {\n trailWidth = partial.trailWidth;\n }\n\n if (userHeadColor === null) {\n headColor = resolveHeadColor(trailColor, trailStyle);\n } else {\n headColor = userHeadColor;\n }\n\n if (partial.trailColor !== undefined || partial.trailStyle !== undefined) {\n warnIfTrailColorMismatch(trailColor, trailStyle);\n }\n },\n };\n\n const pauseOnHidden = options.pauseOnHidden !== false;\n\n function handleVisibilityChange() {\n if (document.hidden) {\n if (animationId !== null) {\n instance.pause();\n pausedByVisibility = true;\n }\n } else {\n if (pausedByVisibility) {\n pausedByVisibility = false;\n instance.play();\n }\n }\n }\n\n if (pauseOnHidden) {\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n }\n\n // If the tab is already hidden at construction time, skip auto-start.\n // The visibilitychange listener will resume when the tab becomes visible.\n const actuallyAutoStart = shouldAutoStart && !(pauseOnHidden && document.hidden);\n if (actuallyAutoStart) {\n instance.play();\n } else if (shouldAutoStart) {\n pausedByVisibility = true;\n }\n\n return instance;\n}\n","import type {\n BaseRendererOptions,\n CurveDef,\n Engine,\n MorphOptions,\n Point,\n RuntimeRenderOptions,\n SarmalInstance,\n TrailColor,\n TrailStyle,\n} from \"./types\";\n\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n TRAIL_MIN_WIDTH,\n TRAIL_MAX_WIDTH,\n computeBoundaries,\n computeTrailQuad,\n enginePassthroughs,\n colorToRgb,\n getPaletteColor,\n parseColorToOklab,\n resolveHeadColor,\n resolveTrailPalette,\n resolveTrailMainColor,\n oklabToRgb,\n Oklab,\n validateRenderOptions,\n warnIfTrailColorMismatch,\n} from \"./renderer-shared\";\nimport { createEngine } from \"./engine\";\n\nexport interface SVGRendererOptions extends BaseRendererOptions {\n /** SVG element the renderer draws into directly */\n container: SVGSVGElement;\n engine: Engine;\n /** @default 'Loading' */\n ariaLabel?: string;\n}\n\nexport interface SVGSarmalOptions extends Omit<SVGRendererOptions, \"container\" | \"engine\"> {\n /** @default 120 */\n trailLength?: number;\n}\nconst EMPTY_PARAMS: Record<string, number> = {};\nconst SVG_DEFAULT_HEAD_RADIUS = 0.5; // viewBox units\n/** Pixel-space skeleton stroke width calibrated to viewBox units at construction like TRAIL_MIN/MAX_WIDTH. */\nconst SKELETON_STROKE_WIDTH_PX = 1.5;\n\n/**\n * Threshold above which a console.warn suggests canvas for long SVG trails\n * The value is based on results from `playwright test e2e/tests/svg-trail-benchmark.spec.ts --project=chromium-dpr1 --reporter=list`\n */\nconst HIGH_TRAIL_LENGTH_THRESHOLD = 5000;\n\nfunction pointsToPathString(pts: Point[], scale: number, offsetX: number, offsetY: number): string {\n if (pts.length < 2) {\n return \"\";\n }\n\n const px = (p: Point) => (p.x * scale + offsetX).toFixed(2);\n const py = (p: Point) => (p.y * scale + offsetY).toFixed(2);\n let d = `M${px(pts[0]!)} ${py(pts[0]!)}`;\n\n for (let i = 1; i < pts.length; i++) {\n d += ` L${px(pts[i]!)} ${py(pts[i]!)}`;\n }\n\n return d + \" Z\";\n}\n\nfunction sampleCurveSkeleton(curveDef: CurveDef): Point[] {\n const period = curveDef.period ?? Math.PI * 2;\n const samples = Math.ceil(period * 50); // match engine's POINTS_PER_PERIOD_UNIT\n const pts: Point[] = Array.from({ length: samples });\n\n for (let i = 0; i < samples; i++) {\n const phase = (i / (samples - 1)) * period;\n pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(phase) : curveDef.fn(phase, 0, EMPTY_PARAMS);\n }\n\n return pts;\n}\n\nfunction el(tag: string): SVGElement {\n return document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n}\n\nfunction colorToRgbAttr(color: string): string {\n const { r, g, b } = colorToRgb(color);\n return `rgb(${r},${g},${b})`;\n}\n\n/**\n * Creates a live SVG renderer for sarmal animations\n * The SVG is appended into `container` and updated each frame via **requestAnimationFrame**\n */\nexport function createSVGRenderer(options: SVGRendererOptions): SarmalInstance {\n const { container, engine } = options;\n const poolSize = engine.trailLength;\n\n if (poolSize > HIGH_TRAIL_LENGTH_THRESHOLD) {\n console.warn(\n `[sarmal] High trailLength in SVG renderer (${poolSize}). Consider using the canvas renderer for long trails.`,\n );\n }\n\n // TODO: duplicate let variables. maybe a better way to share these too?\n // ! Mutated only by `setRenderOptions`.\n let trailStyle: TrailStyle = options.trailStyle ?? \"default\";\n let trailColor: TrailColor = options.trailColor ?? \"#ffffff\";\n let skeletonColor: string = options.skeletonColor ?? \"#ffffff\";\n // `null` means that head color is derived from `trailColor` & `trailStyle` and refreshed whenever either changes.\n let userHeadColor: string | null = options.headColor ?? null;\n let headColor: string = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);\n let headRadius: number; // assigned below after container size is read\n\n let trailSolid: string = colorToRgbAttr(resolveTrailMainColor(trailColor));\n let trailPalette: string[] = resolveTrailPalette(trailColor);\n let trailPaletteOklab: Oklab[] = trailPalette.map((c) => parseColorToOklab(c)!);\n\n const ariaLabel = options.ariaLabel ?? \"Loading\";\n\n warnIfTrailColorMismatch(trailColor, trailStyle);\n\n const viewSize = 100;\n\n function getContainerPixelSize(): number {\n const rect = container.getBoundingClientRect();\n return rect.width && rect.height ? Math.min(rect.width, rect.height) : 200;\n }\n\n /**\n * Trail widths and skeleton stroke are calibrated from pixel-space shared constants so that\n * strokes render at a consistent physical thickness regardless of container dimensions.\n * ! headRadius is NOT calibrated. It is native viewBox units (see SVG_DEFAULT_HEAD_RADIUS).\n */\n const containerPx = getContainerPixelSize();\n const svgTrailMinWidth = (TRAIL_MIN_WIDTH * viewSize) / containerPx;\n const svgTrailMaxWidth = (TRAIL_MAX_WIDTH * viewSize) / containerPx;\n const svgSkeletonStrokeWidth = String((SKELETON_STROKE_WIDTH_PX * viewSize) / containerPx);\n\n if (options.headRadius !== undefined) {\n validateRenderOptions({ headRadius: options.headRadius });\n }\n\n if (options.trailWidth !== undefined) {\n validateRenderOptions({ trailWidth: options.trailWidth });\n }\n headRadius = options.headRadius ?? SVG_DEFAULT_HEAD_RADIUS;\n let trailWidth = options.trailWidth ?? 1;\n\n container.setAttribute(\"viewBox\", `0 0 ${viewSize} ${viewSize}`);\n container.setAttribute(\"role\", \"img\");\n container.setAttribute(\"aria-label\", ariaLabel);\n\n const group = el(\"g\") as SVGGElement;\n\n const titleEl = el(\"title\");\n titleEl.textContent = ariaLabel;\n group.appendChild(titleEl);\n\n const skeletonPath = el(\"path\") as SVGPathElement;\n skeletonPath.setAttribute(\"data-sarmal-role\", \"skeleton\");\n skeletonPath.setAttribute(\"fill\", \"none\");\n skeletonPath.setAttribute(\n \"stroke\",\n skeletonColor === \"transparent\" ? \"transparent\" : colorToRgbAttr(skeletonColor),\n );\n skeletonPath.setAttribute(\"stroke-opacity\", String(DEFAULT_SKELETON_OPACITY));\n skeletonPath.setAttribute(\"stroke-width\", svgSkeletonStrokeWidth);\n if (skeletonColor === \"transparent\") {\n skeletonPath.setAttribute(\"visibility\", \"hidden\");\n }\n group.appendChild(skeletonPath);\n\n const skeletonPathA = el(\"path\") as SVGPathElement;\n skeletonPathA.setAttribute(\"fill\", \"none\");\n skeletonPathA.setAttribute(\n \"stroke\",\n skeletonColor === \"transparent\" ? \"transparent\" : colorToRgbAttr(skeletonColor),\n );\n skeletonPathA.setAttribute(\"stroke-width\", svgSkeletonStrokeWidth);\n skeletonPathA.setAttribute(\"visibility\", \"hidden\");\n group.appendChild(skeletonPathA);\n\n const skeletonPathB = el(\"path\") as SVGPathElement;\n skeletonPathB.setAttribute(\"fill\", \"none\");\n skeletonPathB.setAttribute(\n \"stroke\",\n skeletonColor === \"transparent\" ? \"transparent\" : colorToRgbAttr(skeletonColor),\n );\n skeletonPathB.setAttribute(\"stroke-width\", svgSkeletonStrokeWidth);\n skeletonPathB.setAttribute(\"visibility\", \"hidden\");\n group.appendChild(skeletonPathB);\n\n let morphPathABuilt = \"\";\n let morphPathBBuilt = \"\";\n\n const trailPaths: SVGPathElement[] = [];\n for (let i = 0; i < poolSize; i++) {\n const path = el(\"path\") as SVGPathElement;\n path.setAttribute(\"fill\", trailSolid);\n group.appendChild(path);\n trailPaths.push(path);\n }\n\n const headCircle = el(\"circle\") as SVGCircleElement;\n headCircle.setAttribute(\"data-sarmal-role\", \"head\");\n headCircle.setAttribute(\"fill\", colorToRgbAttr(headColor));\n headCircle.setAttribute(\"r\", String(headRadius));\n group.appendChild(headCircle);\n\n container.appendChild(group);\n\n let gradientAnimTime = 0;\n let scale = 1;\n let offsetX = 0;\n let offsetY = 0;\n\n function applyBoundaries(skeleton: Point[]) {\n const b = computeBoundaries(skeleton, viewSize, viewSize);\n if (b) {\n scale = b.scale;\n offsetX = b.offsetX;\n offsetY = b.offsetY;\n }\n }\n\n // Coordinate transform helpers: numeric (for math)\n function px(p: Point): number {\n return p.x * scale + offsetX;\n }\n function py(p: Point): number {\n return p.y * scale + offsetY;\n }\n\n function updateSkeleton(skeleton: Point[]) {\n skeletonPath.setAttribute(\"d\", pointsToPathString(skeleton, scale, offsetX, offsetY));\n }\n\n const skeleton = engine.getSarmalSkeleton();\n applyBoundaries(skeleton);\n\n if (!engine.isLiveSkeleton) {\n updateSkeleton(skeleton);\n }\n\n function updateTrail(trail: Point[], trailCount: number) {\n if (trailCount < 2) {\n for (const p of trailPaths) {\n p.setAttribute(\"d\", \"\");\n }\n\n return;\n }\n\n /**\n * Ribbon approach: each segment is a filled quad with its own opacity.\n * Quads are drawn from tail to head, with later quads overlaying earlier ones.\n */\n const drawnCount = trailCount - 1;\n\n for (let i = 0; i < drawnCount; i++) {\n const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity, progress } = computeTrailQuad(\n trail,\n i,\n trailCount,\n px,\n py,\n svgTrailMinWidth * trailWidth,\n svgTrailMaxWidth * trailWidth,\n );\n\n const d = `M${l0x.toFixed(2)} ${l0y.toFixed(2)} L${l1x.toFixed(2)} ${l1y.toFixed(2)} L${r1x.toFixed(2)} ${r1y.toFixed(2)} L${r0x.toFixed(2)} ${r0y.toFixed(2)} Z`;\n\n trailPaths[i]!.setAttribute(\"d\", d);\n trailPaths[i]!.setAttribute(\"fill-opacity\", opacity.toFixed(3));\n\n if (trailStyle !== \"default\") {\n const timeOffset = trailStyle === \"gradient-animated\" ? gradientAnimTime * 0.0005 : 0;\n const { r, g, b } = oklabToRgb(getPaletteColor(trailPaletteOklab, progress, timeOffset));\n trailPaths[i]!.setAttribute(\"fill\", `rgb(${r},${g},${b})`);\n }\n }\n\n // Hide unused paths\n for (let i = drawnCount; i < trailPaths.length; i++) {\n trailPaths[i]!.setAttribute(\"d\", \"\");\n }\n }\n\n function updateHead(trail: Point[], trailCount: number) {\n if (trailCount === 0) {\n return;\n }\n\n const head = trail[trailCount - 1]!;\n const x = px(head);\n const y = py(head);\n\n headCircle.setAttribute(\"cx\", String(x));\n headCircle.setAttribute(\"cy\", String(y));\n }\n\n let animationId: number | null = null;\n let lastTime = 0;\n let pausedByVisibility = false;\n const prefersReducedMotion =\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n\n let morphResolve: (() => void) | null = null;\n let morphReject: ((error: Error) => void) | null = null;\n let morphDurationMs = DEFAULT_MORPH_DURATION_MS;\n let morphTarget: CurveDef | null = null;\n let morphAlpha = 0;\n\n function renderFrame(deltaTime: number) {\n if (trailStyle === \"gradient-animated\") {\n gradientAnimTime += deltaTime * 1000;\n }\n\n if (engine.morphAlpha !== null) {\n morphAlpha = Math.min(1, morphAlpha + deltaTime / (morphDurationMs / 1000));\n engine.setMorphAlpha(morphAlpha);\n\n if (morphPathABuilt) {\n skeletonPathA.setAttribute(\"d\", morphPathABuilt);\n skeletonPathA.setAttribute(\"visibility\", \"visible\");\n skeletonPathA.setAttribute(\n \"stroke-opacity\",\n String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY),\n );\n }\n\n if (morphPathBBuilt) {\n skeletonPathB.setAttribute(\"d\", morphPathBBuilt);\n skeletonPathB.setAttribute(\"visibility\", \"visible\");\n skeletonPathB.setAttribute(\"stroke-opacity\", String(morphAlpha * DEFAULT_SKELETON_OPACITY));\n }\n\n if (morphAlpha >= 1) {\n engine.completeMorph();\n morphResolve?.();\n morphResolve = null;\n morphReject = null;\n morphTarget = null;\n morphAlpha = 0;\n morphPathABuilt = \"\";\n morphPathBBuilt = \"\";\n skeletonPathA.setAttribute(\"visibility\", \"hidden\");\n skeletonPathB.setAttribute(\"visibility\", \"hidden\");\n // Snap coordinate space to `curveB` and update skeleton path\n const newSkeleton = engine.getSarmalSkeleton();\n applyBoundaries(newSkeleton);\n updateSkeleton(newSkeleton);\n }\n }\n\n const trail = engine.tick(deltaTime);\n const trailCount = engine.trailCount;\n\n if (engine.isLiveSkeleton && engine.morphAlpha === null) {\n const liveSkeleton = engine.getSarmalSkeleton();\n applyBoundaries(liveSkeleton);\n updateSkeleton(liveSkeleton);\n }\n\n updateTrail(trail, trailCount);\n updateHead(trail, trailCount);\n }\n\n function loop() {\n const now = performance.now();\n const deltaTime = Math.min((now - lastTime) / 1000, 1 / 30);\n lastTime = now;\n\n renderFrame(deltaTime);\n\n if (!prefersReducedMotion) {\n animationId = requestAnimationFrame(loop);\n }\n }\n\n // Handle initialPhase option: seek to the specified position before first frame\n if (options.initialPhase !== undefined) {\n engine.seek(options.initialPhase);\n }\n\n // Draw initial frame unconditionally (shows skeleton and initial position)\n renderFrame(0);\n\n // Handle autoStart option: start the animation loop unless explicitly disabled\n const shouldAutoStart = options.autoStart !== false;\n\n const instance = {\n play() {\n if (animationId !== null) {\n return;\n }\n lastTime = performance.now();\n loop();\n },\n\n pause() {\n if (animationId === null) {\n return;\n }\n cancelAnimationFrame(animationId);\n animationId = null;\n engine.cancelSpeedTransition();\n },\n\n reset() {\n engine.reset();\n },\n\n destroy() {\n if (animationId !== null) {\n cancelAnimationFrame(animationId);\n animationId = null;\n }\n\n document.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\n if (morphReject !== null) {\n morphReject(new Error(\"Instance destroyed during morph\"));\n morphResolve = null;\n morphReject = null;\n }\n\n group.remove();\n },\n\n ...enginePassthroughs(engine),\n\n morphTo(target: CurveDef, options?: MorphOptions): Promise<void> {\n if (morphResolve !== null) {\n engine.completeMorph();\n morphResolve();\n morphResolve = null;\n morphReject = null;\n morphAlpha = 0;\n skeletonPathA.setAttribute(\"visibility\", \"hidden\");\n skeletonPathB.setAttribute(\"visibility\", \"hidden\");\n }\n\n morphDurationMs = options?.duration ?? DEFAULT_MORPH_DURATION_MS;\n morphTarget = target;\n morphAlpha = 0;\n\n const currentSkeleton = engine.getSarmalSkeleton();\n morphPathABuilt = pointsToPathString(currentSkeleton, scale, offsetX, offsetY);\n\n engine.startMorph(target, options?.morphStrategy);\n\n if (morphTarget) {\n const targetSkeleton = sampleCurveSkeleton(target);\n morphPathBBuilt = pointsToPathString(targetSkeleton, scale, offsetX, offsetY);\n }\n\n return new Promise<void>((resolve, reject) => {\n morphResolve = resolve;\n morphReject = reject;\n });\n },\n\n setRenderOptions(partial: RuntimeRenderOptions): void {\n validateRenderOptions(partial);\n\n const prevTrailStyle = trailStyle;\n\n if (partial.trailColor !== undefined) {\n trailColor = partial.trailColor;\n trailSolid = colorToRgbAttr(resolveTrailMainColor(trailColor));\n trailPalette = resolveTrailPalette(trailColor);\n trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c)!);\n\n // Only the \"default\" style paints trail paths at setter time, whereas gradient styles repaint per-segment fills every frame in `updateTrail`,\n // so they would already overwrite any fill operation made here\n if (trailStyle === \"default\") {\n for (const p of trailPaths) {\n p.setAttribute(\"fill\", trailSolid);\n }\n }\n }\n\n if (partial.skeletonColor !== undefined) {\n skeletonColor = partial.skeletonColor;\n\n if (skeletonColor === \"transparent\") {\n skeletonPath.setAttribute(\"visibility\", \"hidden\");\n } else {\n skeletonPath.setAttribute(\"stroke\", colorToRgbAttr(skeletonColor));\n skeletonPath.removeAttribute(\"visibility\");\n skeletonPathA.setAttribute(\"stroke\", colorToRgbAttr(skeletonColor));\n skeletonPathB.setAttribute(\"stroke\", colorToRgbAttr(skeletonColor));\n }\n }\n\n if (partial.trailStyle !== undefined) {\n trailStyle = partial.trailStyle;\n\n // When transitioning from gradient to default, the whole trail needs to be filled with the color\n // Transitioning from default to gradient does not require this as it already does per-segment color fills\n if (prevTrailStyle !== \"default\" && trailStyle === \"default\") {\n for (const p of trailPaths) {\n p.setAttribute(\"fill\", trailSolid);\n }\n }\n }\n if (partial.headColor !== undefined) {\n userHeadColor = partial.headColor;\n }\n\n if (partial.headRadius !== undefined) {\n headRadius = partial.headRadius;\n headCircle.setAttribute(\"r\", String(headRadius));\n }\n\n if (partial.trailWidth !== undefined) {\n trailWidth = partial.trailWidth;\n }\n\n if (userHeadColor === null) {\n headColor = resolveHeadColor(trailColor, trailStyle);\n } else {\n headColor = userHeadColor;\n }\n headCircle.setAttribute(\"fill\", colorToRgbAttr(headColor));\n\n if (partial.trailColor !== undefined || partial.trailStyle !== undefined) {\n warnIfTrailColorMismatch(trailColor, trailStyle);\n }\n },\n };\n\n const pauseOnHidden = options.pauseOnHidden !== false;\n\n function handleVisibilityChange() {\n if (document.hidden) {\n if (animationId !== null) {\n instance.pause();\n pausedByVisibility = true;\n }\n } else {\n if (pausedByVisibility) {\n pausedByVisibility = false;\n instance.play();\n }\n }\n }\n\n if (pauseOnHidden) {\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n }\n\n // If the tab is already hidden at construction time, skip auto-start.\n // The visibilitychange listener will resume when the tab becomes visible.\n const actuallyAutoStart = shouldAutoStart && !(pauseOnHidden && document.hidden);\n if (actuallyAutoStart) {\n instance.play();\n } else if (shouldAutoStart) {\n pausedByVisibility = true;\n }\n\n return instance;\n}\n\n/**\n * Creates a sarmal animation directly inside an `<svg>` element using an SVG renderer.\n * The passed `<svg>` element is set to `viewBox=\"0 0 100 100\"` and animated via requestAnimationFrame\n *\n * @example\n * ```ts\n * import { createSarmalSVG, epitrochoid7 } from '@sarmal/core'\n *\n * // <svg id=\"spinner\"></svg> in your HTML\n * const svg = document.getElementById('spinner')\n * const sarmal = createSarmalSVG(svg, epitrochoid7)\n *\n * // To control manually, use autoStart: false\n * const controlled = createSarmalSVG(svg, rose5, { autoStart: false })\n * controlled.play() // Start when ready\n * controlled.pause() // Pause later\n * ```\n */\nexport function createSarmalSVG(\n container: SVGSVGElement,\n curveDef: CurveDef,\n options?: SVGSarmalOptions,\n): SarmalInstance {\n const { trailLength, ...rendererOpts } = options ?? {};\n const engine = createEngine(curveDef, trailLength);\n return createSVGRenderer({ container, engine, ...rendererOpts });\n}\n","import type {\n CurveDef,\n DotMatrixRuntimeRenderOptions,\n DotMatrixSarmalOptions,\n MorphOptions,\n SarmalInstance,\n TrailColor,\n TrailStyle,\n} from \"./types\";\nimport type { Oklab, Rgb } from \"./renderer-shared\";\n\nimport { createEngine } from \"./engine\";\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n colorToRgb,\n computeBoundaries,\n enginePassthroughs,\n getPaletteColor,\n oklabToRgb,\n parseColorToOklab,\n resolveTrailMainColor,\n resolveTrailPalette,\n validateBaseRenderOptions,\n warnIfTrailColorMismatch,\n} from \"./renderer-shared\";\n\n/**\n * Creates a dot matrix renderer for a sarmal animation on a canvas element.\n *\n * The renderer maps the animation's trail to a grid of dots.\n * Each frame, the grid is cleared and rebuilt: dots near the head of the trail are bright,\n * dots near the tail are dim, and dots with no trail activity are barely visible (5% opacity).\n *\n * Grid geometry is derived from `cols` and `rows`.\n * For example, a 240x240 canvas with `cols: 32, rows: 32` produces 1024 dots with cells approximately 7.5x7.5 px each.\n *\n * At init, a pixel mask is computed that records which canvas pixels belong to each dot.\n * Each frame, RGBA values are written directly into a typed array (one entry per lit pixel)\n * and flushed to the canvas with a single `ctx.putImageData` call.\n * Frame cost is flat regardless of how many dots are lit or what grid size is used.\n *\n * @param canvas - The canvas element to draw into.\n * Its `width` and `height` HTML attributes determine the rendering area.\n * CSS display size is not read.\n * @param curveDef - The curve to animate.\n * @param options - Optional configuration for grid size, color, roundness, and lifecycle.\n * @returns A `SarmalInstance` with the standard `play` / `pause` / `destroy` / `morphTo` interface.\n *\n * @example\n * ```ts\n * import { createSarmalDotMatrix, curves } from '@sarmal/core'\n *\n * const instance = createSarmalDotMatrix(canvas, curves.lissajous43, {\n * cols: 32,\n * rows: 32,\n * trailColor: '#2dd4bf',\n * })\n * ```\n */\nexport function createSarmalDotMatrix(\n canvas: HTMLCanvasElement,\n curveDef: CurveDef,\n options?: DotMatrixSarmalOptions,\n): SarmalInstance<DotMatrixRuntimeRenderOptions> {\n const {\n cols = 32,\n rows = 32,\n roundness = 1,\n trailLength: trailLengthOpt,\n trailColor: initialColor = \"#ffffff\",\n trailStyle: initialTrailStyle = \"default\",\n skeletonColor: skeletonColorOpt = \"#ffffff\",\n autoStart = true,\n pauseOnHidden: pauseOnHiddenOpt = true,\n initialPhase,\n } = options ?? {};\n\n const trailLength = trailLengthOpt ?? cols * 3;\n const engine = createEngine(curveDef, trailLength);\n\n if (!canvas.getContext(\"2d\")) {\n throw new Error(\"[sarmal] Could not get 2d context from canvas\");\n }\n const ctx = canvas.getContext(\"2d\")!;\n\n const W = canvas.width;\n const H = canvas.height;\n const cellW = W / cols;\n const cellH = H / rows;\n // Dot radius is 36% of the smaller cell dimension.\n // It is large enough to be clearly visible without adjacent dots overlapping even at coarse grid densities\n const dotR = Math.min(cellW, cellH) * 0.36;\n\n // Oklab palette: always populated by `applyColor()`, used only when `trailStyle !== \"default\"`.\n // Oklab interpolation avoids the gray dead zone that sRGB gradients produce.\n let gradientOklab: Array<Oklab> = [];\n // Primary color in Rgb: always the first (or only) stop of `trailColor`.\n // Used for solid mode and as the background dot hue. Initialized by `applyColor()` in the init block below.\n let colorRgb: Rgb = { r: 255, g: 255, b: 255 };\n let trailStyle: TrailStyle = initialTrailStyle;\n let trailColor: TrailColor = initialColor;\n // Accumulated milliseconds; incremented each frame only in 'gradient-animated' mode.\n let gradientAnimTime = 0;\n\n // Flat buffer: one intensity value (0–1) per grid cell, indexed as row * cols + col.\n // 0 means the trail is not touching this cell,\n // >0 means the trail passes through it,\n // with 1 being the brightest (head of trail) and small values being the dimmest (tail).\n const grid = new Float32Array(cols * rows);\n\n // Coordinate mapping: engine math space to pixel space.\n // Recomputed from the skeleton so the curve fits within the canvas regardless of its range.\n let scale = 1;\n let offsetX = 0;\n let offsetY = 0;\n\n // Pixel mask: flat-packed arrays mapping each dot index to its RGBA byte offsets in canvas pixel space.\n // Computed once at init so `draw()` never needs to do geometry math.\n let pixelMaskStarts: Uint32Array = new Uint32Array(0);\n let pixelMaskLengths: Uint32Array = new Uint32Array(0);\n let pixelMaskIndices: Uint32Array = new Uint32Array(0);\n // Per-pixel antialiasing coverage (0.0–1.0),\n // precomputed through 4x4 SSAA.\n // Interior pixels = 1.0\n // edge pixels have a fraction that fades alpha smoothly.\n let pixelMaskCoverages: Float32Array = new Float32Array(0);\n // bgImageData: all dots at 5% opacity which are restored at the start of every frame. Rebuilt on color change.\n // frameImageData: working buffer, overwritten completely each frame. Allocated once at init.\n let bgImageData: ImageData | null = null;\n let frameImageData: ImageData | null = null;\n\n // Skeleton state: which dots are \"on\" the skeleton, and the parsed skeleton color.\n // `skeletonDotGrid` is a flat boolean mask (0 or 1) over the grid, updated whenever boundaries change.\n // `skeletonColorOklab` is null when skeleton is 'transparent' (disabled)\n let skeletonColorOklab: Oklab | null = null;\n const skeletonDotGrid = new Uint8Array(cols * rows);\n\n let animationId: number | null = null;\n let lastTime = 0;\n let pausedByVisibility = false;\n\n // Morph state: same pattern as the canvas renderer\n let morphResolve: (() => void) | null = null;\n let morphReject: ((error: Error) => void) | null = null;\n let morphDurationMs = DEFAULT_MORPH_DURATION_MS;\n let morphProgress = 0;\n\n /**\n * Pre-computes which canvas pixels belong to each dot using a rounded-rectangle SDF,\n * with 4x4 supersampled antialiasing coverage.\n *\n * For each pixel in every dot's bounding box, 16 sub-sample points are tested against the SDF.\n * The fraction that pass (0.0625–1.0) is stored as that pixel's coverage.\n * Edge pixels fade out smoothly instead of snapping to binary inside/outside,\n * so all dot shapes look correctly antialiased regardless of radius.\n *\n * Results are stored in TypedArrays for cache friendly access in draw().\n * ! Must be called once before `buildBgImageData()`\n */\n function computePixelMask() {\n const starts = new Uint32Array(cols * rows);\n const lengths = new Uint32Array(cols * rows);\n const allIndices: number[] = [];\n const allCoverages: number[] = [];\n const cornerR = roundness * dotR;\n const cornerR2 = cornerR * cornerR;\n // 4x4 SSAA: 16 sub-samples per pixel, each offset by (i+0.5)/4 within the pixel\n const SSAA = 4;\n const SSAA2 = SSAA * SSAA;\n\n for (let row = 0; row < rows; row++) {\n for (let col = 0; col < cols; col++) {\n const dotIdx = row * cols + col;\n const cx = (col + 0.5) * cellW;\n const cy = (row + 0.5) * cellH;\n // Extend bounding box by one pixel so edge sub-samples are captured\n const x0 = Math.max(0, Math.floor(cx - dotR - 1));\n const x1 = Math.min(W - 1, Math.ceil(cx + dotR + 1));\n const y0 = Math.max(0, Math.floor(cy - dotR - 1));\n const y1 = Math.min(H - 1, Math.ceil(cy + dotR + 1));\n\n starts[dotIdx] = allIndices.length;\n let count = 0;\n for (let py = y0; py <= y1; py++) {\n for (let px = x0; px <= x1; px++) {\n let hits = 0;\n for (let sy = 0; sy < SSAA; sy++) {\n const spyCenter = py + (sy + 0.5) / SSAA;\n for (let sx = 0; sx < SSAA; sx++) {\n const spxCenter = px + (sx + 0.5) / SSAA;\n // Generalized rounded-rect SDF:\n // roundness=0 (square), roundness=1 (full circle)\n const dx = Math.max(Math.abs(spxCenter - cx) - (dotR - cornerR), 0);\n const dy = Math.max(Math.abs(spyCenter - cy) - (dotR - cornerR), 0);\n if (dx * dx + dy * dy <= cornerR2) {\n hits++;\n }\n }\n }\n\n if (hits > 0) {\n allIndices.push((py * W + px) * 4);\n allCoverages.push(hits / SSAA2);\n count++;\n }\n }\n }\n lengths[dotIdx] = count;\n }\n }\n\n pixelMaskStarts = starts;\n pixelMaskLengths = lengths;\n pixelMaskIndices = new Uint32Array(allIndices);\n pixelMaskCoverages = new Float32Array(allCoverages);\n }\n\n /**\n * Builds the background ImageData (all dots at 5% opacity).\n * Rebuilt whenever trailColor changes since background dots share the trail hue.\n * ! Must be called after `computePixelMask()`\n */\n function buildBgImageData() {\n bgImageData = new ImageData(W, H);\n\n const bg = colorRgb;\n const baseAlpha = 0.05 * 255;\n const { data } = bgImageData;\n const n = cols * rows;\n\n for (let dotIdx = 0; dotIdx < n; dotIdx++) {\n const start = pixelMaskStarts[dotIdx]!;\n const len = pixelMaskLengths[dotIdx]!;\n\n for (let k = 0; k < len; k++) {\n const px = pixelMaskIndices[start + k]!;\n const coverage = pixelMaskCoverages[start + k]!;\n data[px] = bg.r;\n data[px + 1] = bg.g;\n data[px + 2] = bg.b;\n data[px + 3] = Math.round(baseAlpha * coverage);\n }\n }\n }\n\n function applyColor(color: TrailColor) {\n colorRgb = colorToRgb(resolveTrailMainColor(color));\n gradientOklab = resolveTrailPalette(color).map((c) => parseColorToOklab(c)!);\n }\n\n function applySkeletonColor(color: string) {\n skeletonColorOklab = color === \"transparent\" ? null : parseColorToOklab(color)!;\n }\n\n /**\n * Marks which grid cells the skeleton path passes through.\n * Uses the same `mapPt` + gap-fill logic as `buildGrid` so the skeleton\n * traces the same cells the trail would trace over a full period.\n * Mutates `skeletonDotGrid`. Called at init and whenever boundaries change.\n */\n function computeSkeletonGrid(skel: Array<{ x: number; y: number }>) {\n skeletonDotGrid.fill(0);\n const count = skel.length;\n for (let i = 0; i < count; i++) {\n const pt = skel[i]!;\n const [c, r] = mapPt(pt.x, pt.y);\n skeletonDotGrid[r * cols + c] = 1;\n\n if (i < count - 1) {\n const next = skel[i + 1]!;\n const [nc, nr] = mapPt(next.x, next.y);\n const steps = Math.ceil(Math.max(Math.abs(nc - c), Math.abs(nr - r))) * 2;\n\n for (let s = 1; s < steps; s++) {\n const t = s / steps;\n const ix = pt.x + (next.x - pt.x) * t;\n const iy = pt.y + (next.y - pt.y) * t;\n const [ic, ir] = mapPt(ix, iy);\n skeletonDotGrid[ir * cols + ic] = 1;\n }\n }\n }\n }\n\n /**\n * Writes skeleton dot pixels into `data` at `DEFAULT_SKELETON_OPACITY`, coverage-weighted.\n * If `skeletonColorOklab` is `null` (transparent), nothing happens\n * Called every frame in `draw()` before the trail pass so trail always overwrites skeleton.\n */\n function writeSkeletonPixels(data: Uint8ClampedArray) {\n if (skeletonColorOklab === null) {\n return;\n }\n\n const { r, g, b } = oklabToRgb(skeletonColorOklab);\n const skelBaseAlpha = DEFAULT_SKELETON_OPACITY * 255;\n const n = cols * rows;\n\n for (let dotIdx = 0; dotIdx < n; dotIdx++) {\n if (!skeletonDotGrid[dotIdx]) {\n continue;\n }\n\n const start = pixelMaskStarts[dotIdx]!;\n const len = pixelMaskLengths[dotIdx]!;\n\n for (let k = 0; k < len; k++) {\n const px = pixelMaskIndices[start + k]!;\n const coverage = pixelMaskCoverages[start + k]!;\n data[px] = r;\n data[px + 1] = g;\n data[px + 2] = b;\n data[px + 3] = Math.round(skelBaseAlpha * coverage);\n }\n }\n }\n\n /**\n * Recomputes the scale and offset needed to map engine coordinates into this canvas.\n * The engine produces coordinates in math space (roughly [-1, 1] for most curves, but not always).\n * `computeBoundaries` finds the bounding box of the full curve and\n * returns a uniform scale + centering offset so the curve fills the canvas with consistent padding.\n */\n function calculateBoundaries(skel: Array<{ x: number; y: number }>) {\n const b = computeBoundaries(skel, W, H);\n\n if (b) {\n scale = b.scale;\n offsetX = b.offsetX;\n offsetY = b.offsetY;\n }\n }\n\n /**\n * Maps a point in engine math space to a grid cell index [col, row].\n *\n * The flow is: engine coords to pixel coords (by scale + offset) to grid cell index.\n * The result is clamped so it always falls within the grid bounds.\n */\n function mapPt(x: number, y: number): [number, number] {\n const px = x * scale + offsetX;\n const py = y * scale + offsetY;\n\n return [\n Math.max(0, Math.min(cols - 1, Math.round((px / W) * (cols - 1)))),\n Math.max(0, Math.min(rows - 1, Math.round((py / H) * (rows - 1)))),\n ];\n }\n\n /**\n * Writes an intensity value to a grid cell, keeping whichever is higher.\n * A single cell can be stamped multiple times. The brightest value wins.\n */\n function stamp(c: number, r: number, intensity: number) {\n const idx = r * cols + c;\n\n if (intensity > grid[idx]!) {\n grid[idx] = intensity;\n }\n }\n\n /**\n * Clears the grid and rebuilds it from the current trail.\n *\n * Tail points get low intensity (near 0),\n * the head gets intensity 1\n *\n * Gap fill: consecutive trail points can skip grid cells when the curve moves fast\n * relative to the grid density.\n * This is visible as gaps in the trail at coarse grids.\n *\n * We prevent this by linearly interpolating between adjacent trail points at sub-cell\n * resolution and stamping every intermediate cell.\n */\n function buildGrid(deltaTime: number) {\n const trail = engine.tick(deltaTime);\n const count = engine.trailCount;\n\n grid.fill(0);\n\n for (let i = 0; i < count; i++) {\n const pt = trail[i]!;\n const intensity = (i + 1) / count;\n const [c, r] = mapPt(pt.x, pt.y);\n stamp(c, r, intensity);\n\n if (i < count - 1) {\n const next = trail[i + 1]!;\n const [nc, nr] = mapPt(next.x, next.y);\n // Number of interpolated steps scales with how far apart the two cells are.\n // Multiplying by 2 ensures we never skip a cell even on diagonal moves.\n const steps = Math.ceil(Math.max(Math.abs(nc - c), Math.abs(nr - r))) * 2;\n\n for (let s = 1; s < steps; s++) {\n const t = s / steps;\n const ix = pt.x + (next.x - pt.x) * t;\n const iy = pt.y + (next.y - pt.y) * t;\n const ii = intensity + (1 / count) * t;\n const [ic, ir] = mapPt(ix, iy);\n stamp(ic, ir, ii);\n }\n }\n }\n }\n\n /**\n * Draws the current grid state to the canvas.\n *\n * Restores the background ImageData (all dim dots at 5% opacity),\n * then writes lit dot pixels directly into the frame buffer at their exact intensity and color,\n * flushing once with `putImageData`\n * Total canvas API calls per frame: 1\n */\n function draw() {\n if (!bgImageData || !frameImageData) {\n return;\n }\n\n frameImageData.data.set(bgImageData.data);\n const { data } = frameImageData;\n\n writeSkeletonPixels(data);\n\n const timeOffset = trailStyle === \"gradient-animated\" ? gradientAnimTime * 0.0005 : 0;\n\n const n = cols * rows;\n for (let dotIdx = 0; dotIdx < n; dotIdx++) {\n const intensity = grid[dotIdx]!;\n if (intensity <= 0) {\n continue;\n }\n\n let r: number, g: number, b: number;\n if (trailStyle !== \"default\") {\n ({ r, g, b } = oklabToRgb(getPaletteColor(gradientOklab, intensity, timeOffset)));\n } else {\n ({ r, g, b } = colorRgb);\n }\n // Skeleton dots act as a brightness floor: trail tail (min 8% alpha) must not dim a\n // skeleton dot (15% alpha) since pixels are raw overwrites, not alpha-composited.\n const skelFloor =\n skeletonColorOklab !== null && skeletonDotGrid[dotIdx] === 1\n ? DEFAULT_SKELETON_OPACITY * 255\n : 0;\n const baseA = Math.max(skelFloor, (0.08 + intensity * 0.92) * 255);\n\n const start = pixelMaskStarts[dotIdx]!;\n const len = pixelMaskLengths[dotIdx]!;\n for (let k = 0; k < len; k++) {\n const px = pixelMaskIndices[start + k]!;\n const coverage = pixelMaskCoverages[start + k]!;\n data[px] = r;\n data[px + 1] = g;\n data[px + 2] = b;\n data[px + 3] = Math.round(baseA * coverage);\n }\n }\n\n ctx.putImageData(frameImageData, 0, 0);\n }\n\n function completeMorphNow() {\n engine.completeMorph();\n morphResolve?.();\n morphResolve = null;\n morphReject = null;\n morphProgress = 0;\n }\n\n /**\n * Advances the simulation by `deltaTime` seconds and redraws the canvas.\n * Handles morph progress and live-skeleton boundary updates the same way the canvas renderer does.\n */\n function renderFrame(deltaTime: number) {\n if (engine.morphAlpha !== null) {\n morphProgress = Math.min(1, morphProgress + deltaTime / (morphDurationMs / 1000));\n engine.setMorphAlpha(morphProgress);\n // Boundaries must track the interpolated skeleton during morph so the curve stays centered\n calculateBoundaries(engine.getSarmalSkeleton());\n\n if (morphProgress >= 1) {\n completeMorphNow();\n calculateBoundaries(engine.getSarmalSkeleton());\n }\n computeSkeletonGrid(engine.getSarmalSkeleton());\n } else if (engine.isLiveSkeleton) {\n calculateBoundaries(engine.getSarmalSkeleton());\n computeSkeletonGrid(engine.getSarmalSkeleton());\n }\n\n if (trailStyle === \"gradient-animated\") {\n gradientAnimTime += deltaTime * 1000;\n }\n\n buildGrid(deltaTime);\n draw();\n }\n\n // Accept the rAF timestamp so tests can drive time manually by passing a controlled value.\n // Falls back to performance.now() when called directly (e.g. from play()).\n function loop(timestamp: number = performance.now()) {\n // Cap dt at 1/30s to prevent large jumps after the tab was backgrounded\n const deltaTime = Math.min((timestamp - lastTime) / 1000, 1 / 30);\n lastTime = timestamp;\n renderFrame(deltaTime);\n animationId = requestAnimationFrame(loop);\n }\n\n // ── Init ────────────────────────────────────────────────────────────────────\n\n validateBaseRenderOptions({ trailColor: initialColor, skeletonColor: skeletonColorOpt });\n applyColor(initialColor);\n applySkeletonColor(skeletonColorOpt);\n warnIfTrailColorMismatch(trailColor, trailStyle);\n calculateBoundaries(engine.getSarmalSkeleton());\n computePixelMask();\n computeSkeletonGrid(engine.getSarmalSkeleton());\n frameImageData = new ImageData(W, H);\n buildBgImageData();\n\n if (initialPhase !== undefined) {\n engine.seek(initialPhase);\n }\n\n renderFrame(0);\n\n // ── Instance ─────────────────────────────────────────────────────────────────\n\n const instance: SarmalInstance<DotMatrixRuntimeRenderOptions> = {\n /** Starts the animation loop. Does nothing if already running. */\n play() {\n if (animationId !== null) {\n return;\n }\n\n lastTime = performance.now();\n loop();\n },\n\n /** Pauses the animation loop. Preserves current trail state. */\n pause() {\n if (animationId === null) {\n return;\n }\n\n cancelAnimationFrame(animationId);\n animationId = null;\n engine.cancelSpeedTransition();\n },\n\n /** Resets the animation to the start of the curve and clears the grid. */\n reset() {\n engine.reset();\n grid.fill(0);\n },\n\n /** Stops the animation and removes all event listeners. */\n destroy() {\n if (animationId !== null) {\n cancelAnimationFrame(animationId);\n animationId = null;\n }\n document.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n if (morphReject !== null) {\n morphReject(new Error(\"[sarmal] Instance destroyed during morph\"));\n morphResolve = null;\n morphReject = null;\n }\n },\n\n ...enginePassthroughs(engine),\n\n /**\n * Smoothly transitions from the current curve to `target`.\n * If a morph is already in progress, it is snapped to completion before the new one starts.\n * @returns A Promise that resolves when the transition finishes.\n */\n morphTo(target: CurveDef, opts?: MorphOptions): Promise<void> {\n if (morphResolve !== null) {\n completeMorphNow();\n }\n\n morphDurationMs = opts?.duration ?? DEFAULT_MORPH_DURATION_MS;\n morphProgress = 0;\n engine.startMorph(target, opts?.morphStrategy);\n\n return new Promise<void>((resolve, reject) => {\n morphResolve = resolve;\n morphReject = reject;\n });\n },\n\n /**\n * Updates render options on a live instance without stopping the animation.\n *\n * Supported: `trailColor`, `trailStyle`, and `skeletonColor`.\n * ! Unsupported fields (`headColor`, `headRadius`, `trailWidth`) throw.\n * ! Validation fails the entire call if any field is invalid, leaving options unchanged.\n */\n setRenderOptions(partial: DotMatrixRuntimeRenderOptions): void {\n validateBaseRenderOptions(partial);\n\n let needsRebuildBg = false;\n\n if (partial.trailColor !== undefined) {\n trailColor = partial.trailColor;\n applyColor(trailColor);\n needsRebuildBg = true;\n }\n\n if (partial.skeletonColor !== undefined) {\n applySkeletonColor(partial.skeletonColor);\n }\n\n if (partial.trailStyle !== undefined) {\n trailStyle = partial.trailStyle;\n if (trailStyle === \"default\") {\n gradientAnimTime = 0;\n }\n }\n\n if (needsRebuildBg) {\n buildBgImageData();\n }\n\n if (partial.trailColor !== undefined || partial.trailStyle !== undefined) {\n warnIfTrailColorMismatch(trailColor, trailStyle);\n }\n },\n };\n\n // ── Visibility handling ──────────────────────────────────────────────────────\n\n function handleVisibilityChange() {\n if (document.hidden) {\n if (animationId !== null) {\n instance.pause();\n pausedByVisibility = true;\n }\n } else {\n if (pausedByVisibility) {\n pausedByVisibility = false;\n instance.play();\n }\n }\n }\n\n if (pauseOnHiddenOpt) {\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n }\n\n const shouldAutoStart = autoStart !== false;\n // Skip auto-start if the tab is already hidden. The visibilitychange listener will resume it\n const actuallyAutoStart = shouldAutoStart && !(pauseOnHiddenOpt && document.hidden);\n\n if (actuallyAutoStart) {\n instance.play();\n } else if (shouldAutoStart) {\n pausedByVisibility = true;\n }\n\n return instance;\n}\n","import type { ControlPoint, Point, CurveDef } from \"./types\";\n\n/**\n * One full loop around the spline maps to the parametric interval `[0, 2π)`,\n * matching the convention for built-in curves.\n */\nconst PERIOD = 2 * Math.PI;\n\n/**\n * Evaluates a one-dimensional Catmull-Rom spline segment given four control values.\n * The parameter `u` ranges from 0 (at `p1`) to 1 (at `p2`).\n * `p0` and `p3` are the phantom neighbours that influence the tangent at each endpoint.\n */\nfunction catmullRom1D(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const u2 = u * u;\n const u3 = u2 * u;\n\n // The standard Catmull-Rom matrix form\n return (\n 0.5 *\n (2 * p1 +\n (-p0 + p2) * u +\n (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 +\n (-p0 + 3 * p1 - 3 * p2 + p3) * u3)\n );\n}\n\n/**\n * Evaluates a closed Catmull-Rom spline through every point in `points`\n *\n * The spline treats `points` as a **closed loop**\n * The last point wraps back to the first,\n * and each segment uses a phantom predecessor / successor so the\n * curve passes exactly through every control point.\n *\n * @param points At least 1 point. An empty array yields `(0, 0)`. A single point returns that point for every `phase`\n * @param phase Parametric position along the closed loop. Wraps into `[0, 2π)` automatically, so values outside that range are remapped rather than rejected\n * @returns The `(x, y)` position on the spline at position `phase`\n */\nexport function evaluateCatmullRom(points: Array<ControlPoint>, phase: number): Point {\n const N = points.length;\n\n if (N === 0) {\n return { x: 0, y: 0 };\n }\n\n if (N === 1) {\n return { x: points[0]![0], y: points[0]![1] };\n }\n\n phase = ((phase % PERIOD) + PERIOD) % PERIOD;\n\n const segmentSize = PERIOD / N;\n let i = Math.floor(phase / segmentSize);\n if (i >= N) {\n i = N - 1;\n }\n\n let u = (phase - i * segmentSize) / segmentSize;\n u = Math.max(0, Math.min(1, u));\n\n const p0 = points[(i - 1 + N) % N]!;\n const p1 = points[i]!;\n const p2 = points[(i + 1) % N]!;\n const p3 = points[(i + 2) % N]!;\n\n return {\n x: catmullRom1D(p0[0], p1[0], p2[0], p3[0], u),\n y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u),\n };\n}\n\n/**\n * The returned curve definition produces a closed Catmull-Rom spline that\n * passes through every point in order, looping back from the last point to the first.\n *\n * @param points Array of control points in **normalized `[−1, 1]` space**,\n * matching the playground's draw-mode coordinate system.\n * ! Must contain at least 3 points.\n * @param opts Optional overrides for the returned `CurveDef`.\n * @param opts.name Display name for the curve. Defaults to `\"drawn\"`.\n * @returns A `CurveDef` with `period: 2π` and the spline evaluator as its `fn`.\n * @throws If `points` has fewer than 3 entries.\n *\n * @example\n * ```ts\n * import { createSarmal, drawCurve } from '@sarmal/core'\n *\n * const curve = drawCurve([\n * [-0.5, 0.3],\n * [ 0.2, -0.8],\n * [ 0.7, 0.4],\n * ])\n *\n * createSarmal(canvas, curve)\n * ```\n */\nexport function drawCurve(points: Array<ControlPoint>, opts?: { name?: string }): CurveDef {\n if (points.length < 3) {\n throw new Error(`drawCurve requires at least 3 points, received ${points.length}.`);\n }\n\n const first = points[0]!;\n if (points.every((p) => p[0] === first[0] && p[1] === first[1])) {\n console.warn(\n \"[sarmal].drawCurve: all control points are identical. The curve will be a single point.\",\n );\n }\n\n const maxAbs = points.reduce((m, p) => Math.max(m, Math.abs(p[0]), Math.abs(p[1])), 0);\n if (maxAbs > 2) {\n console.warn(\n `[sarmal].drawCurve: control points extend to ±${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1].`,\n );\n }\n\n const pts = points.map(([x, y]) => [x, y] as ControlPoint);\n\n return {\n name: opts?.name ?? \"drawn\",\n fn: (phase: number) => evaluateCatmullRom(pts, phase),\n period: PERIOD,\n };\n}\n","import type { ControlPoint, CurveDef } from \"../types\";\n\nimport { drawCurve } from \"../catmull-rom\";\n\nconst points: Array<ControlPoint> = [\n [-0.44, -0.45],\n [-0.53, -0.77],\n [-0.82, -0.66],\n [-0.82, -0.18],\n [-0.25, -0.04],\n [0.16, -0.49],\n [-0.03, -0.87],\n [-0.68, -0.94],\n [-0.95, -0.61],\n [-0.87, -0.0],\n [-0.34, 0.21],\n [0.27, -0.04],\n [0.87, 0.06],\n [0.87, 0.57],\n [0.32, 0.66],\n [-0.21, -0.43],\n [-0.43, -0.81],\n [-0.69, -0.84],\n [-0.87, -0.66],\n [-0.9, -0.47],\n [-0.76, -0.35],\n];\n\nexport const artemis2: CurveDef = {\n ...drawCurve(points, { name: \"Artemis II\" }),\n speed: 0.7,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction astroidFn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const c = Math.cos(phase);\n const s = Math.sin(phase);\n return {\n x: c * c * c,\n y: s * s * s,\n };\n}\n\n/**\n * Astroid curve - a 4-cusped hypocycloid\n * Creates a star-like shape with four sharp corners\n */\nexport const astroid: CurveDef = {\n name: \"Astroid\",\n fn: astroidFn,\n period: TWO_PI,\n speed: 1.1,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction deltoidFn(phase: number, _elapsed: number, _params: Record<string, number>) {\n return {\n x: 2 * Math.cos(phase) + Math.cos(2 * phase),\n y: 2 * Math.sin(phase) - Math.sin(2 * phase),\n };\n}\n\n/**\n * Deltoid curve - a 3-cusped hypocycloid\n * Creates a triangular shape with curved sides\n */\nexport const deltoid: CurveDef = {\n name: \"Deltoid\",\n fn: deltoidFn,\n period: TWO_PI,\n speed: 0.9,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction epicycloid3Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n return {\n x: 4 * Math.cos(phase) - Math.cos(4 * phase),\n y: 4 * Math.sin(phase) - Math.sin(4 * phase),\n };\n}\n\n/**\n * Epicycloid with 3 cusps\n * Creates a three-pointed star shape\n */\nexport const epicycloid3: CurveDef = {\n name: \"Epicycloid (n=3)\",\n fn: epicycloid3Fn,\n period: TWO_PI,\n speed: 0.75,\n};\n","import type { CurveDef, Point } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction epitrochoid7Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const d = 1.0 + 0.55 * Math.sin(phase * 0.5);\n return {\n x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),\n y: 7 * Math.sin(phase) - d * Math.sin(7 * phase),\n };\n}\n\nfunction epitrochoid7SkeletonFn(phase: number): Point {\n // average of the oscillating range for a stable base shape\n const d = 1.275;\n return {\n x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),\n y: 7 * Math.sin(phase) - d * Math.sin(7 * phase),\n };\n}\n\n/**\n * Epitrochoid with 7 lobes and dynamic variation\n * Creates a flower-like pattern with undulating petals\n */\nexport const epitrochoid7: CurveDef = {\n name: \"Epitrochoid\",\n fn: epitrochoid7Fn,\n period: TWO_PI,\n speed: 1.4,\n skeletonFn: epitrochoid7SkeletonFn,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction lissajous32Fn(phase: number, elapsed: number, _params: Record<string, number>) {\n const phi = elapsed * 0.45;\n return {\n x: Math.sin(3 * phase + phi),\n y: Math.sin(2 * phase),\n };\n}\n\n/**\n * Lissajous curve with frequency ratio 3:2\n * Creates a figure-eight-like pattern with live skeleton\n */\nexport const lissajous32: CurveDef = {\n name: \"Lissajous 3:2\",\n fn: lissajous32Fn,\n period: TWO_PI,\n speed: 2.0,\n skeleton: \"live\",\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction lissajous43Fn(phase: number, elapsed: number, _params: Record<string, number>) {\n const phi = elapsed * 0.38;\n return {\n x: Math.sin(4 * phase + phi),\n y: Math.sin(3 * phase),\n };\n}\n\n/**\n * Lissajous curve with frequency ratio 4:3\n * Creates a complex interweaving pattern with live skeleton\n */\nexport const lissajous43: CurveDef = {\n name: \"Lissajous 4:3\",\n fn: lissajous43Fn,\n period: TWO_PI,\n speed: 1.8,\n skeleton: \"live\",\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction lameFn(phase: number, elapsed: number, _params: Record<string, number>) {\n const p = 1.75 + 1.25 * Math.sin(elapsed * 0.48);\n const c = Math.cos(phase),\n s = Math.sin(phase);\n return {\n x: Math.sign(c) * Math.pow(Math.abs(c), p),\n y: Math.sign(s) * Math.pow(Math.abs(s), p),\n };\n}\n\n/**\n * Lamé curve (superellipse) with time-varying exponent\n * Creates a squircle-like shape that morphs over time\n */\nexport const lame: CurveDef = {\n name: \"Lamé Curve\",\n fn: lameFn,\n period: TWO_PI,\n speed: 1.0,\n skeleton: \"live\",\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction rose3Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r = Math.cos(3 * phase);\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * Rose curve with 3 petals\n * Creates a three-petaled flower pattern\n */\nexport const rose3: CurveDef = {\n name: \"Rose (n=3)\",\n fn: rose3Fn,\n period: TWO_PI,\n speed: 1.15,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction rose5Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r = Math.cos(5 * phase);\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * Rose curve with 5 petals\n * Creates a five-petaled flower pattern\n */\nexport const rose5: CurveDef = {\n name: \"Rose (n=5)\",\n fn: rose5Fn,\n period: TWO_PI,\n speed: 1.0,\n};\n","import type { CurveDef } from \"../types\";\n\nconst FOUR_PI = Math.PI * 4;\n\nfunction rose52Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r = Math.cos((5 / 2) * phase);\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * Rose curve with n=5/2 that traces 5 petals over two full revolutions\n * The head passes through the center between petals, creating elegant crossing trails.\n */\nexport const rose52: CurveDef = {\n name: \"Rose (n=5/2)\",\n fn: rose52Fn,\n period: FOUR_PI,\n speed: 0.8,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction starFn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r =\n Math.abs(Math.cos((5 / 2) * phase)) +\n 0.35 * Math.abs(Math.cos((15 / 2) * phase)) +\n 0.15 * Math.abs(Math.cos((25 / 2) * phase));\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * 5-pointed star based on Fourier harmonics.\n */\nexport const star: CurveDef = {\n name: \"Star\",\n fn: starFn,\n period: TWO_PI,\n speed: 1.0,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction star4Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r =\n Math.abs(Math.cos(2 * phase)) +\n 0.35 * Math.abs(Math.cos(6 * phase)) +\n 0.15 * Math.abs(Math.cos(10 * phase));\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * 4-pointed star based on Fourier harmonics.\n * Same construction as `star` but with base frequency `2*phase`, producing 4 tips.\n */\nexport const star4: CurveDef = {\n name: \"Star (4-arm)\",\n fn: star4Fn,\n period: TWO_PI,\n speed: 1.0,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction star7Fn(phase: number, _elapsed: number, _params: Record<string, number>) {\n const r =\n Math.abs(Math.cos((7 / 2) * phase)) +\n 0.35 * Math.abs(Math.cos((21 / 2) * phase)) +\n 0.15 * Math.abs(Math.cos((35 / 2) * phase));\n return {\n x: r * Math.cos(phase),\n y: r * Math.sin(phase),\n };\n}\n\n/**\n * 7-pointed star based on Fourier harmonics.\n * Same construction as `star` but with base frequency `7*phase/2`, producing 7 tips.\n */\nexport const star7: CurveDef = {\n name: \"Star (7-arm)\",\n fn: star7Fn,\n period: TWO_PI,\n speed: 1.0,\n};\n","// Individual curve exports for tree-shaking\nexport { artemis2 } from \"./artemis2\";\nexport { astroid } from \"./astroid\";\nexport { deltoid } from \"./deltoid\";\nexport { epicycloid3 } from \"./epicycloid3\";\nexport { epitrochoid7 } from \"./epitrochoid7\";\nexport { lissajous32 } from \"./lissajous32\";\nexport { lissajous43 } from \"./lissajous43\";\nexport { lame } from \"./lame\";\nexport { rose3 } from \"./rose3\";\nexport { rose5 } from \"./rose5\";\nexport { rose52 } from \"./rose52\";\nexport { star } from \"./star\";\nexport { star4 } from \"./star4\";\nexport { star7 } from \"./star7\";\n\n// Bulk export for convenience\n// >> Standard\nimport { rose3 } from \"./rose3\";\nimport { rose5 } from \"./rose5\";\nimport { rose52 } from \"./rose52\";\nimport { star } from \"./star\";\nimport { star4 } from \"./star4\";\nimport { star7 } from \"./star7\";\nimport { astroid } from \"./astroid\";\nimport { deltoid } from \"./deltoid\";\nimport { epicycloid3 } from \"./epicycloid3\";\nimport { epitrochoid7 } from \"./epitrochoid7\";\nimport { lissajous32 } from \"./lissajous32\";\nimport { lissajous43 } from \"./lissajous43\";\nimport { lame } from \"./lame\";\n// >> Iconic\nimport { artemis2 } from \"./artemis2\";\n\n/**\n * Collection of all built-in sarmal curves\n * Import individual curves for better tree-shaking\n */\nexport const curves = {\n artemis2,\n epitrochoid7,\n astroid,\n deltoid,\n rose3,\n rose5,\n rose52,\n star,\n star4,\n star7,\n lissajous32,\n lissajous43,\n epicycloid3,\n lame,\n} as const;\nexport type CurveName = keyof typeof curves;\n","import type { CurveDef, SarmalInstance, SarmalOptions } from \"./types\";\nexport type { SVGRendererOptions, SVGSarmalOptions } from \"./renderer-svg\";\nexport type {\n BaseRendererOptions,\n BaseRuntimeRenderOptions,\n Point,\n CurveDef,\n Engine,\n SarmalInstance,\n JumpOptions,\n SeekOptions,\n RendererOptions,\n SarmalOptions,\n TrailStyle,\n TrailColor,\n MorphStrategy,\n RuntimeRenderOptions,\n DotMatrixRuntimeRenderOptions,\n BaseInit,\n CanvasInit,\n DotMatrixInit,\n BaseSarmalOptions,\n BaseDotMatrixOptions,\n DotMatrixSarmalOptions,\n} from \"./types\";\nexport type { CurveName } from \"./curves\";\nexport type { SarmalPalette, BoundaryResult } from \"./renderer-shared\";\n\nexport { createEngine } from \"./engine\";\nexport { createRenderer } from \"./renderer\";\nexport { createSVGRenderer, createSarmalSVG } from \"./renderer-svg\";\nexport { createSarmalDotMatrix } from \"./renderer-dot-matrix\";\nexport { curves } from \"./curves\";\nexport { palettes, computeBoundaries } from \"./renderer-shared\";\nexport { drawCurve, evaluateCatmullRom } from \"./catmull-rom\";\nexport {\n artemis2,\n epitrochoid7,\n astroid,\n deltoid,\n rose5,\n rose3,\n lissajous32,\n lissajous43,\n epicycloid3,\n lame,\n} from \"./curves\";\n\nimport { createEngine } from \"./engine\";\nimport { createRenderer } from \"./renderer\";\n\n/**\n * Creates a sarmal animation on a canvas element\n *\n * @example\n * ```ts\n * import { createSarmal, rose3 } from '@sarmal/core'\n * const sarmal = createSarmal(canvas, rose3)\n *\n * // To control manually, use autoStart: false\n * const controlled = createSarmal(canvas, rose3, { autoStart: false })\n * controlled.play() // Start when ready\n * controlled.pause() // Pause later\n * ```\n */\nexport function createSarmal(\n canvas: HTMLCanvasElement,\n curveDef: CurveDef,\n options?: SarmalOptions,\n): SarmalInstance {\n const { trailLength, ...rendererOpts } = options ?? {};\n const engine = createEngine(curveDef, trailLength);\n\n return createRenderer({ canvas, engine, ...rendererOpts });\n}\n"]}
|