@sarmal/core 0.28.0 → 0.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +8 -3
- package/skills/core/SKILL.md +151 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sarmal/core",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.1",
|
|
4
4
|
"description": "Curve path based loading indicators and their renderer",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"animation",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"loading",
|
|
10
10
|
"parametric",
|
|
11
11
|
"spinner",
|
|
12
|
-
"svg"
|
|
12
|
+
"svg",
|
|
13
|
+
"tanstack-intent"
|
|
13
14
|
],
|
|
14
15
|
"homepage": "https://sarmal.art",
|
|
15
16
|
"bugs": {
|
|
@@ -31,7 +32,8 @@
|
|
|
31
32
|
},
|
|
32
33
|
"files": [
|
|
33
34
|
"dist",
|
|
34
|
-
"LICENSE"
|
|
35
|
+
"LICENSE",
|
|
36
|
+
"skills"
|
|
35
37
|
],
|
|
36
38
|
"type": "module",
|
|
37
39
|
"sideEffects": [
|
|
@@ -68,6 +70,9 @@
|
|
|
68
70
|
"types": "./dist/terminal.d.ts"
|
|
69
71
|
}
|
|
70
72
|
},
|
|
73
|
+
"publishConfig": {
|
|
74
|
+
"access": "public"
|
|
75
|
+
},
|
|
71
76
|
"scripts": {
|
|
72
77
|
"build": "tsup",
|
|
73
78
|
"dev": "tsup --watch",
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: core
|
|
3
|
+
description: Parametric curve loading indicators for the web. Use when adding animated
|
|
4
|
+
spinners or loading indicators with @sarmal/core — covers createSarmal (canvas),
|
|
5
|
+
createSarmalSVG, built-in curves, lifecycle, and animation controls.
|
|
6
|
+
license: MIT
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# @sarmal/core
|
|
10
|
+
|
|
11
|
+
sarmal renders parametric math curves as animated loading/thinking indicators. It is not a CSS spinner — it is a canvas or SVG renderer that animates a moving "head" dot leaving a fading trail along a curve path.
|
|
12
|
+
|
|
13
|
+
## Type definitions (read these first)
|
|
14
|
+
|
|
15
|
+
The package ships TypeScript definitions that are the authoritative, always-current API reference. Read them before writing any code:
|
|
16
|
+
|
|
17
|
+
- `node_modules/@sarmal/core/dist/index.d.ts` — `SarmalInstance`, `SarmalOptions`, `createSarmal`, `createSarmalSVG`, `RuntimeRenderOptions`, `TrailStyle`, `TrailColor`, and all other types
|
|
18
|
+
- `node_modules/@sarmal/core/dist/curves/index.d.ts` — `CurveName` union type listing every available built-in curve name; individual curve exports
|
|
19
|
+
|
|
20
|
+
Do not rely on training data for option names, defaults, or curve names — read the `.d.ts` files.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @sarmal/core
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Entry points
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { createSarmal, createSarmalSVG, curves } from "@sarmal/core";
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**`createSarmal(canvas, curveDef, options?): SarmalInstance`** — canvas renderer
|
|
35
|
+
**`createSarmalSVG(svg, curveDef, options?): SarmalInstance`** — SVG renderer
|
|
36
|
+
|
|
37
|
+
Both accept the same options and return the same `SarmalInstance` interface.
|
|
38
|
+
|
|
39
|
+
## Using built-in curves
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
// Named import (tree-shakeable):
|
|
43
|
+
import { lissajous32 } from "@sarmal/core";
|
|
44
|
+
const sarmal = createSarmal(canvas, lissajous32);
|
|
45
|
+
|
|
46
|
+
// Or look up by name string from the curves namespace:
|
|
47
|
+
import { curves } from "@sarmal/core";
|
|
48
|
+
const sarmal = createSarmal(canvas, curves["rose5"]);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
For all available curve names, read the `CurveName` type in `dist/curves/index.d.ts`.
|
|
52
|
+
|
|
53
|
+
## Coordinate space — most important gotcha
|
|
54
|
+
|
|
55
|
+
The two renderers use **different coordinate spaces** for all size values:
|
|
56
|
+
|
|
57
|
+
| Renderer | Space | `headRadius` default |
|
|
58
|
+
| ----------------------- | ------------------- | -------------------- |
|
|
59
|
+
| `createSarmal` (canvas) | CSS pixels | `4` |
|
|
60
|
+
| `createSarmalSVG` (SVG) | 0–100 viewBox units | `0.5` |
|
|
61
|
+
|
|
62
|
+
When configuring `headRadius` or any size option for the SVG renderer, use viewBox units (e.g. `1`–`3`), not pixel values. Passing a canvas-appropriate value like `4` to the SVG renderer produces a massive dot.
|
|
63
|
+
|
|
64
|
+
The same applies to `setRenderOptions` calls on SVG instances.
|
|
65
|
+
|
|
66
|
+
## Lifecycle
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const sarmal = createSarmal(canvas, curveDef, { autoStart: false });
|
|
70
|
+
|
|
71
|
+
sarmal.play(); // start the animation loop
|
|
72
|
+
sarmal.pause(); // pause — preserves animation state
|
|
73
|
+
sarmal.destroy(); // REQUIRED: stops the loop and frees resources
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Always call `destroy()`** when removing the element or unmounting a component. Omitting it leaks a `requestAnimationFrame` loop.
|
|
77
|
+
|
|
78
|
+
## Animation controls
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
// Move to a phase position AND rebuild the trail as if the animation arrived naturally
|
|
82
|
+
sarmal.seek(Math.PI);
|
|
83
|
+
|
|
84
|
+
// Instantly teleport the head; trail is left untouched
|
|
85
|
+
sarmal.jump(Math.PI);
|
|
86
|
+
sarmal.jump(Math.PI, { clearTrail: true }); // or clear it
|
|
87
|
+
|
|
88
|
+
// Speed (0 = freeze, negative = reverse, no upper bound)
|
|
89
|
+
sarmal.setSpeed(2);
|
|
90
|
+
sarmal.resetSpeed(); // revert to curve's inherent default
|
|
91
|
+
await sarmal.setSpeedOver(0, 400); // smooth transition over 400ms
|
|
92
|
+
|
|
93
|
+
// Smooth curve transition (default 300ms)
|
|
94
|
+
await sarmal.morphTo(rose5);
|
|
95
|
+
await sarmal.morphTo(rose5, { duration: 600 });
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**`seek` vs `jump`:** `seek` reconstructs the trail so it looks like the head arrived naturally — use for initialisation. `jump` moves the head instantly without touching the trail — use during morphs or mid-flight repositioning.
|
|
99
|
+
|
|
100
|
+
## Runtime style changes
|
|
101
|
+
|
|
102
|
+
A subset of options can be changed on a live instance via `setRenderOptions`. For the exact list, read `RuntimeRenderOptions` in `dist/index.d.ts`. Validation is strict — if any field fails, the entire call is rejected.
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
sarmal.setRenderOptions({
|
|
106
|
+
trailColor: ["#ff0000", "#0000ff"],
|
|
107
|
+
trailStyle: "gradient-animated",
|
|
108
|
+
skeletonColor: "transparent", // hides the skeleton
|
|
109
|
+
headColor: null, // null = derive from trail automatically
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Auto-init (no JS required)
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import "@sarmal/core/auto";
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```html
|
|
120
|
+
<canvas data-sarmal="lissajous32" width="200" height="200"></canvas>
|
|
121
|
+
<svg data-sarmal="rose5" width="200" height="200"></svg>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Data attributes mirror the option names in kebab-case: `data-trail-color`, `data-trail-length`, `data-trail-style`, `data-skeleton-color`, `data-head-color`, `data-head-radius`.
|
|
125
|
+
|
|
126
|
+
## CDN usage
|
|
127
|
+
|
|
128
|
+
ES module:
|
|
129
|
+
|
|
130
|
+
```html
|
|
131
|
+
<script type="module">
|
|
132
|
+
import { createSarmal, lissajous32 } from "https://cdn.jsdelivr.net/npm/@sarmal/core/+esm";
|
|
133
|
+
const sarmal = createSarmal(document.querySelector("canvas"), lissajous32);
|
|
134
|
+
</script>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Auto-init script (no JS needed):
|
|
138
|
+
|
|
139
|
+
```html
|
|
140
|
+
<script src="https://cdn.jsdelivr.net/npm/@sarmal/core/dist/auto-init.js"></script>
|
|
141
|
+
<canvas data-sarmal="rose5" width="200" height="200"></canvas>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Common mistakes
|
|
145
|
+
|
|
146
|
+
- **`trailColor` with named colors or `rgb()`** — only 6-digit hex strings are supported; `'red'` and `'#f00'` are not valid
|
|
147
|
+
- **SVG `headRadius` with pixel values** — SVG space is 0–100 viewBox units; a canvas value of `4` renders as a large dot in SVG
|
|
148
|
+
- **Forgetting `destroy()`** — always clean up in React `useEffect` return, Vue `onUnmounted`, etc.
|
|
149
|
+
- **Changing `trailLength` after construction** — not possible; `trailLength` is fixed at creation; create a new instance
|
|
150
|
+
- **Gradient colors without a gradient `trailStyle`** — `string[]` for `trailColor` has no visual effect unless `trailStyle` is `'gradient-static'` or `'gradient-animated'`
|
|
151
|
+
- **Reading trail length from `trail.length`** — when using the engine directly, use `engine.trailCount`; the buffer is pre-allocated and always full-length
|