@sarmal/core 0.13.0 → 0.14.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.
Files changed (61) hide show
  1. package/dist/auto-init.cjs +84 -89
  2. package/dist/auto-init.cjs.map +1 -1
  3. package/dist/auto-init.d.cts +2 -1
  4. package/dist/auto-init.d.ts +2 -1
  5. package/dist/auto-init.js +83 -88
  6. package/dist/auto-init.js.map +1 -1
  7. package/dist/curves/artemis2.cjs +7 -10
  8. package/dist/curves/artemis2.d.cts +1 -1
  9. package/dist/curves/artemis2.d.ts +1 -1
  10. package/dist/curves/artemis2.js +6 -9
  11. package/dist/curves/astroid.cjs +4 -4
  12. package/dist/curves/astroid.d.cts +1 -1
  13. package/dist/curves/astroid.d.ts +1 -1
  14. package/dist/curves/astroid.js +3 -3
  15. package/dist/curves/deltoid.cjs +4 -4
  16. package/dist/curves/deltoid.d.cts +1 -1
  17. package/dist/curves/deltoid.d.ts +1 -1
  18. package/dist/curves/deltoid.js +3 -3
  19. package/dist/curves/epicycloid3.cjs +4 -4
  20. package/dist/curves/epicycloid3.d.cts +1 -1
  21. package/dist/curves/epicycloid3.d.ts +1 -1
  22. package/dist/curves/epicycloid3.js +3 -3
  23. package/dist/curves/epitrochoid7.cjs +5 -5
  24. package/dist/curves/epitrochoid7.d.cts +1 -1
  25. package/dist/curves/epitrochoid7.d.ts +1 -1
  26. package/dist/curves/epitrochoid7.js +4 -4
  27. package/dist/curves/index.cjs +28 -32
  28. package/dist/curves/index.d.cts +21 -21
  29. package/dist/curves/index.d.ts +21 -21
  30. package/dist/curves/index.js +28 -44
  31. package/dist/curves/lame.cjs +5 -6
  32. package/dist/curves/lame.d.cts +1 -1
  33. package/dist/curves/lame.d.ts +1 -1
  34. package/dist/curves/lame.js +4 -5
  35. package/dist/curves/lissajous32.cjs +4 -4
  36. package/dist/curves/lissajous32.d.cts +1 -1
  37. package/dist/curves/lissajous32.d.ts +1 -1
  38. package/dist/curves/lissajous32.js +3 -3
  39. package/dist/curves/lissajous43.cjs +4 -4
  40. package/dist/curves/lissajous43.d.cts +1 -1
  41. package/dist/curves/lissajous43.d.ts +1 -1
  42. package/dist/curves/lissajous43.js +3 -3
  43. package/dist/curves/rose3.cjs +4 -4
  44. package/dist/curves/rose3.d.cts +1 -1
  45. package/dist/curves/rose3.d.ts +1 -1
  46. package/dist/curves/rose3.js +3 -3
  47. package/dist/curves/rose5.cjs +4 -4
  48. package/dist/curves/rose5.d.cts +1 -1
  49. package/dist/curves/rose5.d.ts +1 -1
  50. package/dist/curves/rose5.js +3 -3
  51. package/dist/index.cjs +98 -90
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.cts +23 -58
  54. package/dist/index.d.ts +23 -58
  55. package/dist/index.js +98 -107
  56. package/dist/index.js.map +1 -1
  57. package/dist/types-BQosOzlf.d.cts +276 -0
  58. package/dist/types-BQosOzlf.d.ts +276 -0
  59. package/package.json +1 -1
  60. package/dist/types-BW0bpL1Z.d.cts +0 -290
  61. package/dist/types-BW0bpL1Z.d.ts +0 -290
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/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/index.ts","../src/index.ts"],"names":["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 — 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 (time `t`), 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 t = 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 `sampleT` */\n function sampleSkeleton(c: ResolvedCurve, sampleT: number): Point {\n if (c.skeletonFn) {\n return c.skeletonFn(sampleT);\n }\n if (c.skeleton === \"live\") {\n return c.fn(sampleT, actualTime, EMPTY_PARAMS);\n }\n return c.fn(sampleT, 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 t = (t + effectiveSpeed * deltaTime) % curve.period;\n actualTime += deltaTime;\n\n if (morphCurveB !== null && _morphAlpha !== null) {\n const a = curve.fn(t, actualTime, EMPTY_PARAMS);\n const tB = _morphStrategy === \"normalized\" ? (t / curve.period) * morphCurveB.period : t;\n const b = morphCurveB.fn(tB, 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(t, 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 isLiveSkeleton() {\n return curve.skeleton === \"live\";\n },\n\n get morphAlpha() {\n return _morphAlpha;\n },\n\n reset() {\n t = 0;\n actualTime = 0;\n trail.clear();\n },\n\n jump(newT: number, { clearTrail = false }: JumpOptions = {}) {\n t = ((newT % curve.period) + curve.period) % curve.period;\n if (clearTrail) {\n trail.clear();\n }\n },\n\n seek(targetT: number, { wrap = false, step = curve.period / trailLength }: SeekOptions = {}) {\n const advance = curve.speed * step;\n const target = ((targetT % curve.period) + curve.period) % curve.period;\n const targetTime = target / curve.speed;\n\n t = 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 sampleT = target - i * advance;\n const wrappedT = ((sampleT % curve.period) + curve.period) % curve.period;\n const time = targetTime - i * step;\n const point = curve.fn(wrappedT, time, 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: (sampleT: number, time: number, params: Record<string, number>) => {\n const a = frozenA.fn(sampleT, time, params);\n const tB =\n frozenStrategy === \"normalized\"\n ? (sampleT / frozenA.period) * frozenB.period\n : sampleT;\n const b = frozenB.fn(tB, time, params);\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 `tB` = `(t / periodA) * periodB`\n // Remap `t` so the trail continues from the same position on `curveB`,\n // not from a raw `t` value that belongs to `curveA`'s smaller range.\n if (_morphStrategy === \"normalized\" && curve.period !== morphCurveB.period) {\n t = (t / 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 sampleT = (i / (steps - 1)) * curve.period;\n const a = sampleSkeleton(curve, sampleT);\n const tB =\n _morphStrategy === \"normalized\"\n ? (sampleT / curve.period) * morphCurveB.period\n : sampleT;\n const b = sampleSkeleton(morphCurveB, tB);\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 sampleT = (i / (steps - 1)) * curve.period;\n points[i] = sampleSkeleton(curve, sampleT);\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 } 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/** Stroke/line width at the tail */\nexport const TRAIL_MIN_WIDTH = 0.5;\n/** Stroke/line width at the head */\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 pixel-space quad corners and style for one ribbon segment.\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): 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 = (TRAIL_MIN_WIDTH + progress * (TRAIL_MAX_WIDTH - TRAIL_MIN_WIDTH)) / 2;\n const w1 = (TRAIL_MIN_WIDTH + nextProgress * (TRAIL_MAX_WIDTH - TRAIL_MIN_WIDTH)) / 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, FIT_PADDING_MIN)`, so the stricter constraint wins\n */\nexport function computeBoundaries(\n pts: Point[],\n logicalWidth: number,\n logicalHeight: number,\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 - FIT_PADDING_MIN * 2) / w;\n const scaleYMinPadding = (logicalHeight - FIT_PADDING_MIN * 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 };\n}\n","import type {\n CurveDef,\n MorphOptions,\n PalettePreset,\n Point,\n RendererOptions,\n SarmalInstance,\n TrailStyle,\n} from \"./types\";\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n computeBoundaries,\n computeTrailQuad,\n enginePassthroughs,\n} from \"./renderer-shared\";\n\n// Re-exported so existing test imports (renderer.test.ts) keep working\nexport { computeTangent, computeNormal, TrailPoint } from \"./renderer-shared\";\n\nconst DEFAULT_SKELETON_COLOR = \"#ffffff\";\n\nconst GRADIENT = {\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};\n\nconst PRESETS: Record<PalettePreset, string[]> = {\n bard: GRADIENT.bard,\n sunset: GRADIENT.sunset,\n ocean: GRADIENT.ocean,\n ice: GRADIENT.ice,\n fire: GRADIENT.fire,\n forest: GRADIENT.forest,\n};\n\n// ? exported for testing\nexport interface Rgb {\n r: number;\n g: number;\n b: number;\n}\n\n// ? exported for testing\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// ? exported for testing\nexport const lerpRgb = (a: Rgb, b: Rgb, t: number) => ({\n r: Math.round(a.r + (b.r - a.r) * t),\n g: Math.round(a.g + (b.g - a.g) * t),\n b: Math.round(a.b + (b.b - a.b) * t),\n});\n\n/**\n * Gets a color from a palette based on position (0-1) with optional time-based cycling\n * ? Exported for testing.\n */\nexport function getPaletteColor(palette: string[], position: number, timeOffset: number = 0): Rgb {\n if (palette.length === 0) return { r: 255, g: 255, b: 255 };\n if (palette.length === 1) return hexToRgb(palette[0]!);\n\n const cyclePos = (position + timeOffset) % 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 lerpRgb(c1, c2, t);\n}\n\n// ? exported for testing\nexport function resolvePalette(\n palette: PalettePreset | string[] | undefined,\n trailStyle: TrailStyle,\n): string[] {\n if (Array.isArray(palette)) return palette;\n if (palette && palette in PRESETS) return PRESETS[palette as PalettePreset]!;\n return trailStyle === \"gradient-animated\" ? GRADIENT.bard : GRADIENT.ice;\n}\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 const trailStyle: TrailStyle = options.trailStyle ?? \"default\";\n const trailColor = options.trailColor ?? \"#ffffff\";\n const palette = resolvePalette(options.palette, trailStyle);\n\n function defaultHeadColor(): string {\n if (trailStyle !== \"default\") {\n const { r, g, b } = getPaletteColor(palette, 1.0);\n return `rgb(${r},${g},${b})`;\n }\n return trailColor;\n }\n\n const opts = {\n skeletonColor: options.skeletonColor ?? DEFAULT_SKELETON_COLOR,\n trailColor,\n headColor: options.headColor ?? defaultHeadColor(),\n };\n\n const trailRgb = hexToRgbComponents(opts.trailColor);\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 rect = canvas.getBoundingClientRect();\n const lw = rect.width || 200;\n const lh = rect.height || 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\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\n let morphResolve: (() => 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) return;\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(opts.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) return;\n ctx.strokeStyle = `rgba(${hexToRgbComponents(opts.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 (opts.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(opts.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(${trailRgb},${opacity})`;\n } else {\n const timeOffset = trailStyle === \"gradient-animated\" ? gradientAnimTime * 0.0005 : 0;\n const color = getPaletteColor(palette, 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 =\n options.headRadius ?? Math.max(2, 3 * Math.sqrt(Math.min(logicalWidth, logicalHeight) / 160));\n\n ctx.fillStyle = opts.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 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 initialT option: seek to the specified position before first frame\n if (options.initialT !== undefined) {\n engine.seek(options.initialT);\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\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 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) => {\n morphResolve = resolve;\n });\n },\n };\n\n if (shouldAutoStart) {\n instance.play();\n }\n\n return instance;\n}\n","import type {\n BaseRendererOptions,\n CurveDef,\n Engine,\n MorphOptions,\n Point,\n SarmalInstance,\n} from \"./types\";\n\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n computeBoundaries,\n computeTrailQuad,\n enginePassthroughs,\n} from \"./renderer-shared\";\nimport { createEngine } from \"./engine\";\n\nexport interface SVGRendererOptions extends BaseRendererOptions {\n /** Container element that will contain the SVG */\n container: Element;\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}\n/** Maximum number of trail segment paths pre-created for the ribbon */\nconst MAX_TRAIL_SEGMENTS = 200;\n\nconst EMPTY_PARAMS: Record<string, number> = {};\n\nfunction pointsToPathString(pts: Point[], scale: number, offsetX: number, offsetY: number): string {\n if (pts.length < 2) return \"\";\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 for (let i = 1; i < pts.length; i++) {\n d += ` L${px(pts[i]!)} ${py(pts[i]!)}`;\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 for (let i = 0; i < samples; i++) {\n const t = (i / (samples - 1)) * period;\n pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(t) : curveDef.fn(t, 0, EMPTY_PARAMS);\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 trailColor = options.trailColor ?? \"#ffffff\";\n const opts = {\n skeletonColor: options.skeletonColor ?? \"#ffffff\",\n trailColor,\n headColor: options.headColor ?? trailColor,\n ariaLabel: options.ariaLabel ?? \"Loading\",\n };\n\n const rect = container.getBoundingClientRect();\n const width = rect.width || 200;\n const height = rect.height || 200;\n const headRadius =\n options.headRadius ?? Math.max(2, 3 * Math.sqrt(Math.min(width, height) / 160));\n\n const svg = el(\"svg\") as SVGSVGElement;\n svg.setAttribute(\"width\", String(width));\n svg.setAttribute(\"height\", String(height));\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svg.setAttribute(\"role\", \"img\");\n svg.setAttribute(\"aria-label\", opts.ariaLabel);\n\n const titleEl = el(\"title\");\n titleEl.textContent = opts.ariaLabel;\n svg.appendChild(titleEl);\n\n const skeletonPath = el(\"path\") as SVGPathElement;\n skeletonPath.setAttribute(\"fill\", \"none\");\n skeletonPath.setAttribute(\"stroke\", opts.skeletonColor);\n skeletonPath.setAttribute(\"stroke-opacity\", String(DEFAULT_SKELETON_OPACITY));\n skeletonPath.setAttribute(\"stroke-width\", \"1.5\");\n svg.appendChild(skeletonPath);\n\n const skeletonPathA = el(\"path\") as SVGPathElement;\n skeletonPathA.setAttribute(\"fill\", \"none\");\n skeletonPathA.setAttribute(\"stroke\", opts.skeletonColor);\n skeletonPathA.setAttribute(\"stroke-width\", \"1.5\");\n skeletonPathA.setAttribute(\"visibility\", \"hidden\");\n svg.appendChild(skeletonPathA);\n\n const skeletonPathB = el(\"path\") as SVGPathElement;\n skeletonPathB.setAttribute(\"fill\", \"none\");\n skeletonPathB.setAttribute(\"stroke\", opts.skeletonColor);\n skeletonPathB.setAttribute(\"stroke-width\", \"1.5\");\n skeletonPathB.setAttribute(\"visibility\", \"hidden\");\n svg.appendChild(skeletonPathB);\n\n let morphPathABuilt = \"\";\n let morphPathBBuilt = \"\";\n\n const trailPaths: SVGPathElement[] = [];\n for (let i = 0; i < MAX_TRAIL_SEGMENTS; i++) {\n const path = el(\"path\") as SVGPathElement;\n path.setAttribute(\"fill\", opts.trailColor);\n svg.appendChild(path);\n trailPaths.push(path);\n }\n\n const headCircle = el(\"circle\") as SVGCircleElement;\n headCircle.setAttribute(\"fill\", opts.headColor);\n headCircle.setAttribute(\"r\", String(headRadius));\n svg.appendChild(headCircle);\n\n container.appendChild(svg);\n\n let scale = 1;\n let offsetX = 0;\n let offsetY = 0;\n\n function applyBoundaries(skeleton: Point[]) {\n const b = computeBoundaries(skeleton, width, height);\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 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 for (let i = 0; i < trailCount - 1; i++) {\n const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity } = computeTrailQuad(\n trail,\n i,\n trailCount,\n px,\n py,\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\n // Hide unused paths\n for (let i = trailCount - 1; 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 const prefersReducedMotion =\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n\n let morphResolve: (() => 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 (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 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 initialT option: seek to the specified position before first frame\n if (options.initialT !== undefined) {\n engine.seek(options.initialT);\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 svg.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 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) => {\n morphResolve = resolve;\n });\n },\n };\n\n if (shouldAutoStart) {\n instance.play();\n }\n\n return instance;\n}\n\n/**\n * Creates a sarmal animation inside a container element using an SVG renderer\n * The SVG is appended to the container and animated via requestAnimationFrame\n *\n * @example\n * ```ts\n * import { createSarmalSVG, curves } from '@sarmal/core'\n * const sarmal = createSarmalSVG(document.getElementById('spinner'), curves.epitrochoid7)\n *\n * // To control manually, use autoStart: false\n * const controlled = createSarmalSVG(container, curves.artemis2, { autoStart: false })\n * controlled.play() // Start when ready\n * controlled.pause() // Pause later\n * ```\n */\nexport function createSarmalSVG(\n container: Element,\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 { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\n/**\n * Artemis II free-return lunar trajectory\n * @see https://www.nasa.gov/wp-content/uploads/2025/09/artemis-ii-map-508.pdf\n * a = x-axis asymmetry (widens one lobe),\n * b = y-axis asymmetry,\n * ox = horizontal offset to visually center the shape\n */\nfunction artemis2Fn(t: number, _time: number, _params: Record<string, number>) {\n const a = 0.35,\n b = 0.15,\n ox = 0.175;\n const s = Math.sin(t),\n c = Math.cos(t);\n const denom = 1 + s * s;\n return {\n x: (c * (1 + a * c)) / denom - ox,\n y: (s * c * (1 + b * c)) / denom,\n };\n}\n\n/**\n * Artemis II free-return lunar trajectory curve\n * Traces the path of the Orion spacecraft during the Artemis II mission\n */\nexport const artemis2: CurveDef = {\n name: \"Artemis II\",\n fn: artemis2Fn,\n period: TWO_PI,\n speed: 0.7,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction astroidFn(t: number, _time: number, _params: Record<string, number>) {\n const c = Math.cos(t);\n const s = Math.sin(t);\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(t: number, _time: number, _params: Record<string, number>) {\n return {\n x: 2 * Math.cos(t) + Math.cos(2 * t),\n y: 2 * Math.sin(t) - Math.sin(2 * t),\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(t: number, _time: number, _params: Record<string, number>) {\n return {\n x: 4 * Math.cos(t) - Math.cos(4 * t),\n y: 4 * Math.sin(t) - Math.sin(4 * t),\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(t: number, _time: number, _params: Record<string, number>) {\n const d = 1.0 + 0.55 * Math.sin(t * 0.5);\n return {\n x: 7 * Math.cos(t) - d * Math.cos(7 * t),\n y: 7 * Math.sin(t) - d * Math.sin(7 * t),\n };\n}\n\nfunction epitrochoid7SkeletonFn(t: 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(t) - d * Math.cos(7 * t),\n y: 7 * Math.sin(t) - d * Math.sin(7 * t),\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(t: number, time: number, _params: Record<string, number>) {\n const phi = time * 0.45;\n return {\n x: Math.sin(3 * t + phi),\n y: Math.sin(2 * t),\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(t: number, time: number, _params: Record<string, number>) {\n const phi = time * 0.38;\n return {\n x: Math.sin(4 * t + phi),\n y: Math.sin(3 * t),\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(t: number, time: number, _params: Record<string, number>) {\n const p = 1.75 + 1.25 * Math.sin(time * 0.48);\n const c = Math.cos(t),\n s = Math.sin(t);\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(t: number, _time: number, _params: Record<string, number>) {\n const r = Math.cos(3 * t);\n return {\n x: r * Math.cos(t),\n y: r * Math.sin(t),\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(t: number, _time: number, _params: Record<string, number>) {\n const r = Math.cos(5 * t);\n return {\n x: r * Math.cos(t),\n y: r * Math.sin(t),\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","// 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\";\n\n// Bulk export for convenience\n// >> Standard\nimport { rose3 } from \"./rose3\";\nimport { rose5 } from \"./rose5\";\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 rose5,\n rose3,\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 PalettePreset,\n} from \"./types\";\nexport type { CurveName } from \"./curves\";\n\nexport { createEngine } from \"./engine\";\nexport { createRenderer } from \"./renderer\";\nexport { createSVGRenderer, createSarmalSVG } from \"./renderer-svg\";\nexport { curves } from \"./curves\";\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, curves } from '@sarmal/core'\n * const sarmal = createSarmal(canvas, curves.artemis2)\n *\n * // To control manually, use autoStart: false\n * const controlled = createSarmal(canvas, curves.artemis2, { 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/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/index.ts","../src/index.ts"],"names":["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 (time `t`), 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 t = 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 `sampleT` */\n function sampleSkeleton(c: ResolvedCurve, sampleT: number): Point {\n if (c.skeletonFn) {\n return c.skeletonFn(sampleT);\n }\n if (c.skeleton === \"live\") {\n return c.fn(sampleT, actualTime, EMPTY_PARAMS);\n }\n return c.fn(sampleT, 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 t = (t + effectiveSpeed * deltaTime) % curve.period;\n actualTime += deltaTime;\n\n if (morphCurveB !== null && _morphAlpha !== null) {\n const a = curve.fn(t, actualTime, EMPTY_PARAMS);\n const tB = _morphStrategy === \"normalized\" ? (t / curve.period) * morphCurveB.period : t;\n const b = morphCurveB.fn(tB, 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(t, 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 isLiveSkeleton() {\n return curve.skeleton === \"live\";\n },\n\n get morphAlpha() {\n return _morphAlpha;\n },\n\n reset() {\n t = 0;\n actualTime = 0;\n trail.clear();\n },\n\n jump(newT: number, { clearTrail = false }: JumpOptions = {}) {\n t = ((newT % curve.period) + curve.period) % curve.period;\n if (clearTrail) {\n trail.clear();\n }\n },\n\n seek(targetT: number, { wrap = false, step = curve.period / trailLength }: SeekOptions = {}) {\n const advance = curve.speed * step;\n const target = ((targetT % curve.period) + curve.period) % curve.period;\n const targetTime = target / curve.speed;\n\n t = 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 sampleT = target - i * advance;\n const wrappedT = ((sampleT % curve.period) + curve.period) % curve.period;\n const time = targetTime - i * step;\n const point = curve.fn(wrappedT, time, 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: (sampleT: number, time: number, params: Record<string, number>) => {\n const a = frozenA.fn(sampleT, time, params);\n const tB =\n frozenStrategy === \"normalized\"\n ? (sampleT / frozenA.period) * frozenB.period\n : sampleT;\n const b = frozenB.fn(tB, time, params);\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 `tB` = `(t / periodA) * periodB`\n // Remap `t` so the trail continues from the same position on `curveB`,\n // not from a raw `t` value that belongs to `curveA`'s smaller range.\n if (_morphStrategy === \"normalized\" && curve.period !== morphCurveB.period) {\n t = (t / 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 sampleT = (i / (steps - 1)) * curve.period;\n const a = sampleSkeleton(curve, sampleT);\n const tB =\n _morphStrategy === \"normalized\"\n ? (sampleT / curve.period) * morphCurveB.period\n : sampleT;\n const b = sampleSkeleton(morphCurveB, tB);\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 sampleT = (i / (steps - 1)) * curve.period;\n points[i] = sampleSkeleton(curve, sampleT);\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, PalettePreset, Point, 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/** Stroke/line width at the tail */\nexport const TRAIL_MIN_WIDTH = 0.5;\n/** Stroke/line width at the head */\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 pixel-space quad corners and style for one ribbon segment.\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): 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 = (TRAIL_MIN_WIDTH + progress * (TRAIL_MAX_WIDTH - TRAIL_MIN_WIDTH)) / 2;\n const w1 = (TRAIL_MIN_WIDTH + nextProgress * (TRAIL_MAX_WIDTH - TRAIL_MIN_WIDTH)) / 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, FIT_PADDING_MIN)`, so the stricter constraint wins\n */\nexport function computeBoundaries(\n pts: Point[],\n logicalWidth: number,\n logicalHeight: number,\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 - FIT_PADDING_MIN * 2) / w;\n const scaleYMinPadding = (logicalHeight - FIT_PADDING_MIN * 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 };\n}\n\nexport const GRADIENT = {\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};\n\nexport const PRESETS: Record<PalettePreset, string[]> = {\n bard: GRADIENT.bard,\n sunset: GRADIENT.sunset,\n ocean: GRADIENT.ocean,\n ice: GRADIENT.ice,\n fire: GRADIENT.fire,\n forest: GRADIENT.forest,\n};\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/** Linear interpolation between two RGB colors */\nexport const lerpRgb = (a: Rgb, b: Rgb, t: number) => ({\n r: Math.round(a.r + (b.r - a.r) * t),\n g: Math.round(a.g + (b.g - a.g) * t),\n b: Math.round(a.b + (b.b - a.b) * t),\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;\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 lerpRgb(c1, c2, t);\n}\n\n/**\n * Resolves a palette option to an array of hex color strings\n * @param palette Preset name, custom array, or undefined\n * @param trailStyle The trail style (determines default palette)\n * @returns Array of hex color strings\n */\nexport function resolvePalette(\n palette: PalettePreset | string[] | undefined,\n trailStyle: TrailStyle,\n): string[] {\n if (Array.isArray(palette)) {\n return palette;\n }\n\n if (palette && palette in PRESETS) {\n return PRESETS[palette as PalettePreset]!;\n }\n\n return trailStyle === \"gradient-animated\" ? GRADIENT.bard : GRADIENT.ice;\n}\n","import type {\n CurveDef,\n MorphOptions,\n Point,\n RendererOptions,\n SarmalInstance,\n TrailStyle,\n} from \"./types\";\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n computeBoundaries,\n computeTrailQuad,\n enginePassthroughs,\n getPaletteColor,\n resolvePalette,\n} from \"./renderer-shared\";\n\nexport { computeTangent, computeNormal, TrailPoint } from \"./renderer-shared\";\nexport {\n Rgb,\n GRADIENT,\n PRESETS,\n hexToRgb,\n lerpRgb,\n getPaletteColor,\n resolvePalette,\n} from \"./renderer-shared\";\n\nconst DEFAULT_SKELETON_COLOR = \"#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 const trailStyle: TrailStyle = options.trailStyle ?? \"default\";\n const trailColor = options.trailColor ?? \"#ffffff\";\n const palette = resolvePalette(options.palette, trailStyle);\n\n function defaultHeadColor(): string {\n if (trailStyle !== \"default\") {\n const { r, g, b } = getPaletteColor(palette, 1.0);\n return `rgb(${r},${g},${b})`;\n }\n return trailColor;\n }\n\n const opts = {\n skeletonColor: options.skeletonColor ?? DEFAULT_SKELETON_COLOR,\n trailColor,\n headColor: options.headColor ?? defaultHeadColor(),\n };\n\n const trailRgb = hexToRgbComponents(opts.trailColor);\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 rect = canvas.getBoundingClientRect();\n const lw = rect.width || 200;\n const lh = rect.height || 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\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\n let morphResolve: (() => 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) return;\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(opts.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) return;\n ctx.strokeStyle = `rgba(${hexToRgbComponents(opts.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 (opts.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(opts.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(${trailRgb},${opacity})`;\n } else {\n const timeOffset = trailStyle === \"gradient-animated\" ? gradientAnimTime * 0.0005 : 0;\n const color = getPaletteColor(palette, 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 =\n options.headRadius ?? Math.max(2, 3 * Math.sqrt(Math.min(logicalWidth, logicalHeight) / 160));\n\n ctx.fillStyle = opts.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 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 initialT option: seek to the specified position before first frame\n if (options.initialT !== undefined) {\n engine.seek(options.initialT);\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\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 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) => {\n morphResolve = resolve;\n });\n },\n };\n\n if (shouldAutoStart) {\n instance.play();\n }\n\n return instance;\n}\n","import type {\n BaseRendererOptions,\n CurveDef,\n Engine,\n MorphOptions,\n Point,\n SarmalInstance,\n TrailStyle,\n} from \"./types\";\n\nimport {\n DEFAULT_MORPH_DURATION_MS,\n DEFAULT_SKELETON_OPACITY,\n computeBoundaries,\n computeTrailQuad,\n enginePassthroughs,\n getPaletteColor,\n resolvePalette,\n} from \"./renderer-shared\";\nimport { createEngine } from \"./engine\";\n\nexport interface SVGRendererOptions extends BaseRendererOptions {\n /** Container element that will contain the SVG */\n container: Element;\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}\n/** Maximum number of trail segment paths pre-created for the ribbon */\nconst MAX_TRAIL_SEGMENTS = 200;\n\nconst EMPTY_PARAMS: Record<string, number> = {};\n\nfunction pointsToPathString(pts: Point[], scale: number, offsetX: number, offsetY: number): string {\n if (pts.length < 2) return \"\";\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 for (let i = 1; i < pts.length; i++) {\n d += ` L${px(pts[i]!)} ${py(pts[i]!)}`;\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 for (let i = 0; i < samples; i++) {\n const t = (i / (samples - 1)) * period;\n pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(t) : curveDef.fn(t, 0, EMPTY_PARAMS);\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 trailColor = options.trailColor ?? \"#ffffff\";\n const trailStyle: TrailStyle = options.trailStyle ?? \"default\";\n const palette = resolvePalette(options.palette, trailStyle);\n const opts = {\n skeletonColor: options.skeletonColor ?? \"#ffffff\",\n trailColor,\n headColor:\n options.headColor ??\n (trailStyle !== \"default\"\n ? (() => {\n const { r, g, b } = getPaletteColor(palette, 1.0);\n return `rgb(${r},${g},${b})`;\n })()\n : trailColor),\n ariaLabel: options.ariaLabel ?? \"Loading\",\n };\n\n const rect = container.getBoundingClientRect();\n const width = rect.width || 200;\n const height = rect.height || 200;\n const headRadius =\n options.headRadius ?? Math.max(2, 3 * Math.sqrt(Math.min(width, height) / 160));\n\n const svg = el(\"svg\") as SVGSVGElement;\n svg.setAttribute(\"width\", String(width));\n svg.setAttribute(\"height\", String(height));\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svg.setAttribute(\"role\", \"img\");\n svg.setAttribute(\"aria-label\", opts.ariaLabel);\n\n const titleEl = el(\"title\");\n titleEl.textContent = opts.ariaLabel;\n svg.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\", opts.skeletonColor);\n skeletonPath.setAttribute(\"stroke-opacity\", String(DEFAULT_SKELETON_OPACITY));\n skeletonPath.setAttribute(\"stroke-width\", \"1.5\");\n svg.appendChild(skeletonPath);\n\n const skeletonPathA = el(\"path\") as SVGPathElement;\n skeletonPathA.setAttribute(\"fill\", \"none\");\n skeletonPathA.setAttribute(\"stroke\", opts.skeletonColor);\n skeletonPathA.setAttribute(\"stroke-width\", \"1.5\");\n skeletonPathA.setAttribute(\"visibility\", \"hidden\");\n svg.appendChild(skeletonPathA);\n\n const skeletonPathB = el(\"path\") as SVGPathElement;\n skeletonPathB.setAttribute(\"fill\", \"none\");\n skeletonPathB.setAttribute(\"stroke\", opts.skeletonColor);\n skeletonPathB.setAttribute(\"stroke-width\", \"1.5\");\n skeletonPathB.setAttribute(\"visibility\", \"hidden\");\n svg.appendChild(skeletonPathB);\n\n let morphPathABuilt = \"\";\n let morphPathBBuilt = \"\";\n\n const trailPaths: SVGPathElement[] = [];\n for (let i = 0; i < MAX_TRAIL_SEGMENTS; i++) {\n const path = el(\"path\") as SVGPathElement;\n path.setAttribute(\"fill\", opts.trailColor);\n svg.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\", opts.headColor);\n headCircle.setAttribute(\"r\", String(headRadius));\n svg.appendChild(headCircle);\n\n container.appendChild(svg);\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, width, height);\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 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 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 px,\n py,\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(palette, progress, timeOffset);\n trailPaths[i]!.setAttribute(\"fill\", `rgb(${r},${g},${b})`);\n }\n }\n\n // Hide unused paths\n for (let i = trailCount - 1; 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 const prefersReducedMotion =\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n\n let morphResolve: (() => 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 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 initialT option: seek to the specified position before first frame\n if (options.initialT !== undefined) {\n engine.seek(options.initialT);\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 svg.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 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) => {\n morphResolve = resolve;\n });\n },\n };\n\n if (shouldAutoStart) {\n instance.play();\n }\n\n return instance;\n}\n\n/**\n * Creates a sarmal animation inside a container element using an SVG renderer\n * The SVG is appended to the container and animated via requestAnimationFrame\n *\n * @example\n * ```ts\n * import { createSarmalSVG, curves } from '@sarmal/core'\n * const sarmal = createSarmalSVG(document.getElementById('spinner'), curves.epitrochoid7)\n *\n * // To control manually, use autoStart: false\n * const controlled = createSarmalSVG(container, curves.artemis2, { autoStart: false })\n * controlled.play() // Start when ready\n * controlled.pause() // Pause later\n * ```\n */\nexport function createSarmalSVG(\n container: Element,\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 { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\n/**\n * Artemis II free-return lunar trajectory\n * @see https://www.nasa.gov/wp-content/uploads/2025/09/artemis-ii-map-508.pdf\n * a = x-axis asymmetry (widens one lobe),\n * b = y-axis asymmetry,\n * ox = horizontal offset to visually center the shape\n */\nfunction artemis2Fn(t: number, _time: number, _params: Record<string, number>) {\n const a = 0.35,\n b = 0.15,\n ox = 0.175;\n const s = Math.sin(t),\n c = Math.cos(t);\n const denom = 1 + s * s;\n return {\n x: (c * (1 + a * c)) / denom - ox,\n y: (s * c * (1 + b * c)) / denom,\n };\n}\n\n/**\n * Artemis II free-return lunar trajectory curve\n * Traces the path of the Orion spacecraft during the Artemis II mission\n */\nexport const artemis2: CurveDef = {\n name: \"Artemis II\",\n fn: artemis2Fn,\n period: TWO_PI,\n speed: 0.7,\n};\n","import type { CurveDef } from \"../types\";\n\nconst TWO_PI = Math.PI * 2;\n\nfunction astroidFn(t: number, _time: number, _params: Record<string, number>) {\n const c = Math.cos(t);\n const s = Math.sin(t);\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(t: number, _time: number, _params: Record<string, number>) {\n return {\n x: 2 * Math.cos(t) + Math.cos(2 * t),\n y: 2 * Math.sin(t) - Math.sin(2 * t),\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(t: number, _time: number, _params: Record<string, number>) {\n return {\n x: 4 * Math.cos(t) - Math.cos(4 * t),\n y: 4 * Math.sin(t) - Math.sin(4 * t),\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(t: number, _time: number, _params: Record<string, number>) {\n const d = 1.0 + 0.55 * Math.sin(t * 0.5);\n return {\n x: 7 * Math.cos(t) - d * Math.cos(7 * t),\n y: 7 * Math.sin(t) - d * Math.sin(7 * t),\n };\n}\n\nfunction epitrochoid7SkeletonFn(t: 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(t) - d * Math.cos(7 * t),\n y: 7 * Math.sin(t) - d * Math.sin(7 * t),\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(t: number, time: number, _params: Record<string, number>) {\n const phi = time * 0.45;\n return {\n x: Math.sin(3 * t + phi),\n y: Math.sin(2 * t),\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(t: number, time: number, _params: Record<string, number>) {\n const phi = time * 0.38;\n return {\n x: Math.sin(4 * t + phi),\n y: Math.sin(3 * t),\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(t: number, time: number, _params: Record<string, number>) {\n const p = 1.75 + 1.25 * Math.sin(time * 0.48);\n const c = Math.cos(t),\n s = Math.sin(t);\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(t: number, _time: number, _params: Record<string, number>) {\n const r = Math.cos(3 * t);\n return {\n x: r * Math.cos(t),\n y: r * Math.sin(t),\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(t: number, _time: number, _params: Record<string, number>) {\n const r = Math.cos(5 * t);\n return {\n x: r * Math.cos(t),\n y: r * Math.sin(t),\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","// 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\";\n\n// Bulk export for convenience\n// >> Standard\nimport { rose3 } from \"./rose3\";\nimport { rose5 } from \"./rose5\";\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 rose5,\n rose3,\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 PalettePreset,\n} from \"./types\";\nexport type { CurveName } from \"./curves\";\n\nexport { createEngine } from \"./engine\";\nexport { createRenderer } from \"./renderer\";\nexport { createSVGRenderer, createSarmalSVG } from \"./renderer-svg\";\nexport { curves } from \"./curves\";\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, curves } from '@sarmal/core'\n * const sarmal = createSarmal(canvas, curves.artemis2)\n *\n * // To control manually, use autoStart: false\n * const controlled = createSarmal(canvas, curves.artemis2, { 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"]}