use-scroll-animate 1.4.0 → 2.0.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/CHANGELOG.md +68 -0
- package/README.md +184 -10
- package/README_ja.md +57 -1
- package/README_zh.md +68 -1
- package/dist/{index.mjs → chunks/core-CH41ekIo.cjs} +366 -393
- package/dist/chunks/core-CH41ekIo.cjs.map +1 -0
- package/dist/{index.esm.js → chunks/core-FUEi4ncH.js} +351 -393
- package/dist/chunks/core-FUEi4ncH.js.map +1 -0
- package/dist/chunks/stagger-DabrnrcE.js +84 -0
- package/dist/chunks/stagger-DabrnrcE.js.map +1 -0
- package/dist/chunks/stagger-XD-0-FQz.cjs +86 -0
- package/dist/chunks/stagger-XD-0-FQz.cjs.map +1 -0
- package/dist/element.cjs +97 -0
- package/dist/element.cjs.map +1 -0
- package/dist/{types/types.d.ts → element.d.cts} +87 -10
- package/dist/element.d.ts +216 -0
- package/dist/element.js +95 -0
- package/dist/element.js.map +1 -0
- package/dist/element.umd.js +2 -0
- package/dist/element.umd.js.map +1 -0
- package/dist/index.cjs +241 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{index.d.mts → index.d.cts} +98 -51
- package/dist/index.d.ts +98 -51
- package/dist/index.js +105 -1070
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +5 -3
- package/dist/index.umd.js.map +1 -1
- package/dist/react.cjs +67 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +159 -0
- package/dist/react.d.ts +159 -0
- package/dist/react.js +64 -0
- package/dist/react.js.map +1 -0
- package/dist/solid.cjs +62 -0
- package/dist/solid.cjs.map +1 -0
- package/dist/solid.d.cts +245 -0
- package/dist/solid.d.ts +245 -0
- package/dist/solid.js +58 -0
- package/dist/solid.js.map +1 -0
- package/dist/svelte.cjs +65 -0
- package/dist/svelte.cjs.map +1 -0
- package/dist/svelte.d.cts +244 -0
- package/dist/svelte.d.ts +244 -0
- package/dist/svelte.js +62 -0
- package/dist/svelte.js.map +1 -0
- package/dist/vue.cjs +61 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.d.cts +159 -0
- package/dist/vue.d.ts +159 -0
- package/dist/vue.js +59 -0
- package/dist/vue.js.map +1 -0
- package/docs/API.md +139 -0
- package/docs/deprecations.md +20 -0
- package/docs/migration-from-aos.md +67 -0
- package/docs/migration-from-gsap-scrolltrigger.md +80 -0
- package/package.json +86 -15
- package/dist/index.esm.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/types/core.d.ts +0 -41
- package/dist/types/index.d.ts +0 -36
- package/dist/types/presets.d.ts +0 -15
- package/dist/types/react.d.ts +0 -29
- package/dist/types/sequence.d.ts +0 -38
- package/dist/types/stagger.d.ts +0 -25
- package/dist/types/vue.d.ts +0 -28
package/dist/index.js
CHANGED
|
@@ -1,945 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* use-scroll-animate - Animation Presets
|
|
7
|
-
* Defines keyframes for all built-in animation presets
|
|
8
|
-
*/
|
|
9
|
-
const PRESETS = {
|
|
10
|
-
'fade-in': {
|
|
11
|
-
from: { opacity: 0 },
|
|
12
|
-
to: { opacity: 1 },
|
|
13
|
-
},
|
|
14
|
-
'fade-in-up': {
|
|
15
|
-
from: { opacity: 0, transform: 'translateY(40px)' },
|
|
16
|
-
to: { opacity: 1, transform: 'translateY(0px)' },
|
|
17
|
-
},
|
|
18
|
-
'fade-in-down': {
|
|
19
|
-
from: { opacity: 0, transform: 'translateY(-40px)' },
|
|
20
|
-
to: { opacity: 1, transform: 'translateY(0px)' },
|
|
21
|
-
},
|
|
22
|
-
'fade-in-left': {
|
|
23
|
-
from: { opacity: 0, transform: 'translateX(-40px)' },
|
|
24
|
-
to: { opacity: 1, transform: 'translateX(0px)' },
|
|
25
|
-
},
|
|
26
|
-
'fade-in-right': {
|
|
27
|
-
from: { opacity: 0, transform: 'translateX(40px)' },
|
|
28
|
-
to: { opacity: 1, transform: 'translateX(0px)' },
|
|
29
|
-
},
|
|
30
|
-
'zoom-in': {
|
|
31
|
-
from: { opacity: 0, transform: 'scale(0.8)' },
|
|
32
|
-
to: { opacity: 1, transform: 'scale(1)' },
|
|
33
|
-
},
|
|
34
|
-
'zoom-out': {
|
|
35
|
-
from: { opacity: 0, transform: 'scale(1.2)' },
|
|
36
|
-
to: { opacity: 1, transform: 'scale(1)' },
|
|
37
|
-
},
|
|
38
|
-
'flip-x': {
|
|
39
|
-
from: { opacity: 0, transform: 'rotateX(-90deg)' },
|
|
40
|
-
to: { opacity: 1, transform: 'rotateX(0deg)' },
|
|
41
|
-
},
|
|
42
|
-
'flip-y': {
|
|
43
|
-
from: { opacity: 0, transform: 'rotateY(-90deg)' },
|
|
44
|
-
to: { opacity: 1, transform: 'rotateY(0deg)' },
|
|
45
|
-
},
|
|
46
|
-
'slide-up': {
|
|
47
|
-
from: { transform: 'translateY(100%)' },
|
|
48
|
-
to: { transform: 'translateY(0px)' },
|
|
49
|
-
},
|
|
50
|
-
'slide-down': {
|
|
51
|
-
from: { transform: 'translateY(-100%)' },
|
|
52
|
-
to: { transform: 'translateY(0px)' },
|
|
53
|
-
},
|
|
54
|
-
'slide-left': {
|
|
55
|
-
from: { transform: 'translateX(-100%)' },
|
|
56
|
-
to: { transform: 'translateX(0px)' },
|
|
57
|
-
},
|
|
58
|
-
'slide-right': {
|
|
59
|
-
from: { transform: 'translateX(100%)' },
|
|
60
|
-
to: { transform: 'translateX(0px)' },
|
|
61
|
-
},
|
|
62
|
-
'bounce': {
|
|
63
|
-
from: { opacity: 0, transform: 'translateY(-60px)' },
|
|
64
|
-
to: { opacity: 1, transform: 'translateY(0px)' },
|
|
65
|
-
},
|
|
66
|
-
'rotate-in': {
|
|
67
|
-
from: { opacity: 0, transform: 'rotate(-180deg) scale(0.5)' },
|
|
68
|
-
to: { opacity: 1, transform: 'rotate(0deg) scale(1)' },
|
|
69
|
-
},
|
|
70
|
-
'blur-in': {
|
|
71
|
-
from: { opacity: 0, filter: 'blur(12px)' },
|
|
72
|
-
to: { opacity: 1, filter: 'blur(0px)' },
|
|
73
|
-
},
|
|
74
|
-
'skew-in': {
|
|
75
|
-
from: { opacity: 0, transform: 'skewX(20deg) translateX(30px)' },
|
|
76
|
-
to: { opacity: 1, transform: 'skewX(0deg) translateX(0px)' },
|
|
77
|
-
},
|
|
78
|
-
'scale-x': {
|
|
79
|
-
from: { transform: 'scaleX(0)' },
|
|
80
|
-
to: { transform: 'scaleX(1)' },
|
|
81
|
-
},
|
|
82
|
-
'scale-y': {
|
|
83
|
-
from: { transform: 'scaleY(0)' },
|
|
84
|
-
to: { transform: 'scaleY(1)' },
|
|
85
|
-
},
|
|
86
|
-
'shimmer': {
|
|
87
|
-
from: { opacity: 0.5, filter: 'brightness(1)' },
|
|
88
|
-
to: { opacity: 1, filter: 'brightness(1.5)' },
|
|
89
|
-
},
|
|
90
|
-
'pulse': {
|
|
91
|
-
from: { transform: 'scale(1)' },
|
|
92
|
-
to: { transform: 'scale(1.05)' },
|
|
93
|
-
},
|
|
94
|
-
'swing': {
|
|
95
|
-
from: { transform: 'rotate(-10deg)' },
|
|
96
|
-
to: { transform: 'rotate(10deg)' },
|
|
97
|
-
},
|
|
98
|
-
'scale-up': {
|
|
99
|
-
from: { opacity: 0, transform: 'scale(0.5)' },
|
|
100
|
-
to: { opacity: 1, transform: 'scale(1)' },
|
|
101
|
-
},
|
|
102
|
-
'blur-in-up': {
|
|
103
|
-
from: { opacity: 0, filter: 'blur(12px)', transform: 'translateY(40px)' },
|
|
104
|
-
to: { opacity: 1, filter: 'blur(0px)', transform: 'translateY(0px)' },
|
|
105
|
-
},
|
|
106
|
-
'flip-up': {
|
|
107
|
-
from: { opacity: 0, transform: 'perspective(800px) rotateX(60deg)' },
|
|
108
|
-
to: { opacity: 1, transform: 'perspective(800px) rotateX(0deg)' },
|
|
109
|
-
},
|
|
110
|
-
'flip-down': {
|
|
111
|
-
from: { opacity: 0, transform: 'perspective(800px) rotateX(-60deg)' },
|
|
112
|
-
to: { opacity: 1, transform: 'perspective(800px) rotateX(0deg)' },
|
|
113
|
-
},
|
|
114
|
-
'rotate-left': {
|
|
115
|
-
from: { opacity: 0, transform: 'rotate(-15deg) translateX(-40px)' },
|
|
116
|
-
to: { opacity: 1, transform: 'rotate(0deg) translateX(0px)' },
|
|
117
|
-
},
|
|
118
|
-
'rotate-right': {
|
|
119
|
-
from: { opacity: 0, transform: 'rotate(15deg) translateX(40px)' },
|
|
120
|
-
to: { opacity: 1, transform: 'rotate(0deg) translateX(0px)' },
|
|
121
|
-
},
|
|
122
|
-
// clip-path reveals: content is uncovered without moving or fading
|
|
123
|
-
'clip-up': {
|
|
124
|
-
from: { clipPath: 'inset(100% 0% 0% 0%)' },
|
|
125
|
-
to: { clipPath: 'inset(0% 0% 0% 0%)' },
|
|
126
|
-
},
|
|
127
|
-
'clip-down': {
|
|
128
|
-
from: { clipPath: 'inset(0% 0% 100% 0%)' },
|
|
129
|
-
to: { clipPath: 'inset(0% 0% 0% 0%)' },
|
|
130
|
-
},
|
|
131
|
-
'clip-left': {
|
|
132
|
-
from: { clipPath: 'inset(0% 0% 0% 100%)' },
|
|
133
|
-
to: { clipPath: 'inset(0% 0% 0% 0%)' },
|
|
134
|
-
},
|
|
135
|
-
'clip-right': {
|
|
136
|
-
from: { clipPath: 'inset(0% 100% 0% 0%)' },
|
|
137
|
-
to: { clipPath: 'inset(0% 0% 0% 0%)' },
|
|
138
|
-
},
|
|
139
|
-
'clip-circle': {
|
|
140
|
-
from: { clipPath: 'circle(0% at 50% 50%)' },
|
|
141
|
-
to: { clipPath: 'circle(75% at 50% 50%)' },
|
|
142
|
-
},
|
|
143
|
-
};
|
|
144
|
-
function resolvePreset(animation) {
|
|
145
|
-
var _a;
|
|
146
|
-
if (typeof animation === 'string') {
|
|
147
|
-
return (_a = PRESETS[animation.trim()]) !== null && _a !== void 0 ? _a : PRESETS['fade-in-up'];
|
|
148
|
-
}
|
|
149
|
-
if (Array.isArray(animation)) {
|
|
150
|
-
const combined = { from: {}, to: {} };
|
|
151
|
-
animation.forEach(name => {
|
|
152
|
-
const preset = PRESETS[name.trim()];
|
|
153
|
-
if (preset) {
|
|
154
|
-
Object.entries(preset.from).forEach(([key, val]) => {
|
|
155
|
-
if (key === 'transform' && combined.from[key]) {
|
|
156
|
-
combined.from[key] = `${combined.from[key]} ${val}`;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
combined.from[key] = val;
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
Object.entries(preset.to).forEach(([key, val]) => {
|
|
163
|
-
if (key === 'transform' && combined.to[key]) {
|
|
164
|
-
combined.to[key] = `${combined.to[key]} ${val}`;
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
combined.to[key] = val;
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
return combined;
|
|
173
|
-
}
|
|
174
|
-
return animation;
|
|
175
|
-
}
|
|
176
|
-
/** Easing to CSS cubic-bezier mapping */
|
|
177
|
-
const EASING_MAP = {
|
|
178
|
-
linear: 'linear',
|
|
179
|
-
ease: 'ease',
|
|
180
|
-
'ease-in': 'ease-in',
|
|
181
|
-
'ease-out': 'ease-out',
|
|
182
|
-
'ease-in-out': 'ease-in-out',
|
|
183
|
-
spring: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
|
|
184
|
-
'soft-spring': 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
|
|
185
|
-
'heavy-bounce': 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
|
|
186
|
-
};
|
|
187
|
-
function resolveEasing(easing) {
|
|
188
|
-
var _a;
|
|
189
|
-
if (typeof easing === 'string') {
|
|
190
|
-
return (_a = EASING_MAP[easing]) !== null && _a !== void 0 ? _a : easing;
|
|
191
|
-
}
|
|
192
|
-
if (Array.isArray(easing)) {
|
|
193
|
-
return `cubic-bezier(${easing.join(', ')})`;
|
|
194
|
-
}
|
|
195
|
-
if (typeof easing === 'function') {
|
|
196
|
-
// Functions cannot be expressed as a CSS easing string; the core samples
|
|
197
|
-
// them into a `linear()` easing (or keyframes on older browsers).
|
|
198
|
-
return 'linear';
|
|
199
|
-
}
|
|
200
|
-
return 'ease';
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* use-scroll-animate - Core Implementation
|
|
205
|
-
* Uses IntersectionObserver + Web Animations API for zero-dependency,
|
|
206
|
-
* high-performance scroll-triggered animations.
|
|
207
|
-
*/
|
|
208
|
-
const DEFAULT_CONFIG = {
|
|
209
|
-
defaultAnimation: 'fade-in-up',
|
|
210
|
-
defaultDuration: 600,
|
|
211
|
-
defaultDelay: 0,
|
|
212
|
-
defaultEasing: 'ease',
|
|
213
|
-
defaultThreshold: 0.1,
|
|
214
|
-
defaultRootMargin: '0px',
|
|
215
|
-
defaultRepeat: false,
|
|
216
|
-
defaultOnce: true,
|
|
217
|
-
defaultOffset: 0,
|
|
218
|
-
hiddenClass: 'sa-hidden',
|
|
219
|
-
visibleClass: 'sa-visible',
|
|
220
|
-
useClassNames: false,
|
|
221
|
-
disabled: false,
|
|
222
|
-
root: null,
|
|
223
|
-
autoUnregister: true,
|
|
224
|
-
};
|
|
225
|
-
const noop = () => undefined;
|
|
226
|
-
/* ------------------------------------------------------------------ */
|
|
227
|
-
/* Environment helpers (all SSR-safe: never touch globals at import) */
|
|
228
|
-
/* ------------------------------------------------------------------ */
|
|
229
|
-
const hasDOM = () => typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
230
|
-
/** @internal */
|
|
231
|
-
const supportsObserver = () => hasDOM() && typeof IntersectionObserver !== 'undefined';
|
|
232
|
-
let reducedMotionQuery;
|
|
233
|
-
/** @internal Whether the user asked the OS/browser to reduce motion. */
|
|
234
|
-
function prefersReducedMotion() {
|
|
235
|
-
if (!hasDOM())
|
|
236
|
-
return false;
|
|
237
|
-
if (reducedMotionQuery === undefined) {
|
|
238
|
-
reducedMotionQuery =
|
|
239
|
-
typeof window.matchMedia === 'function' ? window.matchMedia('(prefers-reduced-motion: reduce)') : null;
|
|
240
|
-
}
|
|
241
|
-
return !!reducedMotionQuery && reducedMotionQuery.matches;
|
|
242
|
-
}
|
|
243
|
-
/* ------------------------------------------------------------------ */
|
|
244
|
-
/* Option parsing */
|
|
245
|
-
/* ------------------------------------------------------------------ */
|
|
246
|
-
function num(value) {
|
|
247
|
-
if (value === undefined || value.trim() === '')
|
|
248
|
-
return undefined;
|
|
249
|
-
const n = parseFloat(value);
|
|
250
|
-
return Number.isFinite(n) ? n : undefined;
|
|
251
|
-
}
|
|
252
|
-
/** Numeric strings ("100") become numbers (px); strings with units stay as-is. */
|
|
253
|
-
function lengthValue(value) {
|
|
254
|
-
if (value === undefined || value.trim() === '')
|
|
255
|
-
return undefined;
|
|
256
|
-
const v = value.trim();
|
|
257
|
-
return /^-?(\d+\.?\d*|\.\d+)$/.test(v) ? parseFloat(v) : v;
|
|
258
|
-
}
|
|
259
|
-
function parseDataAttributes(el, config) {
|
|
260
|
-
var _a;
|
|
261
|
-
const dataset = el.dataset || {};
|
|
262
|
-
const opts = {};
|
|
263
|
-
if (dataset.saAnimation) {
|
|
264
|
-
const anim = dataset.saAnimation;
|
|
265
|
-
opts.animation = (anim.includes(',') ? anim.split(',').map((s) => s.trim()) : anim.trim());
|
|
266
|
-
}
|
|
267
|
-
opts.duration = num(dataset.saDuration);
|
|
268
|
-
opts.delay = num(dataset.saDelay);
|
|
269
|
-
if (dataset.saEasing) {
|
|
270
|
-
const e = dataset.saEasing.trim();
|
|
271
|
-
if (e.startsWith('[')) {
|
|
272
|
-
try {
|
|
273
|
-
opts.easing = JSON.parse(e);
|
|
274
|
-
}
|
|
275
|
-
catch (_b) {
|
|
276
|
-
// Malformed JSON: fall back to the default easing instead of throwing
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
280
|
-
opts.easing = e;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
if (dataset.saThreshold) {
|
|
284
|
-
const t = dataset.saThreshold;
|
|
285
|
-
opts.threshold = t.includes(',')
|
|
286
|
-
? t.split(',').map(parseFloat).filter(Number.isFinite)
|
|
287
|
-
: num(t);
|
|
288
|
-
}
|
|
289
|
-
if (dataset.saRootMargin)
|
|
290
|
-
opts.rootMargin = dataset.saRootMargin;
|
|
291
|
-
if (dataset.saRepeat !== undefined)
|
|
292
|
-
opts.repeat = dataset.saRepeat !== 'false';
|
|
293
|
-
if (dataset.saOnce !== undefined)
|
|
294
|
-
opts.once = dataset.saOnce !== 'false';
|
|
295
|
-
opts.offset = num(dataset.saOffset);
|
|
296
|
-
opts.stagger = num(dataset.saStagger);
|
|
297
|
-
if (dataset.saProgress)
|
|
298
|
-
opts.progressMode = dataset.saProgress.trim() === 'scroll' ? 'scroll' : 'ratio';
|
|
299
|
-
if (dataset.saParallaxX || dataset.saParallaxY || dataset.saParallaxRotate || dataset.saParallaxScale) {
|
|
300
|
-
opts.parallax = {
|
|
301
|
-
x: lengthValue(dataset.saParallaxX),
|
|
302
|
-
y: lengthValue(dataset.saParallaxY),
|
|
303
|
-
rotate: num(dataset.saParallaxRotate),
|
|
304
|
-
scale: num(dataset.saParallaxScale),
|
|
305
|
-
speed: (_a = num(dataset.saParallaxSpeed)) !== null && _a !== void 0 ? _a : 1,
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
return mergeOptions(opts, config);
|
|
309
|
-
}
|
|
310
|
-
function mergeOptions(opts, config) {
|
|
311
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
312
|
-
const repeat = (_a = opts.repeat) !== null && _a !== void 0 ? _a : config.defaultRepeat;
|
|
313
|
-
const threshold = (_b = opts.threshold) !== null && _b !== void 0 ? _b : config.defaultThreshold;
|
|
314
|
-
return {
|
|
315
|
-
animation: (_c = opts.animation) !== null && _c !== void 0 ? _c : config.defaultAnimation,
|
|
316
|
-
duration: (_d = opts.duration) !== null && _d !== void 0 ? _d : config.defaultDuration,
|
|
317
|
-
delay: (_e = opts.delay) !== null && _e !== void 0 ? _e : config.defaultDelay,
|
|
318
|
-
easing: (_f = opts.easing) !== null && _f !== void 0 ? _f : config.defaultEasing,
|
|
319
|
-
threshold: Array.isArray(threshold) && threshold.length === 0 ? config.defaultThreshold : threshold,
|
|
320
|
-
rootMargin: (_g = opts.rootMargin) !== null && _g !== void 0 ? _g : config.defaultRootMargin,
|
|
321
|
-
repeat,
|
|
322
|
-
once: (_h = opts.once) !== null && _h !== void 0 ? _h : (repeat ? false : config.defaultOnce),
|
|
323
|
-
offset: (_j = opts.offset) !== null && _j !== void 0 ? _j : config.defaultOffset,
|
|
324
|
-
stagger: (_k = opts.stagger) !== null && _k !== void 0 ? _k : 0,
|
|
325
|
-
parallax: (_l = opts.parallax) !== null && _l !== void 0 ? _l : {},
|
|
326
|
-
onStart: (_m = opts.onStart) !== null && _m !== void 0 ? _m : noop,
|
|
327
|
-
onComplete: (_o = opts.onComplete) !== null && _o !== void 0 ? _o : noop,
|
|
328
|
-
onEnter: (_p = opts.onEnter) !== null && _p !== void 0 ? _p : noop,
|
|
329
|
-
onLeave: (_q = opts.onLeave) !== null && _q !== void 0 ? _q : noop,
|
|
330
|
-
onProgress: (_r = opts.onProgress) !== null && _r !== void 0 ? _r : noop,
|
|
331
|
-
progressMode: (_s = opts.progressMode) !== null && _s !== void 0 ? _s : 'ratio',
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
function resolveTargets(target) {
|
|
335
|
-
if (!target || !hasDOM())
|
|
336
|
-
return [];
|
|
337
|
-
if (typeof target === 'string')
|
|
338
|
-
return Array.from(document.querySelectorAll(target));
|
|
339
|
-
if (target instanceof Element)
|
|
340
|
-
return [target];
|
|
341
|
-
if (Array.isArray(target) || target instanceof NodeList) {
|
|
342
|
-
return Array.from(target).filter((el) => el instanceof Element);
|
|
343
|
-
}
|
|
344
|
-
return [];
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* Apply `offset` to the bottom edge of a rootMargin, preserving the other
|
|
348
|
-
* three sides. `offset: 100` means "trigger 100px later" (bottom -100px).
|
|
349
|
-
* @internal
|
|
350
|
-
*/
|
|
351
|
-
function applyOffset(rootMargin, offset) {
|
|
352
|
-
var _a, _b, _c;
|
|
353
|
-
if (!offset)
|
|
354
|
-
return rootMargin;
|
|
355
|
-
const parts = (rootMargin || '0px').trim().split(/\s+/);
|
|
356
|
-
const top = parts[0];
|
|
357
|
-
const right = (_a = parts[1]) !== null && _a !== void 0 ? _a : top;
|
|
358
|
-
const bottom = (_b = parts[2]) !== null && _b !== void 0 ? _b : top;
|
|
359
|
-
const left = (_c = parts[3]) !== null && _c !== void 0 ? _c : right;
|
|
360
|
-
const m = /^(-?\d*\.?\d+)(px)?$/.exec(bottom);
|
|
361
|
-
const base = m ? parseFloat(m[1]) : 0; // non-px bottoms (e.g. %) cannot be combined; offset wins
|
|
362
|
-
return `${top} ${right} ${base - offset}px ${left}`;
|
|
363
|
-
}
|
|
364
|
-
function hasParallax(p) {
|
|
365
|
-
return !!p && Object.keys(p).some((k) => p[k] !== undefined);
|
|
366
|
-
}
|
|
367
|
-
function needsProgress(opts) {
|
|
368
|
-
return hasParallax(opts.parallax) || opts.onProgress !== noop;
|
|
369
|
-
}
|
|
370
|
-
/**
|
|
371
|
-
* True scroll progress of `el` through the viewport (or `root`): 0 when its top
|
|
372
|
-
* edge reaches the bottom of the viewport, 1 when its bottom edge passes the top.
|
|
373
|
-
* Works for elements taller than the viewport. Returns 0 without a DOM.
|
|
374
|
-
*/
|
|
375
|
-
function getScrollProgress(el, root) {
|
|
376
|
-
if (!hasDOM())
|
|
377
|
-
return 0;
|
|
378
|
-
const rect = el.getBoundingClientRect();
|
|
379
|
-
let top = 0;
|
|
380
|
-
let height = window.innerHeight || document.documentElement.clientHeight || 0;
|
|
381
|
-
if (root) {
|
|
382
|
-
const r = root.getBoundingClientRect();
|
|
383
|
-
top = r.top;
|
|
384
|
-
height = r.height;
|
|
385
|
-
}
|
|
386
|
-
const total = height + rect.height;
|
|
387
|
-
if (total <= 0)
|
|
388
|
-
return 0;
|
|
389
|
-
const p = (top + height - rect.top) / total;
|
|
390
|
-
return p < 0 ? 0 : p > 1 ? 1 : p;
|
|
391
|
-
}
|
|
392
|
-
/* ------------------------------------------------------------------ */
|
|
393
|
-
/* Animation */
|
|
394
|
-
/* ------------------------------------------------------------------ */
|
|
395
|
-
/** The animation currently running on an element, so it can be cancelled/replaced. */
|
|
396
|
-
const running = new WeakMap();
|
|
397
|
-
const timers = new WeakMap();
|
|
398
|
-
function cancelRunning(el) {
|
|
399
|
-
const anim = running.get(el);
|
|
400
|
-
if (anim) {
|
|
401
|
-
running.delete(el);
|
|
402
|
-
anim.onfinish = null;
|
|
403
|
-
anim.cancel();
|
|
404
|
-
}
|
|
405
|
-
const timer = timers.get(el);
|
|
406
|
-
if (timer !== undefined) {
|
|
407
|
-
clearTimeout(timer);
|
|
408
|
-
timers.delete(el);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
function setStyles(el, styles) {
|
|
412
|
-
const style = el.style;
|
|
413
|
-
if (!style)
|
|
414
|
-
return;
|
|
415
|
-
Object.keys(styles).forEach((prop) => {
|
|
416
|
-
style[prop] = String(styles[prop]);
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
const NUM_UNIT = /(-?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?)([a-z%]*)/gi;
|
|
420
|
-
/**
|
|
421
|
-
* Interpolate two CSS values at `t`. Numbers interpolate directly; strings
|
|
422
|
-
* interpolate when they share the same structure (e.g. `translateY(40px)` ->
|
|
423
|
-
* `translateY(0px)`, or `scale(0.8)` -> `scale(1)`). Otherwise snaps at 0.5.
|
|
424
|
-
* @internal
|
|
425
|
-
*/
|
|
426
|
-
function interpolateValue(from, to, t) {
|
|
427
|
-
if (typeof from === 'number' && typeof to === 'number')
|
|
428
|
-
return from + (to - from) * t;
|
|
429
|
-
const a = String(from);
|
|
430
|
-
const b = String(to);
|
|
431
|
-
const ta = [];
|
|
432
|
-
const tb = [];
|
|
433
|
-
const skA = a.replace(NUM_UNIT, (_, n, u) => (ta.push([parseFloat(n), u]), '#'));
|
|
434
|
-
const skB = b.replace(NUM_UNIT, (_, n, u) => (tb.push([parseFloat(n), u]), '#'));
|
|
435
|
-
if (skA !== skB || ta.length !== tb.length)
|
|
436
|
-
return t < 0.5 ? from : to;
|
|
437
|
-
let i = 0;
|
|
438
|
-
let ok = true;
|
|
439
|
-
const out = skA.replace(/#/g, () => {
|
|
440
|
-
const [na, ua] = ta[i];
|
|
441
|
-
const [nb, ub] = tb[i++];
|
|
442
|
-
if (ua !== ub && na !== 0 && nb !== 0 && ua && ub)
|
|
443
|
-
ok = false;
|
|
444
|
-
const unit = ua || ub;
|
|
445
|
-
return `${+(na + (nb - na) * t).toFixed(4)}${unit}`;
|
|
446
|
-
});
|
|
447
|
-
return ok ? out : t < 0.5 ? from : to;
|
|
448
|
-
}
|
|
449
|
-
const EASING_SAMPLES = 30;
|
|
450
|
-
let linearSupported;
|
|
451
|
-
function supportsLinearEasing() {
|
|
452
|
-
if (linearSupported === undefined) {
|
|
453
|
-
linearSupported =
|
|
454
|
-
typeof CSS !== 'undefined' &&
|
|
455
|
-
typeof CSS.supports === 'function' &&
|
|
456
|
-
CSS.supports('animation-timing-function', 'linear(0, 1)');
|
|
457
|
-
}
|
|
458
|
-
return linearSupported;
|
|
459
|
-
}
|
|
460
|
-
function sampleEasing(fn) {
|
|
461
|
-
const values = [];
|
|
462
|
-
for (let i = 0; i <= EASING_SAMPLES; i++) {
|
|
463
|
-
const v = fn(i / EASING_SAMPLES);
|
|
464
|
-
values.push(Number.isFinite(v) ? +v.toFixed(4) : i / EASING_SAMPLES);
|
|
465
|
-
}
|
|
466
|
-
return values;
|
|
467
|
-
}
|
|
468
|
-
function buildAnimation(preset, easing) {
|
|
469
|
-
if (typeof easing !== 'function') {
|
|
470
|
-
return { keyframes: [preset.from, preset.to], easing: resolveEasing(easing) };
|
|
471
|
-
}
|
|
472
|
-
const samples = sampleEasing(easing);
|
|
473
|
-
// Modern browsers: an exact, property-agnostic `linear()` easing curve.
|
|
474
|
-
if (supportsLinearEasing()) {
|
|
475
|
-
return { keyframes: [preset.from, preset.to], easing: `linear(${samples.join(', ')})` };
|
|
476
|
-
}
|
|
477
|
-
// Fallback: approximate the curve with interpolated keyframes.
|
|
478
|
-
const props = Object.keys(preset.from).filter((p) => p in preset.to);
|
|
479
|
-
const keyframes = samples.map((eased, i) => {
|
|
480
|
-
const frame = { offset: i / EASING_SAMPLES };
|
|
481
|
-
props.forEach((prop) => {
|
|
482
|
-
frame[prop] = interpolateValue(preset.from[prop], preset.to[prop], eased);
|
|
483
|
-
});
|
|
484
|
-
return frame;
|
|
485
|
-
});
|
|
486
|
-
return { keyframes, easing: 'linear' };
|
|
487
|
-
}
|
|
488
|
-
/** Make an element visible without animating (reduced motion / disabled / no WAAPI). */
|
|
489
|
-
function reveal(el, config) {
|
|
490
|
-
cancelRunning(el);
|
|
491
|
-
if (config.useClassNames) {
|
|
492
|
-
el.classList.remove(config.hiddenClass);
|
|
493
|
-
el.classList.add(config.visibleClass);
|
|
494
|
-
}
|
|
495
|
-
else {
|
|
496
|
-
const style = el.style;
|
|
497
|
-
if (style)
|
|
498
|
-
style.opacity = '';
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
/** @internal Cancel a running/pending animation and make the element visible. */
|
|
502
|
-
function stopAnimation(el, config = {}) {
|
|
503
|
-
reveal(el, { ...DEFAULT_CONFIG, ...config });
|
|
504
|
-
}
|
|
505
|
-
/** @internal Whether animations should be skipped entirely. */
|
|
506
|
-
function motionDisabled(config) {
|
|
507
|
-
return !!config.disabled || prefersReducedMotion();
|
|
508
|
-
}
|
|
509
|
-
function runAnimation(el, opts, config, staggerIndex = 0) {
|
|
510
|
-
const { duration, delay, stagger, onStart, onComplete } = opts;
|
|
511
|
-
const totalDelay = Math.max(0, delay + staggerIndex * stagger);
|
|
512
|
-
cancelRunning(el);
|
|
513
|
-
if (motionDisabled(config)) {
|
|
514
|
-
reveal(el, config);
|
|
515
|
-
onStart(el);
|
|
516
|
-
onComplete(el);
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
if (config.useClassNames) {
|
|
520
|
-
if (totalDelay > 0)
|
|
521
|
-
el.style.animationDelay = `${totalDelay}ms`;
|
|
522
|
-
el.classList.remove(config.hiddenClass);
|
|
523
|
-
el.classList.add(config.visibleClass);
|
|
524
|
-
onStart(el);
|
|
525
|
-
timers.set(el, setTimeout(() => {
|
|
526
|
-
timers.delete(el);
|
|
527
|
-
onComplete(el);
|
|
528
|
-
}, duration + totalDelay));
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
const preset = resolvePreset(opts.animation);
|
|
532
|
-
// Presets that don't animate opacity (slide-*, clip-*, scale-x, ...) would
|
|
533
|
-
// otherwise stay at the `opacity: 0` applied while waiting to enter.
|
|
534
|
-
if (!('opacity' in preset.to)) {
|
|
535
|
-
const style = el.style;
|
|
536
|
-
if (style && style.opacity === '0')
|
|
537
|
-
style.opacity = '';
|
|
538
|
-
}
|
|
539
|
-
if (typeof el.animate !== 'function') {
|
|
540
|
-
setStyles(el, preset.to);
|
|
541
|
-
onStart(el);
|
|
542
|
-
onComplete(el);
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
|
-
const built = buildAnimation(preset, opts.easing);
|
|
546
|
-
const timing = { duration, delay: totalDelay, easing: built.easing, fill: 'both' };
|
|
547
|
-
let anim;
|
|
548
|
-
try {
|
|
549
|
-
anim = el.animate(built.keyframes, timing);
|
|
550
|
-
}
|
|
551
|
-
catch (_a) {
|
|
552
|
-
// Invalid user easing string (WAAPI throws a TypeError): fall back to 'ease'
|
|
553
|
-
anim = el.animate(built.keyframes, { ...timing, easing: 'ease' });
|
|
554
|
-
}
|
|
555
|
-
running.set(el, anim);
|
|
556
|
-
onStart(el);
|
|
557
|
-
anim.onfinish = () => {
|
|
558
|
-
if (running.get(el) === anim) {
|
|
559
|
-
running.delete(el);
|
|
560
|
-
// Persist the end state inline and drop the filling animation. This frees
|
|
561
|
-
// the Animation object and lets later inline styles (parallax, user code)
|
|
562
|
-
// take effect instead of being masked by `fill: forwards`.
|
|
563
|
-
try {
|
|
564
|
-
anim.commitStyles();
|
|
565
|
-
}
|
|
566
|
-
catch (_a) {
|
|
567
|
-
setStyles(el, preset.to);
|
|
568
|
-
}
|
|
569
|
-
anim.cancel();
|
|
570
|
-
}
|
|
571
|
-
onComplete(el);
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
function applyParallax(el, progress, parallax) {
|
|
575
|
-
const { x = 0, y = 0, rotate = 0, scale = 1, speed = 1 } = parallax;
|
|
576
|
-
const p = (progress - 0.5) * 2 * speed;
|
|
577
|
-
const axis = (v) => (typeof v === 'number' ? `${v * p}px` : `calc(${v} * ${p})`);
|
|
578
|
-
let transform = '';
|
|
579
|
-
if (x)
|
|
580
|
-
transform += ` translateX(${axis(x)})`;
|
|
581
|
-
if (y)
|
|
582
|
-
transform += ` translateY(${axis(y)})`;
|
|
583
|
-
if (rotate)
|
|
584
|
-
transform += ` rotate(${rotate * p}deg)`;
|
|
585
|
-
if (scale !== 1)
|
|
586
|
-
transform += ` scale(${1 + (scale - 1) * p})`;
|
|
587
|
-
el.style.transform = transform.trim();
|
|
588
|
-
}
|
|
589
|
-
function hideElement(el, config) {
|
|
590
|
-
cancelRunning(el);
|
|
591
|
-
if (config.useClassNames) {
|
|
592
|
-
el.classList.add(config.hiddenClass);
|
|
593
|
-
el.classList.remove(config.visibleClass);
|
|
594
|
-
}
|
|
595
|
-
else {
|
|
596
|
-
const style = el.style;
|
|
597
|
-
if (style)
|
|
598
|
-
style.opacity = '0';
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
/** @internal Hide an element before its entrance animation, unless motion is off. */
|
|
602
|
-
function prepareElement(el, config = {}) {
|
|
603
|
-
const full = { ...DEFAULT_CONFIG, ...config };
|
|
604
|
-
if (!motionDisabled(full))
|
|
605
|
-
hideElement(el, full);
|
|
606
|
-
}
|
|
607
|
-
let progressThresholds;
|
|
608
|
-
function getProgressThresholds() {
|
|
609
|
-
if (!progressThresholds) {
|
|
610
|
-
progressThresholds = [];
|
|
611
|
-
for (let i = 0; i <= 100; i++)
|
|
612
|
-
progressThresholds.push(i / 100);
|
|
613
|
-
}
|
|
614
|
-
return progressThresholds;
|
|
615
|
-
}
|
|
616
|
-
const PASSIVE = { passive: true };
|
|
617
|
-
/* ------------------------------------------------------------------ */
|
|
618
|
-
/* Instance */
|
|
619
|
-
/* ------------------------------------------------------------------ */
|
|
620
|
-
function createScrollAnimate(userConfig = {}) {
|
|
621
|
-
let config = { ...DEFAULT_CONFIG, ...userConfig };
|
|
622
|
-
const registry = new Map();
|
|
623
|
-
// `once` elements that finished and were dropped from the registry (autoUnregister).
|
|
624
|
-
let finished = new WeakSet();
|
|
625
|
-
// Elements in `progressMode: 'scroll'` that are currently inside the viewport.
|
|
626
|
-
const scrolling = new Set();
|
|
627
|
-
let frame = 0;
|
|
628
|
-
let listening = null;
|
|
629
|
-
// Observers are shared between elements with the same root/threshold/rootMargin,
|
|
630
|
-
// instead of one (or two) IntersectionObservers per element.
|
|
631
|
-
const pools = new Map();
|
|
632
|
-
function pooled(root, key, create) {
|
|
633
|
-
let pool = pools.get(root);
|
|
634
|
-
if (!pool)
|
|
635
|
-
pools.set(root, (pool = new Map()));
|
|
636
|
-
let io = pool.get(key);
|
|
637
|
-
if (!io)
|
|
638
|
-
pool.set(key, (io = create()));
|
|
639
|
-
return io;
|
|
640
|
-
}
|
|
641
|
-
function teardown(el, restore) {
|
|
642
|
-
var _a;
|
|
643
|
-
const record = registry.get(el);
|
|
644
|
-
if (!record)
|
|
645
|
-
return;
|
|
646
|
-
record.observer.unobserve(el);
|
|
647
|
-
(_a = record.progressObserver) === null || _a === void 0 ? void 0 : _a.unobserve(el);
|
|
648
|
-
registry.delete(el);
|
|
649
|
-
untrack(el);
|
|
650
|
-
// An element that never animated would otherwise stay invisible forever.
|
|
651
|
-
if (restore && !record.animated)
|
|
652
|
-
reveal(el, config);
|
|
653
|
-
}
|
|
654
|
-
function pruneDetached() {
|
|
655
|
-
registry.forEach((record, el) => {
|
|
656
|
-
if (el.isConnected === false)
|
|
657
|
-
teardown(el, false);
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
function emitProgress(el, record, progress) {
|
|
661
|
-
const opts = record.options;
|
|
662
|
-
opts.onProgress(el, progress);
|
|
663
|
-
if (hasParallax(opts.parallax) && !motionDisabled(config))
|
|
664
|
-
applyParallax(el, progress, opts.parallax);
|
|
665
|
-
}
|
|
666
|
-
function update() {
|
|
667
|
-
frame = 0;
|
|
668
|
-
scrolling.forEach((el) => {
|
|
669
|
-
const record = registry.get(el);
|
|
670
|
-
if (record)
|
|
671
|
-
emitProgress(el, record, getScrollProgress(el, config.root));
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
// rAF-throttled; IntersectionObserver-capable browsers all have rAF.
|
|
675
|
-
const schedule = () => frame || (frame = requestAnimationFrame(update));
|
|
676
|
-
function listen(on) {
|
|
677
|
-
if (on === !!listening)
|
|
678
|
-
return;
|
|
679
|
-
const method = on ? 'addEventListener' : 'removeEventListener';
|
|
680
|
-
const target = listening || config.root || window;
|
|
681
|
-
target[method]('scroll', schedule, PASSIVE);
|
|
682
|
-
window[method]('resize', schedule, PASSIVE);
|
|
683
|
-
listening = on ? target : null;
|
|
684
|
-
if (!on && frame) {
|
|
685
|
-
cancelAnimationFrame(frame);
|
|
686
|
-
frame = 0;
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
function untrack(el) {
|
|
690
|
-
if (scrolling.delete(el) && !scrolling.size)
|
|
691
|
-
listen(false);
|
|
692
|
-
}
|
|
693
|
-
function onScrollIntersect(entries) {
|
|
694
|
-
entries.forEach((entry) => {
|
|
695
|
-
const el = entry.target;
|
|
696
|
-
const record = registry.get(el);
|
|
697
|
-
if (!record)
|
|
698
|
-
return;
|
|
699
|
-
if (entry.isIntersecting) {
|
|
700
|
-
scrolling.add(el);
|
|
701
|
-
listen(true);
|
|
702
|
-
}
|
|
703
|
-
else {
|
|
704
|
-
untrack(el);
|
|
705
|
-
}
|
|
706
|
-
// Emit right away so the edges (0 / 1) are reported even on fast scrolls.
|
|
707
|
-
emitProgress(el, record, getScrollProgress(el, config.root));
|
|
708
|
-
});
|
|
709
|
-
}
|
|
710
|
-
function onIntersect(entries) {
|
|
711
|
-
const staggerCounts = new Map();
|
|
712
|
-
entries.forEach((entry) => {
|
|
713
|
-
var _a;
|
|
714
|
-
const el = entry.target;
|
|
715
|
-
const record = registry.get(el);
|
|
716
|
-
if (!record)
|
|
717
|
-
return;
|
|
718
|
-
const opts = record.options;
|
|
719
|
-
if (el.isConnected === false) {
|
|
720
|
-
teardown(el, false);
|
|
721
|
-
return;
|
|
722
|
-
}
|
|
723
|
-
if (entry.isIntersecting) {
|
|
724
|
-
opts.onEnter(el);
|
|
725
|
-
if (record.animated && !opts.repeat)
|
|
726
|
-
return;
|
|
727
|
-
// Stagger relative to siblings revealed in the same batch, so elements
|
|
728
|
-
// scrolled into view later don't inherit an ever-growing delay.
|
|
729
|
-
let staggerIndex = 0;
|
|
730
|
-
if (opts.stagger > 0) {
|
|
731
|
-
const parent = el.parentElement;
|
|
732
|
-
staggerIndex = (_a = staggerCounts.get(parent)) !== null && _a !== void 0 ? _a : 0;
|
|
733
|
-
staggerCounts.set(parent, staggerIndex + 1);
|
|
734
|
-
}
|
|
735
|
-
runAnimation(el, opts, config, staggerIndex);
|
|
736
|
-
record.animated = true;
|
|
737
|
-
if (opts.once && !opts.repeat) {
|
|
738
|
-
// Keep the progress observer: parallax/onProgress must keep working.
|
|
739
|
-
record.observer.unobserve(el);
|
|
740
|
-
if (config.autoUnregister && !record.progressObserver) {
|
|
741
|
-
// Nothing left to watch: free the record (the running animation
|
|
742
|
-
// keeps its own reference until it finishes).
|
|
743
|
-
finished.add(el);
|
|
744
|
-
teardown(el, false);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
else {
|
|
749
|
-
opts.onLeave(el);
|
|
750
|
-
if (opts.repeat && record.animated) {
|
|
751
|
-
if (!motionDisabled(config))
|
|
752
|
-
hideElement(el, config);
|
|
753
|
-
record.animated = false;
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
function onProgress(entries) {
|
|
759
|
-
entries.forEach((entry) => {
|
|
760
|
-
const record = registry.get(entry.target);
|
|
761
|
-
if (!record)
|
|
762
|
-
return;
|
|
763
|
-
emitProgress(entry.target, record, entry.intersectionRatio);
|
|
764
|
-
});
|
|
765
|
-
}
|
|
766
|
-
function getObserver(opts) {
|
|
767
|
-
const rootMargin = applyOffset(opts.rootMargin, opts.offset);
|
|
768
|
-
const threshold = opts.threshold;
|
|
769
|
-
const root = config.root;
|
|
770
|
-
return pooled(root, `m|${rootMargin}|${String(threshold)}`, () => new IntersectionObserver(onIntersect, { threshold, rootMargin, root: root }));
|
|
771
|
-
}
|
|
772
|
-
function getProgressObserver(opts) {
|
|
773
|
-
const root = config.root;
|
|
774
|
-
if (opts.progressMode === 'scroll') {
|
|
775
|
-
// Only used to know when to start/stop measuring; progress itself comes
|
|
776
|
-
// from a single shared, rAF-throttled passive scroll listener.
|
|
777
|
-
return pooled(root, `s|${opts.rootMargin}`, () => new IntersectionObserver(onScrollIntersect, { threshold: 0, rootMargin: opts.rootMargin, root: root }));
|
|
778
|
-
}
|
|
779
|
-
return pooled(root, `p|${opts.rootMargin}`, () => new IntersectionObserver(onProgress, {
|
|
780
|
-
threshold: getProgressThresholds(),
|
|
781
|
-
rootMargin: opts.rootMargin,
|
|
782
|
-
root: root,
|
|
783
|
-
}));
|
|
784
|
-
}
|
|
785
|
-
function attach(el, record, observeMain) {
|
|
786
|
-
var _a;
|
|
787
|
-
record.observer = getObserver(record.options);
|
|
788
|
-
if (observeMain)
|
|
789
|
-
record.observer.observe(el);
|
|
790
|
-
record.progressObserver = needsProgress(record.options) ? getProgressObserver(record.options) : undefined;
|
|
791
|
-
(_a = record.progressObserver) === null || _a === void 0 ? void 0 : _a.observe(el);
|
|
792
|
-
}
|
|
793
|
-
function observeElement(el, opts) {
|
|
794
|
-
if (registry.has(el) || finished.has(el))
|
|
795
|
-
return;
|
|
796
|
-
if (!supportsObserver()) {
|
|
797
|
-
// No IntersectionObserver (very old browser): never leave content hidden.
|
|
798
|
-
reveal(el, config);
|
|
799
|
-
return;
|
|
800
|
-
}
|
|
801
|
-
if (!motionDisabled(config))
|
|
802
|
-
hideElement(el, config);
|
|
803
|
-
const record = { element: el, options: opts, animated: false };
|
|
804
|
-
registry.set(el, record);
|
|
805
|
-
attach(el, record, true);
|
|
806
|
-
}
|
|
807
|
-
const instance = {
|
|
808
|
-
observe(target, options = {}) {
|
|
809
|
-
pruneDetached();
|
|
810
|
-
const opts = mergeOptions(options, config);
|
|
811
|
-
resolveTargets(target).forEach((el) => observeElement(el, opts));
|
|
812
|
-
},
|
|
813
|
-
unobserve(target) {
|
|
814
|
-
resolveTargets(target).forEach((el) => {
|
|
815
|
-
finished.delete(el);
|
|
816
|
-
teardown(el, true);
|
|
817
|
-
});
|
|
818
|
-
},
|
|
819
|
-
init(rootElement) {
|
|
820
|
-
const scope = rootElement !== null && rootElement !== void 0 ? rootElement : (hasDOM() ? document : null);
|
|
821
|
-
if (!scope)
|
|
822
|
-
return;
|
|
823
|
-
pruneDetached();
|
|
824
|
-
scope.querySelectorAll('[data-sa]').forEach((el) => {
|
|
825
|
-
if (!registry.has(el))
|
|
826
|
-
observeElement(el, parseDataAttributes(el, config));
|
|
827
|
-
});
|
|
828
|
-
},
|
|
829
|
-
destroy() {
|
|
830
|
-
registry.forEach((record, el) => {
|
|
831
|
-
if (!record.animated)
|
|
832
|
-
reveal(el, config);
|
|
833
|
-
});
|
|
834
|
-
pools.forEach((pool) => pool.forEach((io) => io.disconnect()));
|
|
835
|
-
pools.clear();
|
|
836
|
-
registry.clear();
|
|
837
|
-
scrolling.clear();
|
|
838
|
-
listen(false);
|
|
839
|
-
finished = new WeakSet();
|
|
840
|
-
},
|
|
841
|
-
refresh() {
|
|
842
|
-
// Rebuild observers (e.g. after configure({ root })) without re-hiding or
|
|
843
|
-
// replaying elements that have already animated.
|
|
844
|
-
pools.forEach((pool) => pool.forEach((io) => io.disconnect()));
|
|
845
|
-
pools.clear();
|
|
846
|
-
scrolling.clear();
|
|
847
|
-
listen(false);
|
|
848
|
-
pruneDetached();
|
|
849
|
-
if (!supportsObserver())
|
|
850
|
-
return;
|
|
851
|
-
registry.forEach((record, el) => {
|
|
852
|
-
const done = record.animated && record.options.once && !record.options.repeat;
|
|
853
|
-
attach(el, record, !done);
|
|
854
|
-
});
|
|
855
|
-
},
|
|
856
|
-
animate(target, options = {}) {
|
|
857
|
-
const opts = mergeOptions(options, config);
|
|
858
|
-
resolveTargets(target).forEach((el) => runAnimation(el, opts, config, 0));
|
|
859
|
-
},
|
|
860
|
-
getObservedElements() {
|
|
861
|
-
return Array.from(registry.values());
|
|
862
|
-
},
|
|
863
|
-
configure(newConfig) {
|
|
864
|
-
config = { ...config, ...newConfig };
|
|
865
|
-
},
|
|
866
|
-
};
|
|
867
|
-
return instance;
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
/**
|
|
871
|
-
* use-scroll-animate - Staggered children
|
|
872
|
-
* Reveal a container's children one after another when the container scrolls
|
|
873
|
-
* into view, optionally also animating children that are added later.
|
|
874
|
-
*/
|
|
875
|
-
let fallback$1 = null;
|
|
876
|
-
/**
|
|
877
|
-
* Animate the children of `container` with a stagger once it enters the
|
|
878
|
-
* viewport. Returns a cleanup function. SSR-safe (no-op without a DOM).
|
|
879
|
-
*
|
|
880
|
-
* @example
|
|
881
|
-
* const stop = staggerChildren(document.querySelector('ul'), { stagger: 60, observeChildren: true });
|
|
882
|
-
*/
|
|
883
|
-
function staggerChildren(container, options = {}, instance) {
|
|
884
|
-
if (!container || !hasDOM() || !supportsObserver())
|
|
885
|
-
return () => undefined; // leave content visible
|
|
886
|
-
const sa = instance || fallback$1 || (fallback$1 = createScrollAnimate());
|
|
887
|
-
const { stagger = 80, delay = 0, threshold = 0.1, rootMargin = '0px', observeChildren = false, ...rest } = options;
|
|
888
|
-
let items = Array.from(container.children);
|
|
889
|
-
let revealed = false;
|
|
890
|
-
const late = [];
|
|
891
|
-
items.forEach((child) => prepareElement(child));
|
|
892
|
-
const io = new IntersectionObserver((entries) => {
|
|
893
|
-
if (revealed || !entries.some((entry) => entry.isIntersecting))
|
|
894
|
-
return;
|
|
895
|
-
revealed = true;
|
|
896
|
-
io.disconnect();
|
|
897
|
-
items.forEach((child, i) => {
|
|
898
|
-
if (child.parentNode === container)
|
|
899
|
-
sa.animate(child, { ...rest, delay: delay + i * stagger });
|
|
900
|
-
});
|
|
901
|
-
items = [];
|
|
902
|
-
}, { threshold, rootMargin });
|
|
903
|
-
io.observe(container);
|
|
904
|
-
let mo;
|
|
905
|
-
if (observeChildren && typeof MutationObserver !== 'undefined') {
|
|
906
|
-
mo = new MutationObserver((records) => {
|
|
907
|
-
records.forEach((record) => {
|
|
908
|
-
record.addedNodes.forEach((node) => {
|
|
909
|
-
if (!(node instanceof Element) || node.parentNode !== container)
|
|
910
|
-
return;
|
|
911
|
-
if (!revealed) {
|
|
912
|
-
prepareElement(node);
|
|
913
|
-
items.push(node);
|
|
914
|
-
}
|
|
915
|
-
else {
|
|
916
|
-
// The core engine staggers siblings relative to the batch that
|
|
917
|
-
// enters the viewport together.
|
|
918
|
-
late.push(node);
|
|
919
|
-
sa.observe(node, { ...rest, delay, stagger, threshold, rootMargin });
|
|
920
|
-
}
|
|
921
|
-
});
|
|
922
|
-
record.removedNodes.forEach((node) => {
|
|
923
|
-
if (!(node instanceof Element))
|
|
924
|
-
return;
|
|
925
|
-
items = items.filter((el) => el !== node);
|
|
926
|
-
const i = late.indexOf(node);
|
|
927
|
-
if (i >= 0) {
|
|
928
|
-
late.splice(i, 1);
|
|
929
|
-
sa.unobserve(node);
|
|
930
|
-
}
|
|
931
|
-
});
|
|
932
|
-
});
|
|
933
|
-
});
|
|
934
|
-
mo.observe(container, { childList: true });
|
|
935
|
-
}
|
|
936
|
-
return () => {
|
|
937
|
-
io.disconnect();
|
|
938
|
-
mo === null || mo === void 0 ? void 0 : mo.disconnect();
|
|
939
|
-
late.forEach((el) => sa.unobserve(el));
|
|
940
|
-
late.length = 0;
|
|
941
|
-
};
|
|
942
|
-
}
|
|
1
|
+
import { h as hasDOM, s as supportsObserver, r as resolveTargets, p as prepareElement, a as stopAnimation, c as createScrollAnimate, g as getScrollProgress, b as prefersReducedMotion } from './chunks/core-FUEi4ncH.js';
|
|
2
|
+
export { E as EASING_MAP, P as PRESETS, d as resolveEasing, e as resolvePreset, f as supportsScrollTimeline } from './chunks/core-FUEi4ncH.js';
|
|
3
|
+
export { s as staggerChildren } from './chunks/stagger-DabrnrcE.js';
|
|
943
4
|
|
|
944
5
|
/**
|
|
945
6
|
* use-scroll-animate - Sequence / timeline helper
|
|
@@ -950,15 +11,13 @@ function plan(steps, defaults) {
|
|
|
950
11
|
const out = [];
|
|
951
12
|
let cursor = 0;
|
|
952
13
|
steps.forEach((step) => {
|
|
953
|
-
var _a, _b;
|
|
954
14
|
const { target, gap = 0, at, ...stepOpts } = step;
|
|
955
15
|
const opts = { ...defaults, ...stepOpts };
|
|
956
|
-
const duration =
|
|
957
|
-
const start = Math.max(0, at
|
|
16
|
+
const duration = opts.duration ?? 600;
|
|
17
|
+
const start = Math.max(0, at ?? cursor + gap) + (opts.delay ?? 0);
|
|
958
18
|
let end = Math.max(cursor, start);
|
|
959
19
|
resolveTargets(target).forEach((el, i) => {
|
|
960
|
-
|
|
961
|
-
const delay = start + i * ((_a = opts.stagger) !== null && _a !== void 0 ? _a : 0);
|
|
20
|
+
const delay = start + i * (opts.stagger ?? 0);
|
|
962
21
|
out.push({ el, opts: { ...opts, duration, delay, stagger: 0 }, end: delay + duration });
|
|
963
22
|
end = Math.max(end, delay + duration);
|
|
964
23
|
});
|
|
@@ -977,12 +36,13 @@ function plan(steps, defaults) {
|
|
|
977
36
|
* ], { trigger: '.hero' });
|
|
978
37
|
*/
|
|
979
38
|
function sequence(steps, options = {}) {
|
|
980
|
-
var _a, _b;
|
|
981
39
|
const { trigger, instance, ...defaults } = options;
|
|
982
40
|
const sa = () => instance || fallback || (fallback = createScrollAnimate());
|
|
983
41
|
let io;
|
|
984
42
|
let active = [];
|
|
985
43
|
let settle;
|
|
44
|
+
// Targets hidden while waiting for `trigger`; revealed if cancelled before it fires.
|
|
45
|
+
let prepared = [];
|
|
986
46
|
const controller = {
|
|
987
47
|
play() {
|
|
988
48
|
controller.cancel();
|
|
@@ -1003,20 +63,22 @@ function sequence(steps, options = {}) {
|
|
|
1003
63
|
sa().animate(el, {
|
|
1004
64
|
...opts,
|
|
1005
65
|
onComplete: (node) => {
|
|
1006
|
-
done
|
|
66
|
+
done?.(node);
|
|
1007
67
|
if (run === active && --left === 0)
|
|
1008
|
-
settle
|
|
68
|
+
settle?.();
|
|
1009
69
|
},
|
|
1010
70
|
});
|
|
1011
71
|
});
|
|
1012
72
|
});
|
|
1013
73
|
},
|
|
1014
74
|
cancel() {
|
|
1015
|
-
io
|
|
75
|
+
io?.disconnect();
|
|
1016
76
|
io = undefined;
|
|
77
|
+
prepared.forEach((el) => stopAnimation(el));
|
|
78
|
+
prepared = [];
|
|
1017
79
|
active.forEach(({ el }) => stopAnimation(el));
|
|
1018
80
|
active = [];
|
|
1019
|
-
settle
|
|
81
|
+
settle?.();
|
|
1020
82
|
},
|
|
1021
83
|
duration() {
|
|
1022
84
|
return plan(steps, defaults).reduce((max, p) => Math.max(max, p.end), 0);
|
|
@@ -1025,14 +87,16 @@ function sequence(steps, options = {}) {
|
|
|
1025
87
|
if (trigger && hasDOM() && supportsObserver()) {
|
|
1026
88
|
const el = resolveTargets(trigger)[0];
|
|
1027
89
|
if (el) {
|
|
1028
|
-
plan(steps, defaults).
|
|
90
|
+
prepared = plan(steps, defaults).map(({ el: target }) => target);
|
|
91
|
+
prepared.forEach((target) => prepareElement(target));
|
|
1029
92
|
io = new IntersectionObserver((entries) => {
|
|
1030
93
|
if (!entries.some((e) => e.isIntersecting))
|
|
1031
94
|
return;
|
|
1032
|
-
io
|
|
95
|
+
io?.disconnect();
|
|
1033
96
|
io = undefined;
|
|
97
|
+
prepared = []; // play() takes over from here
|
|
1034
98
|
controller.play();
|
|
1035
|
-
}, { threshold:
|
|
99
|
+
}, { threshold: defaults.threshold ?? 0.1, rootMargin: defaults.rootMargin ?? '0px' });
|
|
1036
100
|
io.observe(el);
|
|
1037
101
|
}
|
|
1038
102
|
}
|
|
@@ -1040,116 +104,95 @@ function sequence(steps, options = {}) {
|
|
|
1040
104
|
}
|
|
1041
105
|
|
|
1042
106
|
/**
|
|
1043
|
-
* use-scroll-animate -
|
|
1044
|
-
* Provides useScrollAnimate and useScrollStagger hooks for React applications.
|
|
1045
|
-
* `useScrollStagger({ observeChildren: true })` also animates children added later.
|
|
107
|
+
* use-scroll-animate - parallax() helper
|
|
1046
108
|
*
|
|
1047
|
-
*
|
|
1048
|
-
*
|
|
1049
|
-
*
|
|
109
|
+
* Moves elements at a different speed than the page while they cross the
|
|
110
|
+
* viewport. Built on the same scroll progress as `progressVar` (0 when the
|
|
111
|
+
* element's top enters at the bottom, 1 when its bottom leaves at the top):
|
|
112
|
+
* the progress is written to a CSS custom property (default `--sa-parallax`)
|
|
113
|
+
* and the offset is applied with the individual `translate` property, so it
|
|
114
|
+
* composes with entrance animations and other `transform`s.
|
|
1050
115
|
*/
|
|
1051
|
-
const
|
|
116
|
+
const PASSIVE = { passive: true };
|
|
1052
117
|
/**
|
|
1053
|
-
*
|
|
1054
|
-
*
|
|
1055
|
-
*
|
|
1056
|
-
*
|
|
118
|
+
* Apply a scroll parallax to `target` (selector, Element, NodeList or array).
|
|
119
|
+
* Returns a function that stops it and removes the inline styles it set.
|
|
120
|
+
* SSR-safe (no-op without a DOM / IntersectionObserver).
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* const stop = parallax('.hero-bg', { speed: 0.3 });
|
|
124
|
+
* parallax('.badge', { speed: -0.15, axis: 'x' });
|
|
1057
125
|
*/
|
|
1058
|
-
function
|
|
1059
|
-
const
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
126
|
+
function parallax(target, options = {}) {
|
|
127
|
+
const els = resolveTargets(target);
|
|
128
|
+
if (!els.length || !hasDOM() || !supportsObserver())
|
|
129
|
+
return () => undefined;
|
|
130
|
+
const { speed = 0.2, axis = 'y', root = null, respectReducedMotion = true } = options;
|
|
131
|
+
const name = options.progressVar ? (options.progressVar.startsWith('--') ? options.progressVar : `--${options.progressVar}`) : '--sa-parallax';
|
|
132
|
+
const unit = axis === 'x' ? 'vw' : 'vh';
|
|
133
|
+
const visible = new Set();
|
|
134
|
+
let frame = 0;
|
|
135
|
+
let listening = false;
|
|
136
|
+
const scroller = root || window;
|
|
137
|
+
const apply = (el) => {
|
|
138
|
+
const style = el.style;
|
|
139
|
+
if (!style)
|
|
140
|
+
return;
|
|
141
|
+
const p = getScrollProgress(el, root);
|
|
142
|
+
style.setProperty(name, String(+p.toFixed(4)));
|
|
143
|
+
if (respectReducedMotion && prefersReducedMotion()) {
|
|
144
|
+
style.removeProperty('translate');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const offset = `${+((p - 0.5) * speed * 100).toFixed(3)}${unit}`;
|
|
148
|
+
style.setProperty('translate', axis === 'x' ? `${offset} 0px` : `0px ${offset}`);
|
|
149
|
+
};
|
|
150
|
+
const update = () => {
|
|
151
|
+
frame = 0;
|
|
152
|
+
visible.forEach(apply);
|
|
153
|
+
};
|
|
154
|
+
const schedule = () => {
|
|
155
|
+
if (!frame)
|
|
156
|
+
frame = requestAnimationFrame(update);
|
|
157
|
+
};
|
|
158
|
+
const listen = (on) => {
|
|
159
|
+
if (on === listening)
|
|
160
|
+
return;
|
|
161
|
+
listening = on;
|
|
162
|
+
const method = on ? 'addEventListener' : 'removeEventListener';
|
|
163
|
+
scroller[method]('scroll', schedule, PASSIVE);
|
|
164
|
+
window[method]('resize', schedule, PASSIVE);
|
|
165
|
+
if (!on && frame) {
|
|
166
|
+
cancelAnimationFrame(frame);
|
|
167
|
+
frame = 0;
|
|
1064
168
|
}
|
|
169
|
+
};
|
|
170
|
+
const io = new IntersectionObserver((entries) => {
|
|
171
|
+
entries.forEach((entry) => {
|
|
172
|
+
if (entry.isIntersecting)
|
|
173
|
+
visible.add(entry.target);
|
|
174
|
+
else
|
|
175
|
+
visible.delete(entry.target);
|
|
176
|
+
apply(entry.target); // report the edges even on fast scrolls
|
|
177
|
+
});
|
|
178
|
+
listen(visible.size > 0);
|
|
179
|
+
}, { threshold: 0, root });
|
|
180
|
+
els.forEach((el) => {
|
|
181
|
+
apply(el); // no jump before the first observer callback
|
|
182
|
+
io.observe(el);
|
|
1065
183
|
});
|
|
1066
|
-
return
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
const ref = React.useRef(null);
|
|
1074
|
-
const optionsRef = React.useRef(options);
|
|
1075
|
-
optionsRef.current = options;
|
|
1076
|
-
React.useEffect(() => {
|
|
1077
|
-
const el = ref.current;
|
|
1078
|
-
if (!el)
|
|
1079
|
-
return;
|
|
1080
|
-
const sa = getInstance();
|
|
1081
|
-
sa.observe(el, withLatestCallbacks(optionsRef));
|
|
1082
|
-
return () => sa.unobserve(el);
|
|
1083
|
-
}, []);
|
|
1084
|
-
return ref;
|
|
1085
|
-
}
|
|
1086
|
-
function useScrollStagger(options = {}) {
|
|
1087
|
-
const ref = React.useRef(null);
|
|
1088
|
-
const optionsRef = React.useRef(options);
|
|
1089
|
-
optionsRef.current = options;
|
|
1090
|
-
React.useEffect(() => {
|
|
1091
|
-
const container = ref.current;
|
|
1092
|
-
if (!container)
|
|
1093
|
-
return;
|
|
1094
|
-
return staggerChildren(container, withLatestCallbacks(optionsRef), getInstance());
|
|
1095
|
-
}, []);
|
|
1096
|
-
return ref;
|
|
1097
|
-
}
|
|
1098
|
-
return { useScrollAnimate, useScrollStagger };
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
/**
|
|
1102
|
-
* use-scroll-animate - Vue 3 Integration
|
|
1103
|
-
* Provides useScrollAnimate and useScrollStagger composables for Vue 3 applications.
|
|
1104
|
-
*
|
|
1105
|
-
* A thin wrapper around the core engine, so it shares its behaviour: `once`,
|
|
1106
|
-
* `offset`, custom easing functions, parallax, `prefers-reduced-motion`
|
|
1107
|
-
* support, and cleanup on unmount.
|
|
1108
|
-
*/
|
|
1109
|
-
/** Support refs on components (`$el`) as well as plain elements. */
|
|
1110
|
-
function unwrap(value) {
|
|
1111
|
-
if (value && typeof Element !== 'undefined' && !(value instanceof Element) && value.$el instanceof Element) {
|
|
1112
|
-
return value.$el;
|
|
1113
|
-
}
|
|
1114
|
-
return value || null;
|
|
1115
|
-
}
|
|
1116
|
-
function createVueComposables(Vue) {
|
|
1117
|
-
// Created lazily on the client so importing on the server is side-effect free.
|
|
1118
|
-
let instance = null;
|
|
1119
|
-
const getInstance = () => instance || (instance = createScrollAnimate());
|
|
1120
|
-
function useScrollAnimate(options = {}) {
|
|
1121
|
-
const animateRef = Vue.ref(null);
|
|
1122
|
-
let el = null;
|
|
1123
|
-
Vue.onMounted(() => {
|
|
1124
|
-
const target = unwrap(animateRef.value);
|
|
1125
|
-
if (!target)
|
|
184
|
+
return () => {
|
|
185
|
+
io.disconnect();
|
|
186
|
+
listen(false);
|
|
187
|
+
visible.clear();
|
|
188
|
+
els.forEach((el) => {
|
|
189
|
+
const style = el.style;
|
|
190
|
+
if (!style)
|
|
1126
191
|
return;
|
|
1127
|
-
|
|
1128
|
-
|
|
192
|
+
style.removeProperty('translate');
|
|
193
|
+
style.removeProperty(name);
|
|
1129
194
|
});
|
|
1130
|
-
|
|
1131
|
-
if (el)
|
|
1132
|
-
getInstance().unobserve(el);
|
|
1133
|
-
el = null;
|
|
1134
|
-
});
|
|
1135
|
-
return { animateRef };
|
|
1136
|
-
}
|
|
1137
|
-
/** Stagger the children of `staggerRef`; `observeChildren: true` also animates children added later. */
|
|
1138
|
-
function useScrollStagger(options = {}) {
|
|
1139
|
-
const staggerRef = Vue.ref(null);
|
|
1140
|
-
let stop;
|
|
1141
|
-
Vue.onMounted(() => {
|
|
1142
|
-
const target = unwrap(staggerRef.value);
|
|
1143
|
-
if (target)
|
|
1144
|
-
stop = staggerChildren(target, options, getInstance());
|
|
1145
|
-
});
|
|
1146
|
-
Vue.onUnmounted(() => {
|
|
1147
|
-
stop === null || stop === void 0 ? void 0 : stop();
|
|
1148
|
-
stop = undefined;
|
|
1149
|
-
});
|
|
1150
|
-
return { staggerRef };
|
|
1151
|
-
}
|
|
1152
|
-
return { useScrollAnimate, useScrollStagger };
|
|
195
|
+
};
|
|
1153
196
|
}
|
|
1154
197
|
|
|
1155
198
|
/**
|
|
@@ -1157,7 +200,9 @@ function createVueComposables(Vue) {
|
|
|
1157
200
|
*
|
|
1158
201
|
* A lightweight, dependency-free scroll animation library for modern web
|
|
1159
202
|
* applications. Built with TypeScript, powered by IntersectionObserver and
|
|
1160
|
-
* the Web Animations API
|
|
203
|
+
* the Web Animations API (or the native scroll-driven timeline). Safe to
|
|
204
|
+
* import during SSR. Framework integrations live in the subpath entries:
|
|
205
|
+
* `use-scroll-animate/react`, `/vue`, `/svelte`, `/solid`, `/element`.
|
|
1161
206
|
*
|
|
1162
207
|
* @license MIT
|
|
1163
208
|
* @see https://github.com/HarrisonCN/use-scroll-animate
|
|
@@ -1177,17 +222,7 @@ function createVueComposables(Vue) {
|
|
|
1177
222
|
* ScrollAnimate.observe('.my-element', { animation: 'fade-in-up' });
|
|
1178
223
|
* ```
|
|
1179
224
|
*/
|
|
1180
|
-
const ScrollAnimate = createScrollAnimate();
|
|
225
|
+
const ScrollAnimate = /* @__PURE__ */ createScrollAnimate();
|
|
1181
226
|
|
|
1182
|
-
|
|
1183
|
-
exports.PRESETS = PRESETS;
|
|
1184
|
-
exports.createReactHooks = createReactHooks;
|
|
1185
|
-
exports.createScrollAnimate = createScrollAnimate;
|
|
1186
|
-
exports.createVueComposables = createVueComposables;
|
|
1187
|
-
exports.default = ScrollAnimate;
|
|
1188
|
-
exports.getScrollProgress = getScrollProgress;
|
|
1189
|
-
exports.resolveEasing = resolveEasing;
|
|
1190
|
-
exports.resolvePreset = resolvePreset;
|
|
1191
|
-
exports.sequence = sequence;
|
|
1192
|
-
exports.staggerChildren = staggerChildren;
|
|
227
|
+
export { createScrollAnimate, ScrollAnimate as default, getScrollProgress, parallax, sequence };
|
|
1193
228
|
//# sourceMappingURL=index.js.map
|