@sarmal/core 0.29.1 → 0.30.0
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/dist/auto-init.cjs +72 -31
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.js +72 -31
- package/dist/auto-init.js.map +1 -1
- package/dist/cli.js +31 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +72 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +72 -31
- package/dist/index.js.map +1 -1
- package/dist/terminal.cjs +33 -4
- package/dist/terminal.cjs.map +1 -1
- package/dist/terminal.d.cts +1 -1
- package/dist/terminal.d.ts +1 -1
- package/dist/terminal.js +33 -4
- package/dist/terminal.js.map +1 -1
- package/package.json +1 -1
- package/skills/core/SKILL.md +1 -1
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/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, MorpStrategy, 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: MorpStrategy = \"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: MorpStrategy = \"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 { Engine, Point, RuntimeRenderOptions, TrailColor, TrailStyle } 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) return null;\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 sunset: [\"#f97316\", \"#dc2626\", \"#9333ea\", \"#f472b6\"],\n ocean: [\"#1e3a8a\", \"#06b6d4\", \"#22d3ee\", \"#e0f2fe\"],\n ice: [\"#1e3a8a\", \"#67e8f9\"],\n fire: [\"#7f1d1d\", \"#fbbf24\"],\n forest: [\"#14532d\", \"#86efac\"],\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\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\ninterface 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 */\nfunction 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 */\nfunction 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 sRGB colors in OKLab space without any gray dead zone */\nexport const lerpOklab = (a: Rgb, b: Rgb, t: number) => {\n if (t <= 0) {\n return a;\n }\n\n if (t >= 1) {\n return b;\n }\n\n const la = rgbToOklab(a),\n lb = rgbToOklab(b);\n return oklabToRgb({\n L: la.L + (lb.L - la.L) * t,\n a: la.a + (lb.a - la.a) * t,\n b: la.b + (lb.b - la.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 hex color strings\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: string[], position: number, timeOffset: number = 0): Rgb {\n if (palette.length === 0) {\n return { r: 255, g: 255, b: 255 };\n }\n\n if (palette.length === 1) {\n return hexToRgb(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 = hexToRgb(palette[idx % palette.length]!);\n const c2 = hexToRgb(palette[(idx + 1) % palette.length]!);\n\n return lerpOklab(c1, c2, t);\n}\n\nconst HEX_COLOR_RE = /^#[0-9a-fA-F]{6}$/;\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 RENDER_OPTION_KEYS: ReadonlySet<string> = new Set([\n \"trailColor\",\n \"headColor\",\n \"skeletonColor\",\n \"trailStyle\",\n \"headRadius\",\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}\n\nfunction assertTrailColor(value: TrailColor) {\n if (typeof value === \"string\") {\n if (!HEX_COLOR_RE.test(value)) {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, 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\" || !HEX_COLOR_RE.test(entry)) {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`,\n );\n }\n }\n return;\n }\n\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex 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\" || !HEX_COLOR_RE.test(value)) {\n throw new TypeError(\n `[sarmal] setRenderOptions: headColor must be a 6-digit hex string 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\" || !HEX_COLOR_RE.test(value)) {\n throw new TypeError(\n `[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string 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\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 // TODO: should it return hex here instead of rgb?\n return resolveTrailMainColor(trailColor);\n }\n\n const palette = resolveTrailPalette(trailColor);\n const last = palette[palette.length - 1]!;\n const { r, g, b } = hexToRgb(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\";\n\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n computeBoundaries,\n computeTrailQuad,\n enginePassthroughs,\n getPaletteColor,\n resolveHeadColor,\n resolveTrailPalette,\n resolveTrailMainColor,\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, hexToRgb, lerpOklab, getPaletteColor } from \"./renderer-shared\";\n\nconst WHITE_HEX = \"#ffffff\";\n\n// TODO: accept rgb(a)\nexport function hexToRgbComponents(hex: string): string {\n const n = parseInt(hex.slice(1), 16);\n return `${n >> 16},${(n >> 8) & 255},${n & 255}`;\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 = hexToRgbComponents(resolveTrailMainColor(trailColor));\n let trailPalette = resolveTrailPalette(trailColor);\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 let headRadius = options.headRadius ?? getHeadDotRadius(logicalWidth, logicalHeight);\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(${hexToRgbComponents(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(${hexToRgbComponents(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(${hexToRgbComponents(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 );\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 color = getPaletteColor(trailPalette, progress, timeOffset);\n ctx.fillStyle = `rgba(${color.r},${color.g},${color.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) {\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) {\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 = hexToRgbComponents(resolveTrailMainColor(trailColor));\n trailPalette = resolveTrailPalette(trailColor);\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 (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 getPaletteColor,\n resolveHeadColor,\n resolveTrailPalette,\n resolveTrailMainColor,\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\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 = resolveTrailMainColor(trailColor);\n let trailPalette: string[] = resolveTrailPalette(trailColor);\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 headRadius = options.headRadius ?? SVG_DEFAULT_HEAD_RADIUS;\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(\"stroke\", skeletonColor);\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(\"stroke\", skeletonColor);\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(\"stroke\", skeletonColor);\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\", 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,\n svgTrailMaxWidth,\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 } = getPaletteColor(trailPalette, 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 = resolveTrailMainColor(trailColor);\n trailPalette = resolveTrailPalette(trailColor);\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 // TODO: what happens when `skeletonColor` is set to \"transparent\" during morph? Do the skeleton paths of A and B still render?\n skeletonPath.setAttribute(\"visibility\", \"hidden\");\n } else {\n skeletonPath.setAttribute(\"stroke\", skeletonColor);\n skeletonPath.removeAttribute(\"visibility\");\n skeletonPathA.setAttribute(\"stroke\", skeletonColor);\n skeletonPathB.setAttribute(\"stroke\", 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 (userHeadColor === null) {\n headColor = resolveHeadColor(trailColor, trailStyle);\n } else {\n headColor = userHeadColor;\n }\n headCircle.setAttribute(\"fill\", 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 { 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 Point,\n CurveDef,\n Engine,\n SarmalInstance,\n JumpOptions,\n SeekOptions,\n RendererOptions,\n SarmalOptions,\n TrailStyle,\n TrailColor,\n RuntimeRenderOptions,\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 { 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/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, MorpStrategy, 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: MorpStrategy = \"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: MorpStrategy = \"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 { Engine, Point, RuntimeRenderOptions, TrailColor, TrailStyle } 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) return null;\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 sunset: [\"#f97316\", \"#dc2626\", \"#9333ea\", \"#f472b6\"],\n ocean: [\"#1e3a8a\", \"#06b6d4\", \"#22d3ee\", \"#e0f2fe\"],\n ice: [\"#1e3a8a\", \"#67e8f9\"],\n fire: [\"#7f1d1d\", \"#fbbf24\"],\n forest: [\"#14532d\", \"#86efac\"],\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\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\ninterface 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 */\nfunction 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 */\nfunction 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 sRGB colors in OKLab space without any gray dead zone */\nexport const lerpOklab = (a: Rgb, b: Rgb, t: number) => {\n if (t <= 0) {\n return a;\n }\n\n if (t >= 1) {\n return b;\n }\n\n const la = rgbToOklab(a),\n lb = rgbToOklab(b);\n return oklabToRgb({\n L: la.L + (lb.L - la.L) * t,\n a: la.a + (lb.a - la.a) * t,\n b: la.b + (lb.b - la.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 hex color strings\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: string[], position: number, timeOffset: number = 0): Rgb {\n if (palette.length === 0) {\n return { r: 255, g: 255, b: 255 };\n }\n\n if (palette.length === 1) {\n return hexToRgb(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 = hexToRgb(palette[idx % palette.length]!);\n const c2 = hexToRgb(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 RENDER_OPTION_KEYS: ReadonlySet<string> = new Set([\n \"trailColor\",\n \"headColor\",\n \"skeletonColor\",\n \"trailStyle\",\n \"headRadius\",\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}\n\nfunction assertTrailColor(value: TrailColor) {\n if (typeof value === \"string\") {\n if (parseColorToRgb(value) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()), 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\" || parseColorToRgb(entry) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: trailColor[${i}] must be a valid color string (#rrggbb, #rgb, rgb(), rgba()), 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()) 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\" || parseColorToRgb(value) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: headColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) 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\" || parseColorToRgb(value) === null) {\n throw new TypeError(\n `[sarmal] setRenderOptions: skeletonColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) 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\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 } = parseColorToRgb(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\";\n\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n computeBoundaries,\n computeTrailQuad,\n enginePassthroughs,\n getPaletteColor,\n parseColorToRgb,\n resolveHeadColor,\n resolveTrailPalette,\n resolveTrailMainColor,\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, hexToRgb, lerpOklab, getPaletteColor } from \"./renderer-shared\";\n\nconst WHITE_HEX = \"#ffffff\";\n\nexport function colorToRgbComponents(color: string): string {\n const c = parseColorToRgb(color)!;\n return `${c.r},${c.g},${c.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\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 let headRadius = options.headRadius ?? getHeadDotRadius(logicalWidth, logicalHeight);\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 );\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 color = getPaletteColor(trailPalette, progress, timeOffset);\n ctx.fillStyle = `rgba(${color.r},${color.g},${color.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 }\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 (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 getPaletteColor,\n parseColorToRgb,\n resolveHeadColor,\n resolveTrailPalette,\n resolveTrailMainColor,\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 c = parseColorToRgb(color)!;\n return `rgb(${c.r},${c.g},${c.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\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 headRadius = options.headRadius ?? SVG_DEFAULT_HEAD_RADIUS;\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,\n svgTrailMaxWidth,\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 } = getPaletteColor(trailPalette, 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\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 (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 { 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 Point,\n CurveDef,\n Engine,\n SarmalInstance,\n JumpOptions,\n SeekOptions,\n RendererOptions,\n SarmalOptions,\n TrailStyle,\n TrailColor,\n RuntimeRenderOptions,\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 { 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"]}
|