@cosmictraveler002/anim-kit 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -29
- package/dist/anim-kit.standalone.js +18 -8
- package/dist/anim-kit.standalone.js.map +1 -1
- package/dist/core/gsap.d.ts +2 -1
- package/dist/core/gsap.d.ts.map +1 -1
- package/dist/core/gsap.js +3 -2
- package/dist/core/gsap.js.map +1 -1
- package/dist/effects/clip-wipe.d.ts +10 -2
- package/dist/effects/clip-wipe.d.ts.map +1 -1
- package/dist/effects/clip-wipe.js +30 -9
- package/dist/effects/clip-wipe.js.map +1 -1
- package/dist/effects/cursor-follower.d.ts.map +1 -1
- package/dist/effects/cursor-follower.js +22 -4
- package/dist/effects/cursor-follower.js.map +1 -1
- package/dist/effects/flip-words.d.ts +31 -0
- package/dist/effects/flip-words.d.ts.map +1 -0
- package/dist/effects/flip-words.js +104 -0
- package/dist/effects/flip-words.js.map +1 -0
- package/dist/effects/magnetic.d.ts +15 -0
- package/dist/effects/magnetic.d.ts.map +1 -0
- package/dist/effects/magnetic.js +59 -0
- package/dist/effects/magnetic.js.map +1 -0
- package/dist/effects/media-settle.d.ts +2 -0
- package/dist/effects/media-settle.d.ts.map +1 -1
- package/dist/effects/media-settle.js +5 -2
- package/dist/effects/media-settle.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/gsap.ts +3 -2
- package/src/effects/clip-wipe.ts +50 -10
- package/src/effects/cursor-follower.ts +21 -4
- package/src/effects/flip-words.ts +148 -0
- package/src/effects/magnetic.ts +87 -0
- package/src/effects/media-settle.ts +7 -1
- package/src/index.ts +9 -1
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ inside the published tarball):
|
|
|
78
78
|
|
|
79
79
|
| Specifier | Resolves to | Use for |
|
|
80
80
|
|---|---|---|
|
|
81
|
-
| `@cosmictraveler002/anim-kit` | `dist/index.js` + `dist/index.d.ts` | the full barrel —
|
|
81
|
+
| `@cosmictraveler002/anim-kit` | `dist/index.js` + `dist/index.d.ts` | the full barrel — 45 exports |
|
|
82
82
|
| `@cosmictraveler002/anim-kit/effects/<name>` | `dist/effects/<name>.js` + `.d.ts` | one effect in isolation (`marquee`, `lineReveal`, …) |
|
|
83
83
|
| `@cosmictraveler002/anim-kit/standalone` | `dist/anim-kit.standalone.js` (types → `index.d.ts`) | the self-contained bundle — same API |
|
|
84
84
|
| `@cosmictraveler002/anim-kit/styles` | `dist/styles/anim-kit.css` | untouched plain CSS |
|
|
@@ -97,7 +97,7 @@ resolves declarations through the same map — no `typesVersions` shim needed.
|
|
|
97
97
|
|
|
98
98
|
No build step on the consumer's end: `dist/` is served as-is from the npm
|
|
99
99
|
tarball by any npm CDN. Every URL is **version-pinned** — npm versions are
|
|
100
|
-
immutable, so `@cosmictraveler002/anim-kit@1.
|
|
100
|
+
immutable, so `@cosmictraveler002/anim-kit@1.2.0` always resolves to exactly that build, forever
|
|
101
101
|
(only a new version creates a new URL; nothing floats unless you ask for a
|
|
102
102
|
range).
|
|
103
103
|
|
|
@@ -108,12 +108,12 @@ plugins anim-kit uses) and `lenis` **inlined** — no import map, one URL, works
|
|
|
108
108
|
identically on jsDelivr and unpkg:
|
|
109
109
|
|
|
110
110
|
```html
|
|
111
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@cosmictraveler002/anim-kit@1.
|
|
111
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@cosmictraveler002/anim-kit@1.2.0/dist/styles/anim-kit.css" />
|
|
112
112
|
|
|
113
113
|
<script type="module">
|
|
114
114
|
import {
|
|
115
115
|
smoothScroll, lineReveal, marquee,
|
|
116
|
-
} from "https://cdn.jsdelivr.net/npm/@cosmictraveler002/anim-kit@1.
|
|
116
|
+
} from "https://cdn.jsdelivr.net/npm/@cosmictraveler002/anim-kit@1.2.0/dist/anim-kit.standalone.js";
|
|
117
117
|
|
|
118
118
|
smoothScroll();
|
|
119
119
|
lineReveal("[data-lines]", { mode: "scroll" });
|
|
@@ -121,7 +121,7 @@ identically on jsDelivr and unpkg:
|
|
|
121
121
|
</script>
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
unpkg serves the same file: `https://unpkg.com/@cosmictraveler002/anim-kit@1.
|
|
124
|
+
unpkg serves the same file: `https://unpkg.com/@cosmictraveler002/anim-kit@1.2.0/dist/anim-kit.standalone.js`
|
|
125
125
|
|
|
126
126
|
### Option 2 — jsDelivr `+esm`
|
|
127
127
|
|
|
@@ -130,7 +130,7 @@ per version):
|
|
|
130
130
|
|
|
131
131
|
```html
|
|
132
132
|
<script type="module">
|
|
133
|
-
import { lineReveal } from "https://cdn.jsdelivr.net/npm/@cosmictraveler002/anim-kit@1.
|
|
133
|
+
import { lineReveal } from "https://cdn.jsdelivr.net/npm/@cosmictraveler002/anim-kit@1.2.0/+esm";
|
|
134
134
|
</script>
|
|
135
135
|
```
|
|
136
136
|
|
|
@@ -142,17 +142,18 @@ locally, with CDN URLs — and the way to share one GSAP between anim-kit and
|
|
|
142
142
|
the rest of your page:
|
|
143
143
|
|
|
144
144
|
```html
|
|
145
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@cosmictraveler002/anim-kit@1.
|
|
145
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@cosmictraveler002/anim-kit@1.2.0/dist/styles/anim-kit.css" />
|
|
146
146
|
|
|
147
147
|
<script type="importmap">
|
|
148
148
|
{
|
|
149
149
|
"imports": {
|
|
150
|
-
"@cosmictraveler002/anim-kit": "https://cdn.jsdelivr.net/npm/@cosmictraveler002/anim-kit@1.
|
|
150
|
+
"@cosmictraveler002/anim-kit": "https://cdn.jsdelivr.net/npm/@cosmictraveler002/anim-kit@1.2.0/dist/index.js",
|
|
151
151
|
"gsap": "https://cdn.jsdelivr.net/npm/gsap@3.15.0/index.js",
|
|
152
152
|
"gsap/ScrollTrigger": "https://cdn.jsdelivr.net/npm/gsap@3.15.0/ScrollTrigger.js",
|
|
153
153
|
"gsap/SplitText": "https://cdn.jsdelivr.net/npm/gsap@3.15.0/SplitText.js",
|
|
154
154
|
"gsap/Draggable": "https://cdn.jsdelivr.net/npm/gsap@3.15.0/Draggable.js",
|
|
155
155
|
"gsap/CustomEase": "https://cdn.jsdelivr.net/npm/gsap@3.15.0/CustomEase.js",
|
|
156
|
+
"gsap/Flip": "https://cdn.jsdelivr.net/npm/gsap@3.15.0/Flip.js",
|
|
156
157
|
"gsap/ScrollSmoother": "https://cdn.jsdelivr.net/npm/gsap@3.15.0/ScrollSmoother.js",
|
|
157
158
|
"lenis": "https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.mjs"
|
|
158
159
|
}
|
|
@@ -166,7 +167,7 @@ the rest of your page:
|
|
|
166
167
|
</script>
|
|
167
168
|
```
|
|
168
169
|
|
|
169
|
-
Swap the host for unpkg (`https://unpkg.com/@cosmictraveler002/anim-kit@1.
|
|
170
|
+
Swap the host for unpkg (`https://unpkg.com/@cosmictraveler002/anim-kit@1.2.0/dist/index.js`, …) —
|
|
170
171
|
the file layout is identical. GSAP subpaths are listed one by one because
|
|
171
172
|
import maps match specifiers literally: a trailing-slash prefix map would
|
|
172
173
|
produce extension-less URLs, which CDNs don't serve. The `gsap`/`lenis` pins
|
|
@@ -281,6 +282,7 @@ prompt dock, and backs the `category` / `subcategory` fields on
|
|
|
281
282
|
| Text animations | Decode & scramble | `scrambleText` |
|
|
282
283
|
| Text animations | Rolling text | `rollText` |
|
|
283
284
|
| Text animations | Counters | `counter` |
|
|
285
|
+
| Text animations | Layout transfers | `flipWords` |
|
|
284
286
|
| Scroll & media | Pinned galleries | `horizontalScroll`, `stackedCards`, `stackedCardsPinned` |
|
|
285
287
|
| Scroll & media | Parallax & depth | `parallax` |
|
|
286
288
|
| Scroll & media | Heroes & media | `heroShrink`, `mediaSettle` |
|
|
@@ -290,6 +292,7 @@ prompt dock, and backs the `category` / `subcategory` fields on
|
|
|
290
292
|
| Loops & marquees | Equalizers | `audioBars` |
|
|
291
293
|
| Buttons & links | Liquid fills | `liquidButton` |
|
|
292
294
|
| Buttons & links | Underlines | `underlineLink` |
|
|
295
|
+
| Buttons & links | Magnetic hover | `magnetic` |
|
|
293
296
|
| Navigation & overlays | Menus & nav | `navHide`, `menuOverlay` |
|
|
294
297
|
| Navigation & overlays | Cursors | `cursorFollower` |
|
|
295
298
|
| Intros & transitions | Preloaders | `preloader` |
|
|
@@ -310,7 +313,7 @@ that does not exist.
|
|
|
310
313
|
#### `initGSAP()`
|
|
311
314
|
|
|
312
315
|
Registers the plugins anim-kit relies on (`ScrollTrigger`, `SplitText`,
|
|
313
|
-
`Draggable`, `CustomEase`, `ScrollSmoother`) and the studio's custom eases.
|
|
316
|
+
`Draggable`, `CustomEase`, `Flip`, `ScrollSmoother`) and the studio's custom eases.
|
|
314
317
|
Idempotent; called for you by every effect.
|
|
315
318
|
|
|
316
319
|
#### `EASES`
|
|
@@ -349,7 +352,7 @@ Central reduced-motion gate. If the user prefers reduced motion and
|
|
|
349
352
|
### Text animations
|
|
350
353
|
|
|
351
354
|
Typography in motion — masked lines, rising masks, per-character scatter,
|
|
352
|
-
decode reveals, rolling words, tickers.
|
|
355
|
+
decode reveals, rolling words, tickers, layout transfers.
|
|
353
356
|
|
|
354
357
|
#### `lineReveal(target, options?) => destroy`
|
|
355
358
|
|
|
@@ -478,6 +481,39 @@ rollText("[data-roll-rev]", { direction: "down" }); // walk rows in reverse
|
|
|
478
481
|
blocks itself. `destroy()` unwraps the rows, removes the clone and restores
|
|
479
482
|
every inline style — markup comes back byte-identical.
|
|
480
483
|
|
|
484
|
+
#### `flipWords(target, { to }, options?) => destroy`
|
|
485
|
+
|
|
486
|
+
Words measured in one layout, moved into another and animated from where
|
|
487
|
+
they stood — the FLIP technique: a column of words fans out into a row,
|
|
488
|
+
driven by scroll progress or played once.
|
|
489
|
+
|
|
490
|
+
```ts
|
|
491
|
+
// Both blocks share one grid cell so the stage never reflows mid-flight:
|
|
492
|
+
flipWords("[data-flip-from]", { to: "[data-flip-to]", scrub: 0.6 });
|
|
493
|
+
|
|
494
|
+
// One-shot on enter (reverses on leave-back), or immediately:
|
|
495
|
+
flipWords("[data-flip-from]", { to: "[data-flip-to]", mode: "scroll" });
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
| Option | Default | Notes |
|
|
499
|
+
| --- | --- | --- |
|
|
500
|
+
| `to` | — (required) | destination block; every word is moved into it |
|
|
501
|
+
| `words` | source children | `[data-flip-word]` matches, else the source's element children |
|
|
502
|
+
| `duration` | `1.4` | seconds for one word's travel |
|
|
503
|
+
| `ease` | `"power4.inOut"` | GSAP ease |
|
|
504
|
+
| `stagger` | `0.2` | seconds between word starts |
|
|
505
|
+
| `scale` | `0.2` | mid-flight squash each word pops through (`0` disables) |
|
|
506
|
+
| `mode` | `"scroll"` | or `"immediate"` to play at once |
|
|
507
|
+
| `scrub` | unset | number = scrub smoothing seconds, `true` = immediate |
|
|
508
|
+
| `start / end` | `"top 75%"` / `"bottom 45%"` | ScrollTrigger positions |
|
|
509
|
+
|
|
510
|
+
**DOM:** put the source and destination blocks in the same grid cell
|
|
511
|
+
(`grid-area: 1 / 1`, a `min-height` on both keeps the stage stable). The words
|
|
512
|
+
live in the destination from init but render at their source positions until
|
|
513
|
+
the timeline runs, so scrubbing reverses perfectly. `destroy()` kills the
|
|
514
|
+
timeline, puts every word back in its original parent and restores the
|
|
515
|
+
inline transform.
|
|
516
|
+
|
|
481
517
|
#### `counter(target, options?) => destroy`
|
|
482
518
|
|
|
483
519
|
Tabular number ticker.
|
|
@@ -545,23 +581,28 @@ as authored.
|
|
|
545
581
|
|
|
546
582
|
#### `clipWipe(target, options?) => destroy`
|
|
547
583
|
|
|
548
|
-
A `clip-path: inset()` reveal: the element is collapsed behind one edge
|
|
549
|
-
inside a frame margin) and the inset animates to zero so it wipes
|
|
584
|
+
A `clip-path: inset()` reveal: the element is collapsed behind one edge,
|
|
585
|
+
corner (or inside a frame margin) and the inset animates to zero so it wipes
|
|
586
|
+
into view.
|
|
550
587
|
|
|
551
588
|
```ts
|
|
552
589
|
clipWipe("[data-clip]", { from: "left" }); // inset(0 100% 0 0) → 0
|
|
553
590
|
clipWipe("[data-frame]", { from: "frame", inset: 12 }); // opens out of a frame
|
|
591
|
+
clipWipe("[data-corner]", { from: "bottom-right" }); // opens toward the opposite corner
|
|
592
|
+
clipWipe("[data-scrub]", { from: "frame", scrub: 0.5 }); // bound to scroll progress
|
|
554
593
|
```
|
|
555
594
|
|
|
556
595
|
| Option | Default | Notes |
|
|
557
596
|
| --- | --- | --- |
|
|
558
|
-
| `from` | `"left"` | `"left"` / `"right"` / `"top"` / `"bottom"` / `"frame"` |
|
|
597
|
+
| `from` | `"left"` | `"left"` / `"right"` / `"top"` / `"bottom"`, a corner (`"top-left"` / `"top-right"` / `"bottom-left"` / `"bottom-right"`), or `"frame"` |
|
|
559
598
|
| `inset` | `15` | frame margin in % (`from: "frame"`) |
|
|
560
599
|
| `duration` | `1` | seconds |
|
|
561
600
|
| `ease` | `"power3.out"` | GSAP ease |
|
|
562
601
|
| `stagger` | `0.08` | seconds between targets |
|
|
563
602
|
| `mode` | `"scroll"` | or `"immediate"` to play at once |
|
|
564
603
|
| `start` | `"top 85%"` | ScrollTrigger start |
|
|
604
|
+
| `end` | `"top 20%"` | ScrollTrigger end (scrub mode) |
|
|
605
|
+
| `scrub` | unset | number = scrub smoothing seconds, `true` = immediate: tie the wipe to scroll progress |
|
|
565
606
|
| `replay` | `false` | re-wipe when leaving / re-entering |
|
|
566
607
|
|
|
567
608
|
Works on images, video, blocks and text. `destroy()` removes the inline
|
|
@@ -660,7 +701,8 @@ heroShrink("[data-hero-media]", { offsetY: "49vh", scale: 0.23, scrub: 1 });
|
|
|
660
701
|
|
|
661
702
|
Images and video that arrive slightly oversized and ease down to size as the
|
|
662
703
|
section enters — content lands instead of popping in. Set `scrub` to bind the
|
|
663
|
-
settle to scroll progress
|
|
704
|
+
settle to scroll progress, or `replay: true` to reverse back to `from` on
|
|
705
|
+
leave-back and replay on every re-enter.
|
|
664
706
|
|
|
665
707
|
```ts
|
|
666
708
|
mediaSettle("[data-settle]", { from: 1.15, duration: 1.5 }); // on enter
|
|
@@ -677,6 +719,7 @@ mediaSettle("[data-settle-scrub]", { scrub: 0.5, from: 1.2 }); // scroll-bound
|
|
|
677
719
|
| `mode` | `"scroll"` | or `"immediate"` to play at once |
|
|
678
720
|
| `start` / `end` | `"top 75%"` / `"bottom top"` | ScrollTrigger positions |
|
|
679
721
|
| `scrub` | unset | number = scrub smoothing seconds, `true` = immediate |
|
|
722
|
+
| `replay` | `false` | re-settle when leaving / re-entering (enter mode) |
|
|
680
723
|
|
|
681
724
|
`destroy()` clears `transform` — media returns to its authored scale. Unlike
|
|
682
725
|
`heroShrink()` (which scrubs media down as it *leaves*), `mediaSettle()` plays
|
|
@@ -774,7 +817,7 @@ would rewrite `height` *after* teardown) and clears the inline height.
|
|
|
774
817
|
|
|
775
818
|
### Buttons & links
|
|
776
819
|
|
|
777
|
-
Hover affordances for CTAs and inline links.
|
|
820
|
+
Hover affordances for CTAs and inline links — fills, underlines, magnetic pulls.
|
|
778
821
|
|
|
779
822
|
#### `liquidButton(target, options?) => destroy`
|
|
780
823
|
|
|
@@ -818,6 +861,29 @@ Pure CSS under the hood — it just adds/removes the `.ak-underline` class whose
|
|
|
818
861
|
`::after` sweep is styled by the companion stylesheet, and `destroy()` removes
|
|
819
862
|
the class again.
|
|
820
863
|
|
|
864
|
+
#### `magnetic(target, options?) => destroy`
|
|
865
|
+
|
|
866
|
+
Buttons and links that lean toward the pointer while hovered — following a
|
|
867
|
+
fraction of the pull with a tilt — then spring back to rest with an elastic
|
|
868
|
+
snap on leave.
|
|
869
|
+
|
|
870
|
+
```ts
|
|
871
|
+
magnetic("[data-magnet]", { strength: 0.5, rotation: 10, scale: 1.04 });
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
| Option | Default | Notes |
|
|
875
|
+
| --- | --- | --- |
|
|
876
|
+
| `strength` | `0.4` | how far the element follows the pointer — fraction of its own box |
|
|
877
|
+
| `rotation` | `8` | max tilt in degrees at full pull (`0` disables) |
|
|
878
|
+
| `scale` | `1` | scale held while the pointer is over the element (`1` = none) |
|
|
879
|
+
| `duration` | `1.2` | spring-back duration, seconds |
|
|
880
|
+
| `ease` | `"elastic.out(1, 0.35)"` | spring-back ease |
|
|
881
|
+
|
|
882
|
+
**DOM:** pass a list (selector, array, NodeList) — each element gets its own
|
|
883
|
+
listeners and its own pull. Keep CSS transitions off `transform` for magnetic
|
|
884
|
+
elements (GSAP animates transform directly). `destroy()` removes the
|
|
885
|
+
listeners, kills in-flight tweens and restores the inline transform.
|
|
886
|
+
|
|
821
887
|
---
|
|
822
888
|
|
|
823
889
|
### Navigation & overlays
|
|
@@ -861,7 +927,12 @@ Curtain uses `EASES.curtain` (`.76,0,.24,1`).
|
|
|
861
927
|
|
|
862
928
|
#### `cursorFollower(zone, options?) => destroy`
|
|
863
929
|
|
|
864
|
-
Spring-followed cursor tag, e.g. "▶ Play Showreel" over a video.
|
|
930
|
+
Spring-followed cursor tag, e.g. "▶ Play Showreel" over a video. The tag is
|
|
931
|
+
pinned `position: fixed` and driven in viewport space (`clientX/Y + offset`),
|
|
932
|
+
so it can live anywhere in the DOM — it only reacts while the pointer is over
|
|
933
|
+
the zone. Style it with `opacity: 0` and light text (`color: #fff`): the
|
|
934
|
+
`exclusion` blend inverts the tag against whatever is behind it, which only
|
|
935
|
+
reads with a light source colour.
|
|
865
936
|
|
|
866
937
|
```ts
|
|
867
938
|
cursorFollower("[data-showreel]", {
|
|
@@ -1061,16 +1132,30 @@ npm run typecheck # tsc --noEmit (what CI runs)
|
|
|
1061
1132
|
```
|
|
1062
1133
|
|
|
1063
1134
|
The demo page wires the whole effect set against one document —
|
|
1064
|
-
`demo/index.html` + `demo/demo.js
|
|
1065
|
-
|
|
1066
|
-
instead.)
|
|
1135
|
+
`demo/index.html` + `demo/demo.js` — and every effect in the catalogue has
|
|
1136
|
+
an on-page *copy prompt* chip (the demo smoke enforces the two-way mapping).
|
|
1137
|
+
(`split()` is exercised by the unit smoke instead.)
|
|
1138
|
+
|
|
1139
|
+
Two pages share that wiring:
|
|
1140
|
+
|
|
1141
|
+
- **`demo/index.html`** (default — `npm run demo` → `/demo/`) — import map on
|
|
1142
|
+
local files (`/node_modules/...`, `/dist/index.js`): fast iteration, works
|
|
1143
|
+
offline, and the page `demo-smoke` drives.
|
|
1144
|
+
- **`demo/anim_kit_live.html`** (`/demo/anim_kit_live.html`) — byte-for-byte
|
|
1145
|
+
the same page wired to the **version-pinned CDN** (jsdelivr `@<version>` for
|
|
1146
|
+
the package, `gsap@3.15.0`, `lenis@1.3.26`): the exact path visitors copy
|
|
1147
|
+
from the prompts and docs, so CDN wiring gets the same manual QA as the
|
|
1148
|
+
local build. `demo-smoke` fails if the two files drift apart or the pin
|
|
1149
|
+
stops matching the release version, and the page only loads once that
|
|
1150
|
+
version is published to npm.
|
|
1067
1151
|
|
|
1068
1152
|
### Copy-prompt API
|
|
1069
1153
|
|
|
1070
1154
|
The demo server doubles as a **prompt server**: every effect has a ready-to-
|
|
1071
|
-
paste *"how to implement this with anim-kit"* prompt — markup,
|
|
1072
|
-
|
|
1073
|
-
|
|
1155
|
+
paste *"how to implement this with anim-kit"* prompt — markup, a numbered
|
|
1156
|
+
copy-paste procedure that runs straight from the version-pinned CDN (no
|
|
1157
|
+
build step, plus the npm import for bundlers), initialisation call, options
|
|
1158
|
+
table, teardown and gotchas:
|
|
1074
1159
|
|
|
1075
1160
|
```bash
|
|
1076
1161
|
curl http://localhost:4321/api/prompts # { count, categories, prompts: [{ id, title, summary, category, subcategory, text }] }
|
|
@@ -1078,7 +1163,7 @@ curl http://localhost:4321/api/prompts/marquee # one prompt, text/plain
|
|
|
1078
1163
|
```
|
|
1079
1164
|
|
|
1080
1165
|
On the page, every labelled section carries a **copy prompt** chip, and the
|
|
1081
|
-
floating **⧉ prompts (
|
|
1166
|
+
floating **⧉ prompts (29)** button at the bottom right opens the full
|
|
1082
1167
|
catalogue grouped by [effect category](#effect-categories) — one click copies
|
|
1083
1168
|
an effect's prompt (the prompt states its category), *copy all* puts the
|
|
1084
1169
|
entire set on the clipboard. The catalogue lives in `scripts/prompts.mjs`:
|
|
@@ -1089,11 +1174,11 @@ and slotting the effect into a subcategory.
|
|
|
1089
1174
|
**Unit smoke** (`scripts/smoke.mjs`) runs the built bundle in **jsdom** and
|
|
1090
1175
|
asserts:
|
|
1091
1176
|
|
|
1092
|
-
1. all
|
|
1177
|
+
1. all 45 exports are present;
|
|
1093
1178
|
2. plugins (`ScrollTrigger`, `SplitText`, `Draggable`, `CustomEase`,
|
|
1094
|
-
`ScrollSmoother`) and the 4 custom eases are registered;
|
|
1179
|
+
`Flip`, `ScrollSmoother`) and the 4 custom eases are registered;
|
|
1095
1180
|
3. every effect no-ops safely on missing targets;
|
|
1096
|
-
4.
|
|
1181
|
+
4. 24 effects mount on real markup and unmount cleanly;
|
|
1097
1182
|
5. `preloader` ticks in both the positional and options-object call forms;
|
|
1098
1183
|
6. `lineReveal` actually splits into masked lines (and per-character masks
|
|
1099
1184
|
with `split: "chars"`) and restores markup on destroy;
|
|
@@ -1132,9 +1217,9 @@ anim-kit/
|
|
|
1132
1217
|
│ │ ├─ guard.ts reduced-motion gate
|
|
1133
1218
|
│ │ ├─ util.ts toArray/one/onReady/compose/raf
|
|
1134
1219
|
│ │ └─ types.ts TargetLike / Destroy / CommonOptions
|
|
1135
|
-
│ ├─ effects/ one file per effect (
|
|
1220
|
+
│ ├─ effects/ one file per effect (24 files, 28 effect functions)
|
|
1136
1221
|
│ ├─ styles/anim-kit.css companion stylesheet
|
|
1137
|
-
│ └─ index.ts barrel —
|
|
1222
|
+
│ └─ index.ts barrel — 45 exports
|
|
1138
1223
|
├─ demo/ visual demo (import map, no bundler)
|
|
1139
1224
|
├─ scripts/
|
|
1140
1225
|
│ ├─ serve.mjs static server + /api/prompts (:4321)
|