solid-drift 0.2.0 → 0.7.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/README.md +735 -10
- package/dist/animate.d.ts +2 -2
- package/dist/animate.js +2 -2
- package/dist/cartoon.d.ts +190 -0
- package/dist/cartoon.js +334 -0
- package/dist/color.d.ts +53 -0
- package/dist/color.js +391 -0
- package/dist/directive.d.ts +5 -5
- package/dist/directive.js +15 -7
- package/dist/easing.d.ts +22 -1
- package/dist/easing.js +49 -1
- package/dist/flip.d.ts +44 -0
- package/dist/flip.js +108 -0
- package/dist/horizontal.d.ts +107 -0
- package/dist/horizontal.js +208 -0
- package/dist/index.d.ts +16 -3
- package/dist/index.js +15 -3
- package/dist/inview.d.ts +4 -4
- package/dist/inview.js +5 -5
- package/dist/motion.d.ts +327 -0
- package/dist/motion.js +729 -0
- package/dist/physics.d.ts +146 -0
- package/dist/physics.js +352 -0
- package/dist/pointer.d.ts +76 -0
- package/dist/pointer.js +123 -0
- package/dist/reduced-motion.d.ts +3 -3
- package/dist/reduced-motion.js +5 -4
- package/dist/scroll.d.ts +3 -3
- package/dist/scroll.js +5 -5
- package/dist/scrollfx.d.ts +156 -0
- package/dist/scrollfx.js +148 -0
- package/dist/scrub.d.ts +51 -0
- package/dist/scrub.js +67 -0
- package/dist/spring.d.ts +39 -4
- package/dist/spring.js +26 -7
- package/dist/stagger.d.ts +4 -4
- package/dist/stagger.js +4 -4
- package/dist/timeline.d.ts +45 -0
- package/dist/timeline.js +93 -0
- package/dist/trail.d.ts +27 -0
- package/dist/trail.js +75 -0
- package/dist/tween.d.ts +3 -3
- package/dist/tween.js +3 -3
- package/dist/typography.d.ts +241 -0
- package/dist/typography.js +812 -0
- package/dist/velocity.d.ts +44 -0
- package/dist/velocity.js +88 -0
- package/package.json +1 -1
package/dist/flip.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { animate, } from "./animate.js";
|
|
2
|
+
import { prefersReducedMotion } from "./reduced-motion.js";
|
|
3
|
+
/**
|
|
4
|
+
* FLIP layout animation around a DOM mutation.
|
|
5
|
+
*
|
|
6
|
+
* Records the element's position and size (First), runs your `mutate()`
|
|
7
|
+
* which changes the layout (Last), then Inverts the delta as a transform
|
|
8
|
+
* and Plays it back to identity. List reorders, expanding panels, and
|
|
9
|
+
* grid reshuffles glide to their new spots instead of jumping.
|
|
10
|
+
*
|
|
11
|
+
* The element's pre-existing `transform` is captured and restored after
|
|
12
|
+
* the animation, so FLIP composes with other transform animations.
|
|
13
|
+
* `stop()` halts mid-flight and restores the original transform.
|
|
14
|
+
*
|
|
15
|
+
* SSR-safe and reduced-motion safe: the mutation runs with no animation.
|
|
16
|
+
* If the element does not move, no animation runs either.
|
|
17
|
+
*
|
|
18
|
+
* ```tsx
|
|
19
|
+
* import { animateFlip } from "solid-drift"
|
|
20
|
+
*
|
|
21
|
+
* const [items, setItems] = createSignal(["a", "b", "c"])
|
|
22
|
+
* let list!: HTMLUListElement
|
|
23
|
+
*
|
|
24
|
+
* const shuffle = () =>
|
|
25
|
+
* animateFlip(
|
|
26
|
+
* () => list,
|
|
27
|
+
* () => setItems((prev) => [...prev].reverse()),
|
|
28
|
+
* { duration: 450 },
|
|
29
|
+
* )
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function animateFlip(ref, mutate, options = {}) {
|
|
33
|
+
const { duration = 400, delay = 0, easing = "easeOutCubic", scale = true, } = options;
|
|
34
|
+
let resolveFinished;
|
|
35
|
+
const finished = new Promise((resolve) => {
|
|
36
|
+
resolveFinished = resolve;
|
|
37
|
+
});
|
|
38
|
+
let done = false;
|
|
39
|
+
const finish = () => {
|
|
40
|
+
if (done)
|
|
41
|
+
return;
|
|
42
|
+
done = true;
|
|
43
|
+
resolveFinished();
|
|
44
|
+
};
|
|
45
|
+
const el = ref();
|
|
46
|
+
if (typeof window === "undefined" || !el || prefersReducedMotion()) {
|
|
47
|
+
mutate();
|
|
48
|
+
finish();
|
|
49
|
+
return { stop: () => { }, finished };
|
|
50
|
+
}
|
|
51
|
+
const target = el;
|
|
52
|
+
const prevTransform = target.style.transform;
|
|
53
|
+
const first = target.getBoundingClientRect();
|
|
54
|
+
mutate();
|
|
55
|
+
let stopped = false;
|
|
56
|
+
let step = null;
|
|
57
|
+
const controls = {
|
|
58
|
+
stop: () => {
|
|
59
|
+
stopped = true;
|
|
60
|
+
step?.stop();
|
|
61
|
+
target.style.transform = prevTransform;
|
|
62
|
+
finish();
|
|
63
|
+
},
|
|
64
|
+
finished,
|
|
65
|
+
};
|
|
66
|
+
// Two frames: one for Solid's DOM update to flush, one to measure it.
|
|
67
|
+
requestAnimationFrame(() => requestAnimationFrame(() => {
|
|
68
|
+
if (stopped) {
|
|
69
|
+
finish();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const last = target.getBoundingClientRect();
|
|
73
|
+
const dx = first.left - last.left;
|
|
74
|
+
const dy = first.top - last.top;
|
|
75
|
+
const sx = scale && last.width > 0 ? first.width / last.width : 1;
|
|
76
|
+
const sy = scale && last.height > 0 ? first.height / last.height : 1;
|
|
77
|
+
const moved = Math.abs(dx) >= 0.5 ||
|
|
78
|
+
Math.abs(dy) >= 0.5 ||
|
|
79
|
+
Math.abs(sx - 1) >= 0.001 ||
|
|
80
|
+
Math.abs(sy - 1) >= 0.001;
|
|
81
|
+
if (!moved) {
|
|
82
|
+
finish();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const render = (eased) => {
|
|
86
|
+
const rest = 1 - eased;
|
|
87
|
+
target.style.transform =
|
|
88
|
+
`translate3d(${(dx * rest).toFixed(2)}px, ${(dy * rest).toFixed(2)}px, 0)` +
|
|
89
|
+
(scale
|
|
90
|
+
? ` scale(${(1 + (sx - 1) * rest).toFixed(4)}, ${(1 + (sy - 1) * rest).toFixed(4)})`
|
|
91
|
+
: "");
|
|
92
|
+
};
|
|
93
|
+
render(0);
|
|
94
|
+
// Force the inverted state to apply before the animation runs.
|
|
95
|
+
void target.offsetHeight;
|
|
96
|
+
step = animate(0, 1, {
|
|
97
|
+
duration,
|
|
98
|
+
delay,
|
|
99
|
+
easing,
|
|
100
|
+
onUpdate: render,
|
|
101
|
+
onComplete: () => {
|
|
102
|
+
target.style.transform = prevTransform;
|
|
103
|
+
finish();
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}));
|
|
107
|
+
return controls;
|
|
108
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { type Accessor } from "solid-js";
|
|
2
|
+
export interface HorizontalScrollOptions {
|
|
3
|
+
/**
|
|
4
|
+
* The tall wrapper the user scrolls through. Its height beyond one
|
|
5
|
+
* viewport becomes the scroll range that drives the horizontal slide.
|
|
6
|
+
* Give it e.g. `height: 300vh` in CSS.
|
|
7
|
+
*/
|
|
8
|
+
pin: () => HTMLElement | null | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* The wide track that slides horizontally. Usually a flex row wider
|
|
11
|
+
* than the viewport, e.g. `display: flex; width: max-content`.
|
|
12
|
+
*/
|
|
13
|
+
track: () => HTMLElement | null | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* The sticky viewport showing one screenful of the track at a time,
|
|
16
|
+
* e.g. `position: sticky; top: 0; height: 100vh; overflow: hidden`.
|
|
17
|
+
* Defaults to the track's parent element.
|
|
18
|
+
*/
|
|
19
|
+
stage?: () => HTMLElement | null | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Horizontal travel in pixels. Pass a number for a fixed distance or a
|
|
22
|
+
* function for a dynamic one (re-evaluated on every resize). Default:
|
|
23
|
+
* measured live as `track.scrollWidth - stage.clientWidth`.
|
|
24
|
+
*/
|
|
25
|
+
distance?: number | (() => number);
|
|
26
|
+
/** Fraction of the scroll range where the slide begins. Default 0. */
|
|
27
|
+
start?: number;
|
|
28
|
+
/** Fraction of the scroll range where the slide ends. Default 1. */
|
|
29
|
+
end?: number;
|
|
30
|
+
/** Spring stiffness smoothing vertical scroll into horizontal motion. Default 120. */
|
|
31
|
+
stiffness?: number;
|
|
32
|
+
/** Spring damping for the smoothing. Default 20. */
|
|
33
|
+
damping?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Called with the smoothed progress (0 to 1) whenever it updates,
|
|
36
|
+
* including once on mount. Useful for per-panel parallax driven by
|
|
37
|
+
* the same timeline.
|
|
38
|
+
*/
|
|
39
|
+
onProgress?: (progress: number) => void;
|
|
40
|
+
}
|
|
41
|
+
export interface HorizontalScrollResult {
|
|
42
|
+
/**
|
|
43
|
+
* Smoothed progress through the pinned range, 0 to 1. Drive panel
|
|
44
|
+
* parallax or progress indicators from this signal.
|
|
45
|
+
*/
|
|
46
|
+
progress: Accessor<number>;
|
|
47
|
+
/** The current horizontal travel in pixels. */
|
|
48
|
+
distance: Accessor<number>;
|
|
49
|
+
/** Re-measure the distance and recompute progress immediately. */
|
|
50
|
+
refresh: () => void;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Pin a tall section and slide a wide track through it as the user
|
|
54
|
+
* scrolls vertically: the classic horizontal-scroll storytelling chapter.
|
|
55
|
+
*
|
|
56
|
+
* The pinning itself is plain CSS (`position: sticky` on the stage), so
|
|
57
|
+
* this primitive never hijacks scrolling. It only translates the track
|
|
58
|
+
* with `translate3d`, smoothed by a spring that retargets seamlessly
|
|
59
|
+
* mid-scroll. Touch stays native: vertical swipes scroll the page, and
|
|
60
|
+
* the stage should keep `touch-action: pan-y` in your CSS.
|
|
61
|
+
*
|
|
62
|
+
* Reduced motion is a first-class path, not an afterthought. When the
|
|
63
|
+
* user prefers reduced motion the stage unpins (the tall section scrolls
|
|
64
|
+
* normally), the track renders as a plain vertical stack, nothing slides,
|
|
65
|
+
* and `progress` still reports 0 to 1 through the section so indicators
|
|
66
|
+
* keep working.
|
|
67
|
+
*
|
|
68
|
+
* SSR-safe: returns constant `0` accessors on the server (never touches
|
|
69
|
+
* `window` or `document` outside the browser).
|
|
70
|
+
*
|
|
71
|
+
* ```tsx
|
|
72
|
+
* import { createHorizontalScroll } from "solid-drift"
|
|
73
|
+
*
|
|
74
|
+
* function Story() {
|
|
75
|
+
* let pin!: HTMLElement
|
|
76
|
+
* let track!: HTMLElement
|
|
77
|
+
* const { progress } = createHorizontalScroll({
|
|
78
|
+
* pin: () => pin,
|
|
79
|
+
* track: () => track,
|
|
80
|
+
* stiffness: 120,
|
|
81
|
+
* damping: 20,
|
|
82
|
+
* })
|
|
83
|
+
* return (
|
|
84
|
+
* <section ref={pin} style={{ height: "300vh" }}>
|
|
85
|
+
* <div
|
|
86
|
+
* class="h-stage"
|
|
87
|
+
* style={{
|
|
88
|
+
* position: "sticky", top: 0, height: "100vh",
|
|
89
|
+
* overflow: "hidden", "touch-action": "pan-y",
|
|
90
|
+
* }}
|
|
91
|
+
* >
|
|
92
|
+
* <div
|
|
93
|
+
* ref={track}
|
|
94
|
+
* class="h-track"
|
|
95
|
+
* style={{ display: "flex", width: "max-content", height: "100%" }}
|
|
96
|
+
* >
|
|
97
|
+
* <article style={{ width: "100vw" }}>Chapter one</article>
|
|
98
|
+
* <article style={{ width: "100vw" }}>Chapter two</article>
|
|
99
|
+
* <article style={{ width: "100vw" }}>Chapter three</article>
|
|
100
|
+
* </div>
|
|
101
|
+
* </div>
|
|
102
|
+
* </section>
|
|
103
|
+
* )
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function createHorizontalScroll(options: HorizontalScrollOptions): HorizontalScrollResult;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { createEffect, createSignal, onCleanup } from "solid-js";
|
|
2
|
+
import { createSpring } from "./spring.js";
|
|
3
|
+
import { usePrefersReducedMotion } from "./reduced-motion.js";
|
|
4
|
+
function clamp01(v) {
|
|
5
|
+
return v < 0 ? 0 : v > 1 ? 1 : v;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Pin a tall section and slide a wide track through it as the user
|
|
9
|
+
* scrolls vertically: the classic horizontal-scroll storytelling chapter.
|
|
10
|
+
*
|
|
11
|
+
* The pinning itself is plain CSS (`position: sticky` on the stage), so
|
|
12
|
+
* this primitive never hijacks scrolling. It only translates the track
|
|
13
|
+
* with `translate3d`, smoothed by a spring that retargets seamlessly
|
|
14
|
+
* mid-scroll. Touch stays native: vertical swipes scroll the page, and
|
|
15
|
+
* the stage should keep `touch-action: pan-y` in your CSS.
|
|
16
|
+
*
|
|
17
|
+
* Reduced motion is a first-class path, not an afterthought. When the
|
|
18
|
+
* user prefers reduced motion the stage unpins (the tall section scrolls
|
|
19
|
+
* normally), the track renders as a plain vertical stack, nothing slides,
|
|
20
|
+
* and `progress` still reports 0 to 1 through the section so indicators
|
|
21
|
+
* keep working.
|
|
22
|
+
*
|
|
23
|
+
* SSR-safe: returns constant `0` accessors on the server (never touches
|
|
24
|
+
* `window` or `document` outside the browser).
|
|
25
|
+
*
|
|
26
|
+
* ```tsx
|
|
27
|
+
* import { createHorizontalScroll } from "solid-drift"
|
|
28
|
+
*
|
|
29
|
+
* function Story() {
|
|
30
|
+
* let pin!: HTMLElement
|
|
31
|
+
* let track!: HTMLElement
|
|
32
|
+
* const { progress } = createHorizontalScroll({
|
|
33
|
+
* pin: () => pin,
|
|
34
|
+
* track: () => track,
|
|
35
|
+
* stiffness: 120,
|
|
36
|
+
* damping: 20,
|
|
37
|
+
* })
|
|
38
|
+
* return (
|
|
39
|
+
* <section ref={pin} style={{ height: "300vh" }}>
|
|
40
|
+
* <div
|
|
41
|
+
* class="h-stage"
|
|
42
|
+
* style={{
|
|
43
|
+
* position: "sticky", top: 0, height: "100vh",
|
|
44
|
+
* overflow: "hidden", "touch-action": "pan-y",
|
|
45
|
+
* }}
|
|
46
|
+
* >
|
|
47
|
+
* <div
|
|
48
|
+
* ref={track}
|
|
49
|
+
* class="h-track"
|
|
50
|
+
* style={{ display: "flex", width: "max-content", height: "100%" }}
|
|
51
|
+
* >
|
|
52
|
+
* <article style={{ width: "100vw" }}>Chapter one</article>
|
|
53
|
+
* <article style={{ width: "100vw" }}>Chapter two</article>
|
|
54
|
+
* <article style={{ width: "100vw" }}>Chapter three</article>
|
|
55
|
+
* </div>
|
|
56
|
+
* </div>
|
|
57
|
+
* </section>
|
|
58
|
+
* )
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export function createHorizontalScroll(options) {
|
|
63
|
+
// SSR: no window, no scrolling, nothing to pin.
|
|
64
|
+
if (typeof window === "undefined") {
|
|
65
|
+
const zero = () => 0;
|
|
66
|
+
return { progress: zero, distance: zero, refresh: () => { } };
|
|
67
|
+
}
|
|
68
|
+
const { pin, track, distance: distanceOption, start = 0, end = 1, stiffness = 120, damping = 20, onProgress, } = options;
|
|
69
|
+
const stage = options.stage ??
|
|
70
|
+
(() => (track()?.parentElement ?? null));
|
|
71
|
+
const s0 = clamp01(start);
|
|
72
|
+
const e0 = clamp01(end);
|
|
73
|
+
const reduced = usePrefersReducedMotion();
|
|
74
|
+
const [raw, setRaw] = createSignal(0);
|
|
75
|
+
const [travel, setTravel] = createSignal(0);
|
|
76
|
+
// Reading reduced() in the source keeps the spring reactive to the OS
|
|
77
|
+
// motion preference: toggling it mid-session re-runs the spring effect,
|
|
78
|
+
// which jumps straight to the target when reduced motion is preferred.
|
|
79
|
+
const progress = createSpring(() => (reduced(), raw()), {
|
|
80
|
+
stiffness,
|
|
81
|
+
damping,
|
|
82
|
+
});
|
|
83
|
+
const compute = () => {
|
|
84
|
+
const p = pin();
|
|
85
|
+
if (!p)
|
|
86
|
+
return;
|
|
87
|
+
const rect = p.getBoundingClientRect();
|
|
88
|
+
const viewport = window.innerHeight;
|
|
89
|
+
// -rect.top is how far the pin's top edge has scrolled past the top
|
|
90
|
+
// of the viewport. The slide runs over the pin's extra height.
|
|
91
|
+
const range = Math.max(0, rect.height - viewport);
|
|
92
|
+
const span = (e0 - s0) * range;
|
|
93
|
+
setRaw(span > 0 ? clamp01((-rect.top - s0 * range) / span) : 0);
|
|
94
|
+
};
|
|
95
|
+
const measure = () => {
|
|
96
|
+
const t = track();
|
|
97
|
+
if (!t)
|
|
98
|
+
return;
|
|
99
|
+
const explicit = typeof distanceOption === "function" ? distanceOption() : distanceOption;
|
|
100
|
+
if (typeof explicit === "number" && Number.isFinite(explicit)) {
|
|
101
|
+
setTravel(Math.max(0, explicit));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const s = stage();
|
|
105
|
+
const viewportWidth = s ? s.clientWidth : window.innerWidth;
|
|
106
|
+
setTravel(Math.max(0, t.scrollWidth - viewportWidth));
|
|
107
|
+
};
|
|
108
|
+
const refresh = () => {
|
|
109
|
+
measure();
|
|
110
|
+
compute();
|
|
111
|
+
};
|
|
112
|
+
// Scroll and resize are rAF-throttled: at most one measure per frame.
|
|
113
|
+
let rafId = 0;
|
|
114
|
+
const requestRefresh = () => {
|
|
115
|
+
if (typeof requestAnimationFrame === "undefined") {
|
|
116
|
+
refresh();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (rafId)
|
|
120
|
+
return;
|
|
121
|
+
rafId = requestAnimationFrame(() => {
|
|
122
|
+
rafId = 0;
|
|
123
|
+
refresh();
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
// Reduced motion: unpin the stage, stack the track vertically, stop
|
|
127
|
+
// sliding. Inline styles are captured once and restored when the
|
|
128
|
+
// preference flips back.
|
|
129
|
+
const saved = { stagePosition: "", trackTransform: "", trackFlex: "" };
|
|
130
|
+
let reducedApplied = false;
|
|
131
|
+
createEffect(() => {
|
|
132
|
+
const s = stage();
|
|
133
|
+
const t = track();
|
|
134
|
+
const isReduced = reduced();
|
|
135
|
+
if (!s || !t)
|
|
136
|
+
return;
|
|
137
|
+
if (isReduced) {
|
|
138
|
+
if (!reducedApplied) {
|
|
139
|
+
saved.stagePosition = s.style.position;
|
|
140
|
+
saved.trackTransform = t.style.transform;
|
|
141
|
+
saved.trackFlex = t.style.flexDirection;
|
|
142
|
+
reducedApplied = true;
|
|
143
|
+
}
|
|
144
|
+
s.style.position = "static";
|
|
145
|
+
t.style.transform = "";
|
|
146
|
+
t.style.flexDirection = "column";
|
|
147
|
+
}
|
|
148
|
+
else if (reducedApplied) {
|
|
149
|
+
s.style.position = saved.stagePosition;
|
|
150
|
+
t.style.transform = saved.trackTransform;
|
|
151
|
+
t.style.flexDirection = saved.trackFlex;
|
|
152
|
+
reducedApplied = false;
|
|
153
|
+
refresh();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
// Apply the slide. Skipped entirely under reduced motion, where the
|
|
157
|
+
// effect above owns the track's styles.
|
|
158
|
+
createEffect(() => {
|
|
159
|
+
const t = track();
|
|
160
|
+
if (!t)
|
|
161
|
+
return;
|
|
162
|
+
const d = travel();
|
|
163
|
+
const p = progress();
|
|
164
|
+
if (reduced())
|
|
165
|
+
return;
|
|
166
|
+
const x = -p * d;
|
|
167
|
+
t.style.willChange = "transform";
|
|
168
|
+
t.style.transform = x === 0 ? "" : `translate3d(${x}px, 0, 0)`;
|
|
169
|
+
});
|
|
170
|
+
createEffect(() => {
|
|
171
|
+
onProgress?.(progress());
|
|
172
|
+
});
|
|
173
|
+
// Initial measure once refs are bound, plus re-measure when the bound
|
|
174
|
+
// elements change.
|
|
175
|
+
createEffect(() => {
|
|
176
|
+
pin();
|
|
177
|
+
track();
|
|
178
|
+
stage();
|
|
179
|
+
refresh();
|
|
180
|
+
});
|
|
181
|
+
window.addEventListener("scroll", requestRefresh, { passive: true });
|
|
182
|
+
window.addEventListener("resize", requestRefresh, { passive: true });
|
|
183
|
+
let observer = null;
|
|
184
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
185
|
+
observer = new ResizeObserver(requestRefresh);
|
|
186
|
+
const ro = observer;
|
|
187
|
+
createEffect(() => {
|
|
188
|
+
const p = pin();
|
|
189
|
+
const t = track();
|
|
190
|
+
const s = stage();
|
|
191
|
+
ro.disconnect();
|
|
192
|
+
if (p)
|
|
193
|
+
ro.observe(p);
|
|
194
|
+
if (t)
|
|
195
|
+
ro.observe(t);
|
|
196
|
+
if (s && s !== p)
|
|
197
|
+
ro.observe(s);
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
onCleanup(() => {
|
|
201
|
+
window.removeEventListener("scroll", requestRefresh);
|
|
202
|
+
window.removeEventListener("resize", requestRefresh);
|
|
203
|
+
if (rafId)
|
|
204
|
+
cancelAnimationFrame(rafId);
|
|
205
|
+
observer?.disconnect();
|
|
206
|
+
});
|
|
207
|
+
return { progress, distance: travel, refresh };
|
|
208
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* solid-drift
|
|
2
|
+
* solid-drift: signal-native animation for SolidJS.
|
|
3
3
|
*
|
|
4
4
|
* Animate values, not elements: springs and tweens follow your signals, and
|
|
5
5
|
* retargeting mid-flight is seamless by design.
|
|
6
6
|
*/
|
|
7
|
-
export { createSpring, type SpringOptions } from "./spring.js";
|
|
7
|
+
export { createSpring, type SpringOptions, springPresets } from "./spring.js";
|
|
8
8
|
export { createTween, type TweenOptions } from "./tween.js";
|
|
9
9
|
export { animate, type AnimateOptions, type AnimationControls, } from "./animate.js";
|
|
10
10
|
export { drift, type DriftProps } from "./directive.js";
|
|
@@ -12,4 +12,17 @@ export { createScrollProgress, type ScrollTarget } from "./scroll.js";
|
|
|
12
12
|
export { createInView, type InViewOptions } from "./inview.js";
|
|
13
13
|
export { usePrefersReducedMotion, prefersReducedMotion, } from "./reduced-motion.js";
|
|
14
14
|
export { createStagger } from "./stagger.js";
|
|
15
|
-
export {
|
|
15
|
+
export { createHorizontalScroll, type HorizontalScrollOptions, type HorizontalScrollResult, } from "./horizontal.js";
|
|
16
|
+
export { createScrub, type ScrubKeyframe, type ScrubOptions } from "./scrub.js";
|
|
17
|
+
export { createScrollColor, type ScrollColorStop, type ScrollColorOptions, type ScrollColorFormat, createScrollTracking, type ScrollTrackingOptions, createScrollLine, type ScrollLineOptions, type ScrollLineStyle, type ScrollLineAxis, type ScrollLineOrigin, } from "./scrollfx.js";
|
|
18
|
+
export { createVelocity, type VelocityOptions } from "./velocity.js";
|
|
19
|
+
export { createMagnetic, type MagneticOptions, type MagneticResult, createTilt, type TiltOptions, type TiltResult, } from "./pointer.js";
|
|
20
|
+
export { createTrail, type TrailOptions } from "./trail.js";
|
|
21
|
+
export { createTimeline, type TimelineStep, type TimelineStatus, type TimelineControls, } from "./timeline.js";
|
|
22
|
+
export { animateFlip, type FlipOptions } from "./flip.js";
|
|
23
|
+
export { createSquashStretch, type SquashStretchOptions, type SquashStretchResult, createFollowThrough, type FollowThroughOptions, createAnticipation, type AnticipationOptions, createWobble, type WobbleOptions, type WobbleResult, } from "./cartoon.js";
|
|
24
|
+
export { createGravity, type GravityOptions, type GravityResult, createPendulum, type PendulumOptions, type PendulumResult, createFling, type FlingOptions, type FlingResult, } from "./physics.js";
|
|
25
|
+
export { createFontSwap, type FontSwapOptions, type FontSwapResult, createTyping, type TypingOptions, type TypingResult, createTextPhysics, type TextPhysicsOptions, type TextPhysicsResult, createTextTunnel, type TextTunnelOptions, type TextTunnelResult, createTextCutout, type TextCutoutOptions, createTextGradient, type TextGradientOptions, createTextScramble, type TextScrambleOptions, type TextScrambleResult, createTextWave, type TextWaveOptions, } from "./typography.js";
|
|
26
|
+
export { easings, cubicBezier, linear, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeOutExpo, easeOutBack, easeInBack, easeInOutBack, easeOutElastic, easeOutBounce, resolveEasing, type Easing, type EasingName, } from "./easing.js";
|
|
27
|
+
export { createKineticType, createScenePlayer, createCamera, createColorShift, createTransition, createBeat, } from "./motion.js";
|
|
28
|
+
export type { KineticTypeFrom, KineticTypeOptions, KineticTypeStatus, KineticTypeControls, MotionScene, ScenePlayerStatus, ScenePlayerControls, CameraKeyframe, CameraOptions, ColorShiftOptions, ColorShiftStatus, ColorShiftControls, TransitionType, TransitionDirection, TransitionOptions, TransitionLayerStyle, TransitionStatus, TransitionControls, BeatOptions, BeatStatus, BeatControls, } from "./motion.js";
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* solid-drift
|
|
2
|
+
* solid-drift: signal-native animation for SolidJS.
|
|
3
3
|
*
|
|
4
4
|
* Animate values, not elements: springs and tweens follow your signals, and
|
|
5
5
|
* retargeting mid-flight is seamless by design.
|
|
6
6
|
*/
|
|
7
|
-
export { createSpring } from "./spring.js";
|
|
7
|
+
export { createSpring, springPresets } from "./spring.js";
|
|
8
8
|
export { createTween } from "./tween.js";
|
|
9
9
|
export { animate, } from "./animate.js";
|
|
10
10
|
export { drift } from "./directive.js";
|
|
@@ -12,4 +12,16 @@ export { createScrollProgress } from "./scroll.js";
|
|
|
12
12
|
export { createInView } from "./inview.js";
|
|
13
13
|
export { usePrefersReducedMotion, prefersReducedMotion, } from "./reduced-motion.js";
|
|
14
14
|
export { createStagger } from "./stagger.js";
|
|
15
|
-
export {
|
|
15
|
+
export { createHorizontalScroll, } from "./horizontal.js";
|
|
16
|
+
export { createScrub } from "./scrub.js";
|
|
17
|
+
export { createScrollColor, createScrollTracking, createScrollLine, } from "./scrollfx.js";
|
|
18
|
+
export { createVelocity } from "./velocity.js";
|
|
19
|
+
export { createMagnetic, createTilt, } from "./pointer.js";
|
|
20
|
+
export { createTrail } from "./trail.js";
|
|
21
|
+
export { createTimeline, } from "./timeline.js";
|
|
22
|
+
export { animateFlip } from "./flip.js";
|
|
23
|
+
export { createSquashStretch, createFollowThrough, createAnticipation, createWobble, } from "./cartoon.js";
|
|
24
|
+
export { createGravity, createPendulum, createFling, } from "./physics.js";
|
|
25
|
+
export { createFontSwap, createTyping, createTextPhysics, createTextTunnel, createTextCutout, createTextGradient, createTextScramble, createTextWave, } from "./typography.js";
|
|
26
|
+
export { easings, cubicBezier, linear, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeOutExpo, easeOutBack, easeInBack, easeInOutBack, easeOutElastic, easeOutBounce, resolveEasing, } from "./easing.js";
|
|
27
|
+
export { createKineticType, createScenePlayer, createCamera, createColorShift, createTransition, createBeat, } from "./motion.js";
|
package/dist/inview.d.ts
CHANGED
|
@@ -9,16 +9,16 @@ export interface InViewOptions {
|
|
|
9
9
|
* A boolean signal reporting whether an element is visible in the viewport.
|
|
10
10
|
*
|
|
11
11
|
* Built on IntersectionObserver: cheap, off-main-thread, and exact. With
|
|
12
|
-
* `once: true` (default) the signal latches on first visibility
|
|
12
|
+
* `once: true` (default) the signal latches on first visibility, ideal
|
|
13
13
|
* for entrance animations. Set `once: false` for a live in/out signal.
|
|
14
14
|
*
|
|
15
15
|
* The observer is created when the ref resolves and disconnected on
|
|
16
16
|
* cleanup. SSR-safe: returns a constant `false` accessor on the server.
|
|
17
17
|
*
|
|
18
18
|
* ```tsx
|
|
19
|
-
* let card: HTMLDivElement | undefined
|
|
20
|
-
* const inView = createInView(() => card)
|
|
21
|
-
* const opacity = createTween(() => (inView() ? 1 : 0), { duration: 400 })
|
|
19
|
+
* let card: HTMLDivElement | undefined
|
|
20
|
+
* const inView = createInView(() => card)
|
|
21
|
+
* const opacity = createTween(() => (inView() ? 1 : 0), { duration: 400 })
|
|
22
22
|
* <div ref={card} style={{ opacity: opacity() }}>…</div>
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
package/dist/inview.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { createEffect, createSignal, onCleanup
|
|
1
|
+
import { createEffect, createSignal, onCleanup } from "solid-js";
|
|
2
2
|
/**
|
|
3
3
|
* A boolean signal reporting whether an element is visible in the viewport.
|
|
4
4
|
*
|
|
5
5
|
* Built on IntersectionObserver: cheap, off-main-thread, and exact. With
|
|
6
|
-
* `once: true` (default) the signal latches on first visibility
|
|
6
|
+
* `once: true` (default) the signal latches on first visibility, ideal
|
|
7
7
|
* for entrance animations. Set `once: false` for a live in/out signal.
|
|
8
8
|
*
|
|
9
9
|
* The observer is created when the ref resolves and disconnected on
|
|
10
10
|
* cleanup. SSR-safe: returns a constant `false` accessor on the server.
|
|
11
11
|
*
|
|
12
12
|
* ```tsx
|
|
13
|
-
* let card: HTMLDivElement | undefined
|
|
14
|
-
* const inView = createInView(() => card)
|
|
15
|
-
* const opacity = createTween(() => (inView() ? 1 : 0), { duration: 400 })
|
|
13
|
+
* let card: HTMLDivElement | undefined
|
|
14
|
+
* const inView = createInView(() => card)
|
|
15
|
+
* const opacity = createTween(() => (inView() ? 1 : 0), { duration: 400 })
|
|
16
16
|
* <div ref={card} style={{ opacity: opacity() }}>…</div>
|
|
17
17
|
* ```
|
|
18
18
|
*/
|