use-scroll-animate 3.8.0 → 4.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 +47 -0
- package/README.md +17 -14
- package/README_ja.md +11 -11
- package/README_zh.md +12 -12
- package/dist/chunks/{base-BpROOcey.js → base-ZARFccur.js} +2 -2
- package/dist/chunks/{base-BpROOcey.js.map → base-ZARFccur.js.map} +1 -1
- package/dist/chunks/core-Co-6AL0h.js +218 -0
- package/dist/chunks/core-Co-6AL0h.js.map +1 -0
- package/dist/chunks/{core-uxs3ETou.js → core-DKY-fVzR.js} +2 -2
- package/dist/chunks/{core-uxs3ETou.js.map → core-DKY-fVzR.js.map} +1 -1
- package/dist/chunks/core-DXqZm5Il.cjs +222 -0
- package/dist/chunks/core-DXqZm5Il.cjs.map +1 -0
- package/dist/chunks/{index-tags-BANJ-e4H.js → index-tags-43Xtd01A.js} +3 -2
- package/dist/chunks/index-tags-43Xtd01A.js.map +1 -0
- package/dist/chunks/{index-tags-wbuPiMR6.cjs → index-tags-BQh_uGqH.cjs} +3 -2
- package/dist/chunks/index-tags-BQh_uGqH.cjs.map +1 -0
- package/dist/chunks/{spring-C-fw7_9f.js → spring-E2ickYNI.js} +2 -2
- package/dist/chunks/{spring-C-fw7_9f.js.map → spring-E2ickYNI.js.map} +1 -1
- package/dist/chunks/{variants-CHe1VbSn.js → variants-DvnxvRCM.js} +2 -2
- package/dist/chunks/{variants-CHe1VbSn.js.map → variants-DvnxvRCM.js.map} +1 -1
- package/dist/components/angular.cjs +3 -1
- package/dist/components/angular.cjs.map +1 -1
- package/dist/components/angular.d.cts +29 -17
- package/dist/components/angular.d.ts +29 -17
- package/dist/components/angular.js +7 -5
- package/dist/components/angular.js.map +1 -1
- package/dist/components/background.js +3 -3
- package/dist/components/cards.js +3 -3
- package/dist/components/click.js +3 -3
- package/dist/components/depth.js +4 -4
- package/dist/components/feedback.js +2 -2
- package/dist/components/gesture.js +5 -5
- package/dist/components/interaction.js +2 -2
- package/dist/components/jsx.d.cts +2 -1
- package/dist/components/jsx.d.ts +2 -1
- package/dist/components/layout.js +2 -2
- package/dist/components/lazy.cjs +2 -1
- package/dist/components/lazy.cjs.map +1 -1
- package/dist/components/lazy.d.cts +2 -1
- package/dist/components/lazy.d.ts +2 -1
- package/dist/components/lazy.js +2 -1
- package/dist/components/lazy.js.map +1 -1
- package/dist/components/packs.cjs +194 -0
- package/dist/components/packs.cjs.map +1 -0
- package/dist/components/packs.css +3 -0
- package/dist/components/packs.d.cts +107 -0
- package/dist/components/packs.d.ts +107 -0
- package/dist/components/packs.js +185 -0
- package/dist/components/packs.js.map +1 -0
- package/dist/components/page.js +3 -3
- package/dist/components/physics.js +4 -4
- package/dist/components/react.cjs +2 -2
- package/dist/components/react.cjs.map +1 -1
- package/dist/components/react.d.cts +1 -1
- package/dist/components/react.d.ts +1 -1
- package/dist/components/react.js +2 -2
- package/dist/components/react.js.map +1 -1
- package/dist/components/reveal.js +2 -2
- package/dist/components/solid.cjs +3 -1
- package/dist/components/solid.cjs.map +1 -1
- package/dist/components/solid.d.cts +29 -17
- package/dist/components/solid.d.ts +29 -17
- package/dist/components/solid.js +7 -5
- package/dist/components/solid.js.map +1 -1
- package/dist/components/svelte.cjs +3 -1
- package/dist/components/svelte.cjs.map +1 -1
- package/dist/components/svelte.d.cts +29 -17
- package/dist/components/svelte.d.ts +29 -17
- package/dist/components/svelte.js +7 -5
- package/dist/components/svelte.js.map +1 -1
- package/dist/components/svg.js +2 -2
- package/dist/components/text.js +2 -2
- package/dist/components/timeline.cjs +6 -219
- package/dist/components/timeline.cjs.map +1 -1
- package/dist/components/timeline.js +5 -217
- package/dist/components/timeline.js.map +1 -1
- package/dist/components/transitions.cjs +7 -120
- package/dist/components/transitions.cjs.map +1 -1
- package/dist/components/transitions.css +0 -1
- package/dist/components/transitions.d.cts +5 -32
- package/dist/components/transitions.d.ts +5 -32
- package/dist/components/transitions.js +10 -121
- package/dist/components/transitions.js.map +1 -1
- package/dist/components/ui.js +5 -5
- package/dist/components/vue.cjs +3 -1
- package/dist/components/vue.cjs.map +1 -1
- package/dist/components/vue.d.cts +29 -17
- package/dist/components/vue.d.ts +29 -17
- package/dist/components/vue.js +7 -5
- package/dist/components/vue.js.map +1 -1
- package/dist/components/webgl.js +2 -2
- package/dist/components.cjs +18 -10
- package/dist/components.cjs.map +1 -1
- package/dist/components.css +1 -1
- package/dist/components.d.cts +67 -33
- package/dist/components.d.ts +67 -33
- package/dist/components.js +14 -10
- package/dist/components.js.map +1 -1
- package/dist/components.umd.js +2 -2
- package/dist/components.umd.js.map +1 -1
- package/dist/index.cjs +5 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +72 -30
- package/dist/index.d.ts +72 -30
- package/dist/index.js +4 -103
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/docs/API.md +6 -6
- package/docs/ROADMAP.md +14 -0
- package/docs/components.md +16 -4
- package/docs/migration-from-aos.md +1 -1
- package/docs/migration-from-gsap-scrolltrigger.md +6 -6
- package/docs/upgrading-4.md +65 -0
- package/package.json +13 -2
- package/dist/chunks/index-tags-BANJ-e4H.js.map +0 -1
- package/dist/chunks/index-tags-wbuPiMR6.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -4,107 +4,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var core = require('./chunks/core-qpECfEkb.cjs');
|
|
6
6
|
var stagger = require('./chunks/stagger-CLc3j58T.cjs');
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* use-scroll-animate - Sequence / timeline helper
|
|
10
|
-
* Chain animations on several targets, one after another (or overlapping).
|
|
11
|
-
*/
|
|
12
|
-
let fallback = null;
|
|
13
|
-
function plan(steps, defaults) {
|
|
14
|
-
const out = [];
|
|
15
|
-
let cursor = 0;
|
|
16
|
-
steps.forEach((step) => {
|
|
17
|
-
const { target, gap = 0, at, ...stepOpts } = step;
|
|
18
|
-
const opts = { ...defaults, ...stepOpts };
|
|
19
|
-
const duration = opts.duration ?? 600;
|
|
20
|
-
const start = Math.max(0, at ?? cursor + gap) + (opts.delay ?? 0);
|
|
21
|
-
let end = Math.max(cursor, start);
|
|
22
|
-
core.resolveTargets(target).forEach((el, i) => {
|
|
23
|
-
const delay = start + i * (opts.stagger ?? 0);
|
|
24
|
-
out.push({ el, opts: { ...opts, duration, delay, stagger: 0 }, end: delay + duration });
|
|
25
|
-
end = Math.max(end, delay + duration);
|
|
26
|
-
});
|
|
27
|
-
cursor = end;
|
|
28
|
-
});
|
|
29
|
-
return out;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Build a timeline of animations.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* sequence([
|
|
36
|
-
* { target: '.title', animation: 'fade-in-up' },
|
|
37
|
-
* { target: '.subtitle', animation: 'blur-in', gap: -300 }, // overlap by 300ms
|
|
38
|
-
* { target: '.card', animation: 'scale-up', stagger: 80 },
|
|
39
|
-
* ], { trigger: '.hero' });
|
|
40
|
-
*/
|
|
41
|
-
function sequence(steps, options = {}) {
|
|
42
|
-
const { trigger, instance, ...defaults } = options;
|
|
43
|
-
const sa = () => instance || fallback || (fallback = core.createScrollAnimate());
|
|
44
|
-
let io;
|
|
45
|
-
let active = [];
|
|
46
|
-
let settle;
|
|
47
|
-
// Targets hidden while waiting for `trigger`; revealed if cancelled before it fires.
|
|
48
|
-
let prepared = [];
|
|
49
|
-
const controller = {
|
|
50
|
-
play() {
|
|
51
|
-
controller.cancel();
|
|
52
|
-
if (!core.hasDOM())
|
|
53
|
-
return Promise.resolve();
|
|
54
|
-
active = plan(steps, defaults);
|
|
55
|
-
return new Promise((resolve) => {
|
|
56
|
-
let left = active.length;
|
|
57
|
-
settle = () => {
|
|
58
|
-
settle = undefined;
|
|
59
|
-
resolve();
|
|
60
|
-
};
|
|
61
|
-
if (!left)
|
|
62
|
-
return settle();
|
|
63
|
-
const run = active;
|
|
64
|
-
run.forEach(({ el, opts }) => {
|
|
65
|
-
const done = opts.onComplete;
|
|
66
|
-
sa().animate(el, {
|
|
67
|
-
...opts,
|
|
68
|
-
onComplete: (node) => {
|
|
69
|
-
done?.(node);
|
|
70
|
-
if (run === active && --left === 0)
|
|
71
|
-
settle?.();
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
},
|
|
77
|
-
cancel() {
|
|
78
|
-
io?.disconnect();
|
|
79
|
-
io = undefined;
|
|
80
|
-
prepared.forEach((el) => core.stopAnimation(el));
|
|
81
|
-
prepared = [];
|
|
82
|
-
active.forEach(({ el }) => core.stopAnimation(el));
|
|
83
|
-
active = [];
|
|
84
|
-
settle?.();
|
|
85
|
-
},
|
|
86
|
-
duration() {
|
|
87
|
-
return plan(steps, defaults).reduce((max, p) => Math.max(max, p.end), 0);
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
if (trigger && core.hasDOM() && core.supportsObserver()) {
|
|
91
|
-
const el = core.resolveTargets(trigger)[0];
|
|
92
|
-
if (el) {
|
|
93
|
-
prepared = plan(steps, defaults).map(({ el: target }) => target);
|
|
94
|
-
prepared.forEach((target) => core.prepareElement(target));
|
|
95
|
-
io = new IntersectionObserver((entries) => {
|
|
96
|
-
if (!entries.some((e) => e.isIntersecting))
|
|
97
|
-
return;
|
|
98
|
-
io?.disconnect();
|
|
99
|
-
io = undefined;
|
|
100
|
-
prepared = []; // play() takes over from here
|
|
101
|
-
controller.play();
|
|
102
|
-
}, { threshold: defaults.threshold ?? 0.1, rootMargin: defaults.rootMargin ?? '0px' });
|
|
103
|
-
io.observe(el);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return controller;
|
|
107
|
-
}
|
|
7
|
+
var core$1 = require('./chunks/core-DXqZm5Il.cjs');
|
|
8
|
+
require('./chunks/base-CXx7jZ-o.cjs');
|
|
108
9
|
|
|
109
10
|
/**
|
|
110
11
|
* use-scroll-animate - parallax() helper
|
|
@@ -235,7 +136,9 @@ exports.resolveEasing = core.resolveEasing;
|
|
|
235
136
|
exports.resolvePreset = core.resolvePreset;
|
|
236
137
|
exports.supportsScrollTimeline = core.supportsScrollTimeline;
|
|
237
138
|
exports.staggerChildren = stagger.staggerChildren;
|
|
139
|
+
exports.TIMELINE_PRESETS = core$1.TIMELINE_PRESETS;
|
|
140
|
+
exports.resolvePosition = core$1.resolvePosition;
|
|
141
|
+
exports.timeline = core$1.timeline;
|
|
238
142
|
exports.default = ScrollAnimate;
|
|
239
143
|
exports.parallax = parallax;
|
|
240
|
-
exports.sequence = sequence;
|
|
241
144
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/sequence.ts","../src/parallax.ts","../src/index.ts"],"sourcesContent":["/**\n * use-scroll-animate - Sequence / timeline helper\n * Chain animations on several targets, one after another (or overlapping).\n */\n\nimport type { AnimateOptions, ScrollAnimateInstance } from './types';\nimport { createScrollAnimate, hasDOM, prepareElement, resolveTargets, stopAnimation, supportsObserver } from './core';\n\nexport interface SequenceStep extends AnimateOptions {\n /** Selector, Element, NodeList or Element[] to animate in this step */\n target: string | Element | NodeList | Element[];\n /** Pause (ms) after the previous step ends before this one starts. Negative values overlap. (default: 0) */\n gap?: number;\n /** Absolute start time (ms) on the timeline; overrides `gap` */\n at?: number;\n}\n\nexport interface SequenceOptions extends AnimateOptions {\n /** Play automatically (once) when this element/selector enters the viewport */\n trigger?: string | Element;\n /** Instance whose global config (easing, classes, `disabled`) is used */\n instance?: ScrollAnimateInstance;\n}\n\nexport interface SequenceController {\n /** Play (or replay) the timeline. Resolves when every step has completed, or on `cancel()`. */\n play(): Promise<void>;\n /** Stop the trigger and running animations; elements are left visible. */\n cancel(): void;\n /** Total duration of the timeline in ms (computed for the current DOM). */\n duration(): number;\n}\n\nlet fallback: ScrollAnimateInstance | null = null;\n\ntype Planned = { el: Element; opts: AnimateOptions; end: number };\n\nfunction plan(steps: SequenceStep[], defaults: AnimateOptions): Planned[] {\n const out: Planned[] = [];\n let cursor = 0;\n steps.forEach((step) => {\n const { target, gap = 0, at, ...stepOpts } = step;\n const opts = { ...defaults, ...stepOpts };\n const duration = opts.duration ?? 600;\n const start = Math.max(0, at ?? cursor + gap) + (opts.delay ?? 0);\n let end = Math.max(cursor, start);\n resolveTargets(target).forEach((el, i) => {\n const delay = start + i * (opts.stagger ?? 0);\n out.push({ el, opts: { ...opts, duration, delay, stagger: 0 }, end: delay + duration });\n end = Math.max(end, delay + duration);\n });\n cursor = end;\n });\n return out;\n}\n\n/**\n * Build a timeline of animations.\n *\n * @example\n * sequence([\n * { target: '.title', animation: 'fade-in-up' },\n * { target: '.subtitle', animation: 'blur-in', gap: -300 }, // overlap by 300ms\n * { target: '.card', animation: 'scale-up', stagger: 80 },\n * ], { trigger: '.hero' });\n */\nexport function sequence(steps: SequenceStep[], options: SequenceOptions = {}): SequenceController {\n const { trigger, instance, ...defaults } = options;\n const sa = () => instance || fallback || (fallback = createScrollAnimate());\n let io: IntersectionObserver | undefined;\n let active: Planned[] = [];\n let settle: (() => void) | undefined;\n // Targets hidden while waiting for `trigger`; revealed if cancelled before it fires.\n let prepared: Element[] = [];\n\n const controller: SequenceController = {\n play() {\n controller.cancel();\n if (!hasDOM()) return Promise.resolve();\n active = plan(steps, defaults);\n return new Promise<void>((resolve) => {\n let left = active.length;\n settle = () => {\n settle = undefined;\n resolve();\n };\n if (!left) return settle();\n const run = active;\n run.forEach(({ el, opts }) => {\n const done = opts.onComplete;\n sa().animate(el, {\n ...opts,\n onComplete: (node) => {\n done?.(node);\n if (run === active && --left === 0) settle?.();\n },\n });\n });\n });\n },\n\n cancel() {\n io?.disconnect();\n io = undefined;\n prepared.forEach((el) => stopAnimation(el));\n prepared = [];\n active.forEach(({ el }) => stopAnimation(el));\n active = [];\n settle?.();\n },\n\n duration() {\n return plan(steps, defaults).reduce((max, p) => Math.max(max, p.end), 0);\n },\n };\n\n if (trigger && hasDOM() && supportsObserver()) {\n const el = resolveTargets(trigger)[0];\n if (el) {\n prepared = plan(steps, defaults).map(({ el: target }) => target);\n prepared.forEach((target) => prepareElement(target));\n io = new IntersectionObserver(\n (entries) => {\n if (!entries.some((e) => e.isIntersecting)) return;\n io?.disconnect();\n io = undefined;\n prepared = []; // play() takes over from here\n controller.play();\n },\n { threshold: defaults.threshold ?? 0.1, rootMargin: defaults.rootMargin ?? '0px' }\n );\n io.observe(el);\n }\n }\n\n return controller;\n}\n","/**\n * use-scroll-animate - parallax() helper\n *\n * Moves elements at a different speed than the page while they cross the\n * viewport. Built on the same scroll progress as `progressVar` (0 when the\n * element's top enters at the bottom, 1 when its bottom leaves at the top):\n * the progress is written to a CSS custom property (default `--sa-parallax`)\n * and the offset is applied with the individual `translate` property, so it\n * composes with entrance animations and other `transform`s.\n */\n\nimport { getScrollProgress, hasDOM, prefersReducedMotion, resolveTargets, supportsObserver } from './core';\n\nexport interface ParallaxHelperOptions {\n /**\n * Total distance the element shifts while it crosses the viewport, as a\n * fraction of the viewport size (`0.2` = 20vh on the y axis). Positive values\n * lag behind the scroll (background-like), negative values move ahead of it\n * (foreground-like). (default: `0.2`)\n */\n speed?: number;\n /** `'y'` (default) or `'x'` (horizontal drift, in `vw`) */\n axis?: 'x' | 'y';\n /** CSS custom property receiving the progress (default: `'--sa-parallax'`) */\n progressVar?: string;\n /** Scroll container (default: the viewport) */\n root?: Element | null;\n /**\n * Under `prefers-reduced-motion: reduce` no offset is applied (the progress\n * variable is still written). Set to `false` to move anyway. (default: `true`)\n */\n respectReducedMotion?: boolean;\n}\n\nconst PASSIVE: AddEventListenerOptions = { passive: true };\n\n/**\n * Apply a scroll parallax to `target` (selector, Element, NodeList or array).\n * Returns a function that stops it and removes the inline styles it set.\n * SSR-safe (no-op without a DOM / IntersectionObserver).\n *\n * @example\n * const stop = parallax('.hero-bg', { speed: 0.3 });\n * parallax('.badge', { speed: -0.15, axis: 'x' });\n */\nexport function parallax(\n target: string | Element | NodeList | Element[],\n options: ParallaxHelperOptions = {}\n): () => void {\n const els = resolveTargets(target);\n if (!els.length || !hasDOM() || !supportsObserver()) return () => undefined;\n const { speed = 0.2, axis = 'y', root = null, respectReducedMotion = true } = options;\n const name = options.progressVar ? (options.progressVar.startsWith('--') ? options.progressVar : `--${options.progressVar}`) : '--sa-parallax';\n const unit = axis === 'x' ? 'vw' : 'vh';\n const visible = new Set<Element>();\n let frame = 0;\n let listening = false;\n const scroller: EventTarget = root || window;\n\n const apply = (el: Element) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n const p = getScrollProgress(el, root);\n style.setProperty(name, String(+p.toFixed(4)));\n if (respectReducedMotion && prefersReducedMotion()) {\n style.removeProperty('translate');\n return;\n }\n const offset = `${+((p - 0.5) * speed * 100).toFixed(3)}${unit}`;\n style.setProperty('translate', axis === 'x' ? `${offset} 0px` : `0px ${offset}`);\n };\n\n const update = () => {\n frame = 0;\n visible.forEach(apply);\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(update);\n };\n const listen = (on: boolean) => {\n if (on === listening) return;\n listening = on;\n const method = on ? 'addEventListener' : 'removeEventListener';\n scroller[method]('scroll', schedule, PASSIVE);\n window[method]('resize', schedule, PASSIVE);\n if (!on && frame) {\n cancelAnimationFrame(frame);\n frame = 0;\n }\n };\n\n const io = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) visible.add(entry.target);\n else visible.delete(entry.target);\n apply(entry.target); // report the edges even on fast scrolls\n });\n listen(visible.size > 0);\n },\n { threshold: 0, root }\n );\n els.forEach((el) => {\n apply(el); // no jump before the first observer callback\n io.observe(el);\n });\n\n return () => {\n io.disconnect();\n listen(false);\n visible.clear();\n els.forEach((el) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n style.removeProperty('translate');\n style.removeProperty(name);\n });\n };\n}\n","/**\n * use-scroll-animate\n *\n * A lightweight, dependency-free scroll animation library for modern web\n * applications. Built with TypeScript, powered by IntersectionObserver and\n * the Web Animations API (or the native scroll-driven timeline). Safe to\n * import during SSR. Framework integrations live in the subpath entries:\n * `use-scroll-animate/react`, `/vue`, `/svelte`, `/solid`, `/element`.\n *\n * @license MIT\n * @see https://github.com/HarrisonCN/use-scroll-animate\n */\n\nexport { createScrollAnimate, getScrollProgress, supportsScrollTimeline } from './core';\nexport { staggerChildren } from './stagger';\nexport { sequence } from './sequence';\nexport { parallax } from './parallax';\nexport { PRESETS, resolvePreset, resolveEasing, EASING_MAP } from './presets';\nexport type {\n AnimationPreset,\n EasingType,\n AnimationKeyframe,\n CustomAnimation,\n ProgressMode,\n ScrollEngine,\n AnimateOptions,\n ScrollAnimateConfig,\n AnimatedElement,\n ScrollAnimateInstance,\n} from './types';\nexport type { StaggerOptions } from './stagger';\nexport type { ParallaxHelperOptions } from './parallax';\nexport type { SequenceStep, SequenceOptions, SequenceController } from './sequence';\n\n// Default export: a ready-to-use singleton instance\nimport { createScrollAnimate } from './core';\n\n/**\n * Default singleton instance of ScrollAnimate.\n * Ready to use out of the box with sensible defaults.\n *\n * @example\n * ```js\n * import ScrollAnimate from 'use-scroll-animate';\n *\n * // Auto-initialize all elements with data-sa attribute\n * ScrollAnimate.init();\n *\n * // Or manually observe elements\n * ScrollAnimate.observe('.my-element', { animation: 'fade-in-up' });\n * ```\n */\nconst ScrollAnimate = /* @__PURE__ */ createScrollAnimate();\nexport default ScrollAnimate;\n"],"names":["resolveTargets","createScrollAnimate","hasDOM","stopAnimation","supportsObserver","prepareElement","getScrollProgress","prefersReducedMotion"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/parallax.ts","../src/index.ts"],"sourcesContent":["/**\n * use-scroll-animate - parallax() helper\n *\n * Moves elements at a different speed than the page while they cross the\n * viewport. Built on the same scroll progress as `progressVar` (0 when the\n * element's top enters at the bottom, 1 when its bottom leaves at the top):\n * the progress is written to a CSS custom property (default `--sa-parallax`)\n * and the offset is applied with the individual `translate` property, so it\n * composes with entrance animations and other `transform`s.\n */\n\nimport { getScrollProgress, hasDOM, prefersReducedMotion, resolveTargets, supportsObserver } from './core';\n\nexport interface ParallaxHelperOptions {\n /**\n * Total distance the element shifts while it crosses the viewport, as a\n * fraction of the viewport size (`0.2` = 20vh on the y axis). Positive values\n * lag behind the scroll (background-like), negative values move ahead of it\n * (foreground-like). (default: `0.2`)\n */\n speed?: number;\n /** `'y'` (default) or `'x'` (horizontal drift, in `vw`) */\n axis?: 'x' | 'y';\n /** CSS custom property receiving the progress (default: `'--sa-parallax'`) */\n progressVar?: string;\n /** Scroll container (default: the viewport) */\n root?: Element | null;\n /**\n * Under `prefers-reduced-motion: reduce` no offset is applied (the progress\n * variable is still written). Set to `false` to move anyway. (default: `true`)\n */\n respectReducedMotion?: boolean;\n}\n\nconst PASSIVE: AddEventListenerOptions = { passive: true };\n\n/**\n * Apply a scroll parallax to `target` (selector, Element, NodeList or array).\n * Returns a function that stops it and removes the inline styles it set.\n * SSR-safe (no-op without a DOM / IntersectionObserver).\n *\n * @example\n * const stop = parallax('.hero-bg', { speed: 0.3 });\n * parallax('.badge', { speed: -0.15, axis: 'x' });\n */\nexport function parallax(\n target: string | Element | NodeList | Element[],\n options: ParallaxHelperOptions = {}\n): () => void {\n const els = resolveTargets(target);\n if (!els.length || !hasDOM() || !supportsObserver()) return () => undefined;\n const { speed = 0.2, axis = 'y', root = null, respectReducedMotion = true } = options;\n const name = options.progressVar ? (options.progressVar.startsWith('--') ? options.progressVar : `--${options.progressVar}`) : '--sa-parallax';\n const unit = axis === 'x' ? 'vw' : 'vh';\n const visible = new Set<Element>();\n let frame = 0;\n let listening = false;\n const scroller: EventTarget = root || window;\n\n const apply = (el: Element) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n const p = getScrollProgress(el, root);\n style.setProperty(name, String(+p.toFixed(4)));\n if (respectReducedMotion && prefersReducedMotion()) {\n style.removeProperty('translate');\n return;\n }\n const offset = `${+((p - 0.5) * speed * 100).toFixed(3)}${unit}`;\n style.setProperty('translate', axis === 'x' ? `${offset} 0px` : `0px ${offset}`);\n };\n\n const update = () => {\n frame = 0;\n visible.forEach(apply);\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(update);\n };\n const listen = (on: boolean) => {\n if (on === listening) return;\n listening = on;\n const method = on ? 'addEventListener' : 'removeEventListener';\n scroller[method]('scroll', schedule, PASSIVE);\n window[method]('resize', schedule, PASSIVE);\n if (!on && frame) {\n cancelAnimationFrame(frame);\n frame = 0;\n }\n };\n\n const io = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) visible.add(entry.target);\n else visible.delete(entry.target);\n apply(entry.target); // report the edges even on fast scrolls\n });\n listen(visible.size > 0);\n },\n { threshold: 0, root }\n );\n els.forEach((el) => {\n apply(el); // no jump before the first observer callback\n io.observe(el);\n });\n\n return () => {\n io.disconnect();\n listen(false);\n visible.clear();\n els.forEach((el) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n style.removeProperty('translate');\n style.removeProperty(name);\n });\n };\n}\n","/**\n * use-scroll-animate\n *\n * A lightweight, dependency-free scroll animation library for modern web\n * applications. Built with TypeScript, powered by IntersectionObserver and\n * the Web Animations API (or the native scroll-driven timeline). Safe to\n * import during SSR. Framework integrations live in the subpath entries:\n * `use-scroll-animate/react`, `/vue`, `/svelte`, `/solid`, `/element`.\n *\n * @license MIT\n * @see https://github.com/HarrisonCN/use-scroll-animate\n */\n\nexport { createScrollAnimate, getScrollProgress, supportsScrollTimeline } from './core';\nexport { staggerChildren } from './stagger';\nexport { timeline, resolvePosition, TIMELINE_PRESETS } from './components/timeline/core';\nexport { parallax } from './parallax';\nexport { PRESETS, resolvePreset, resolveEasing, EASING_MAP } from './presets';\nexport type {\n AnimationPreset,\n EasingType,\n AnimationKeyframe,\n CustomAnimation,\n ProgressMode,\n ScrollEngine,\n AnimateOptions,\n ScrollAnimateConfig,\n AnimatedElement,\n ScrollAnimateInstance,\n} from './types';\nexport type { StaggerOptions } from './stagger';\nexport type { ParallaxHelperOptions } from './parallax';\nexport type { Timeline, TimelineOptions, TimelineStepOptions, TimelinePosition, ScrubOptions } from './components/timeline/core';\n\n// Default export: a ready-to-use singleton instance\nimport { createScrollAnimate } from './core';\n\n/**\n * Default singleton instance of ScrollAnimate.\n * Ready to use out of the box with sensible defaults.\n *\n * @example\n * ```js\n * import ScrollAnimate from 'use-scroll-animate';\n *\n * // Auto-initialize all elements with data-sa attribute\n * ScrollAnimate.init();\n *\n * // Or manually observe elements\n * ScrollAnimate.observe('.my-element', { animation: 'fade-in-up' });\n * ```\n */\nconst ScrollAnimate = /* @__PURE__ */ createScrollAnimate();\nexport default ScrollAnimate;\n"],"names":["resolveTargets","hasDOM","supportsObserver","getScrollProgress","prefersReducedMotion","createScrollAnimate"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -219,43 +219,85 @@ interface StaggerOptions extends AnimateOptions {
|
|
|
219
219
|
declare function staggerChildren(container: Element | null | undefined, options?: StaggerOptions, instance?: ScrollAnimateInstance): () => void;
|
|
220
220
|
|
|
221
221
|
/**
|
|
222
|
-
*
|
|
223
|
-
*
|
|
222
|
+
* Where a step starts on a timeline:
|
|
223
|
+
* - a number: absolute time in ms
|
|
224
|
+
* - `'>'` (default): when the previous step ends · `'<'`: when it starts
|
|
225
|
+
* - `'+=200'` / `'-=200'`: after / overlapping the previous end
|
|
226
|
+
* - `'<+=100'`: 100ms after the previous step's start
|
|
227
|
+
* - `'intro'` / `'intro+=150'`: at (or relative to) a label
|
|
224
228
|
*/
|
|
225
|
-
|
|
226
|
-
interface
|
|
227
|
-
/**
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
at?:
|
|
229
|
+
type TimelinePosition = number | string;
|
|
230
|
+
interface TimelineStepOptions {
|
|
231
|
+
/** Duration in ms (default: timeline default, 600). */
|
|
232
|
+
duration?: number;
|
|
233
|
+
/** CSS easing (default `cubic-bezier(0.22, 1, 0.36, 1)`). */
|
|
234
|
+
easing?: string;
|
|
235
|
+
/** Start position, see `TimelinePosition`. */
|
|
236
|
+
at?: TimelinePosition;
|
|
237
|
+
/** ms between targets when the selector matches several elements. */
|
|
238
|
+
stagger?: number;
|
|
233
239
|
}
|
|
234
|
-
interface
|
|
235
|
-
/**
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
|
|
240
|
+
interface TimelineOptions {
|
|
241
|
+
/** Defaults for every step. */
|
|
242
|
+
defaults?: Pick<TimelineStepOptions, 'duration' | 'easing' | 'stagger'>;
|
|
243
|
+
/** Playback rate (1 = normal). */
|
|
244
|
+
speed?: number;
|
|
245
|
+
/** Called after `play()` reaches the end (or the start when reversed). */
|
|
246
|
+
onComplete?: () => void;
|
|
247
|
+
/** Called on every frame with progress 0–1. */
|
|
248
|
+
onUpdate?: (progress: number) => void;
|
|
249
|
+
}
|
|
250
|
+
interface ScrubOptions {
|
|
251
|
+
/** Scroll offset (px) before the source's top reaches the viewport bottom where progress starts. */
|
|
252
|
+
offset?: number;
|
|
253
|
+
/** Smoothing 0–1 (0 = immediate, default 0). */
|
|
254
|
+
smooth?: number;
|
|
239
255
|
}
|
|
240
|
-
interface
|
|
241
|
-
/**
|
|
242
|
-
|
|
243
|
-
/**
|
|
256
|
+
interface Timeline {
|
|
257
|
+
/** Total length in ms. */
|
|
258
|
+
readonly duration: number;
|
|
259
|
+
/** Label positions in ms. */
|
|
260
|
+
readonly labels: Readonly<Record<string, number>>;
|
|
261
|
+
/** Current playhead in ms. */
|
|
262
|
+
readonly time: number;
|
|
263
|
+
/** Add a step: animate `target` with keyframes or a preset name (`fade-up`, `scale`…). */
|
|
264
|
+
to(target: string | Element | Element[] | NodeList, frames: Keyframe[] | string, options?: TimelineStepOptions): Timeline;
|
|
265
|
+
/** Name a position (default: the current end). */
|
|
266
|
+
label(name: string, at?: TimelinePosition): Timeline;
|
|
267
|
+
/** Run `fn` when the playhead passes `at`. */
|
|
268
|
+
call(fn: () => void, at?: TimelinePosition): Timeline;
|
|
269
|
+
/** Play forwards from the playhead (from 0 when at the end). Resolves at the end. */
|
|
270
|
+
play(from?: TimelinePosition): Promise<void>;
|
|
271
|
+
/** Play backwards to 0. */
|
|
272
|
+
reverse(): Promise<void>;
|
|
273
|
+
pause(): Timeline;
|
|
274
|
+
/** Jump to a time (ms) or label. */
|
|
275
|
+
seek(to: TimelinePosition): Timeline;
|
|
276
|
+
/** Get or set progress 0–1. */
|
|
277
|
+
progress(p?: number): number;
|
|
278
|
+
/** Tie progress to the scroll position of `source` (it moves through the viewport). Returns a stop function. */
|
|
279
|
+
scrub(source: Element, options?: ScrubOptions): () => void;
|
|
280
|
+
/** Stop and drop every animation (elements keep their last frame). */
|
|
244
281
|
cancel(): void;
|
|
245
|
-
/** Total duration of the timeline in ms (computed for the current DOM). */
|
|
246
|
-
duration(): number;
|
|
247
282
|
}
|
|
283
|
+
/** Keyframe presets usable by name in `to()` and `data-tl`. */
|
|
284
|
+
declare const TIMELINE_PRESETS: Record<string, Keyframe[]>;
|
|
285
|
+
/** Resolve a position against the previous step and labels (pure). */
|
|
286
|
+
declare function resolvePosition(pos: TimelinePosition | undefined, end: number, prevStart: number, labels?: Record<string, number>): number;
|
|
248
287
|
/**
|
|
249
|
-
*
|
|
288
|
+
* Choreograph animations on one clock: chain, overlap, label, seek, reverse and
|
|
289
|
+
* scrub them with scroll. Built on WAAPI (paused animations driven by one
|
|
290
|
+
* playhead); without WAAPI or under reduced motion it jumps to the end state.
|
|
250
291
|
*
|
|
251
292
|
* @example
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
* ], {
|
|
293
|
+
* const tl = timeline({ defaults: { duration: 500 } })
|
|
294
|
+
* .to('.title', 'fade-up')
|
|
295
|
+
* .label('cards')
|
|
296
|
+
* .to('.card', 'scale', { stagger: 80, at: '-=200' })
|
|
297
|
+
* .to('.cta', [{ opacity: 0 }, { opacity: 1 }], { at: 'cards+=400' });
|
|
298
|
+
* tl.play(); // or tl.scrub(document.querySelector('.hero'))
|
|
257
299
|
*/
|
|
258
|
-
declare function
|
|
300
|
+
declare function timeline(options?: TimelineOptions): Timeline;
|
|
259
301
|
|
|
260
302
|
/**
|
|
261
303
|
* use-scroll-animate - parallax() helper
|
|
@@ -330,5 +372,5 @@ declare function resolveEasing(easing: EasingType): string;
|
|
|
330
372
|
*/
|
|
331
373
|
declare const ScrollAnimate: ScrollAnimateInstance;
|
|
332
374
|
|
|
333
|
-
export { EASING_MAP, PRESETS, createScrollAnimate, ScrollAnimate as default, getScrollProgress, parallax, resolveEasing,
|
|
334
|
-
export type { AnimateOptions, AnimatedElement, AnimationKeyframe, AnimationPreset, CustomAnimation, EasingType, ParallaxHelperOptions, ProgressMode, ScrollAnimateConfig, ScrollAnimateInstance, ScrollEngine,
|
|
375
|
+
export { EASING_MAP, PRESETS, TIMELINE_PRESETS, createScrollAnimate, ScrollAnimate as default, getScrollProgress, parallax, resolveEasing, resolvePosition, resolvePreset, staggerChildren, supportsScrollTimeline, timeline };
|
|
376
|
+
export type { AnimateOptions, AnimatedElement, AnimationKeyframe, AnimationPreset, CustomAnimation, EasingType, ParallaxHelperOptions, ProgressMode, ScrollAnimateConfig, ScrollAnimateInstance, ScrollEngine, ScrubOptions, StaggerOptions, Timeline, TimelineOptions, TimelinePosition, TimelineStepOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -219,43 +219,85 @@ interface StaggerOptions extends AnimateOptions {
|
|
|
219
219
|
declare function staggerChildren(container: Element | null | undefined, options?: StaggerOptions, instance?: ScrollAnimateInstance): () => void;
|
|
220
220
|
|
|
221
221
|
/**
|
|
222
|
-
*
|
|
223
|
-
*
|
|
222
|
+
* Where a step starts on a timeline:
|
|
223
|
+
* - a number: absolute time in ms
|
|
224
|
+
* - `'>'` (default): when the previous step ends · `'<'`: when it starts
|
|
225
|
+
* - `'+=200'` / `'-=200'`: after / overlapping the previous end
|
|
226
|
+
* - `'<+=100'`: 100ms after the previous step's start
|
|
227
|
+
* - `'intro'` / `'intro+=150'`: at (or relative to) a label
|
|
224
228
|
*/
|
|
225
|
-
|
|
226
|
-
interface
|
|
227
|
-
/**
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
at?:
|
|
229
|
+
type TimelinePosition = number | string;
|
|
230
|
+
interface TimelineStepOptions {
|
|
231
|
+
/** Duration in ms (default: timeline default, 600). */
|
|
232
|
+
duration?: number;
|
|
233
|
+
/** CSS easing (default `cubic-bezier(0.22, 1, 0.36, 1)`). */
|
|
234
|
+
easing?: string;
|
|
235
|
+
/** Start position, see `TimelinePosition`. */
|
|
236
|
+
at?: TimelinePosition;
|
|
237
|
+
/** ms between targets when the selector matches several elements. */
|
|
238
|
+
stagger?: number;
|
|
233
239
|
}
|
|
234
|
-
interface
|
|
235
|
-
/**
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
|
|
240
|
+
interface TimelineOptions {
|
|
241
|
+
/** Defaults for every step. */
|
|
242
|
+
defaults?: Pick<TimelineStepOptions, 'duration' | 'easing' | 'stagger'>;
|
|
243
|
+
/** Playback rate (1 = normal). */
|
|
244
|
+
speed?: number;
|
|
245
|
+
/** Called after `play()` reaches the end (or the start when reversed). */
|
|
246
|
+
onComplete?: () => void;
|
|
247
|
+
/** Called on every frame with progress 0–1. */
|
|
248
|
+
onUpdate?: (progress: number) => void;
|
|
249
|
+
}
|
|
250
|
+
interface ScrubOptions {
|
|
251
|
+
/** Scroll offset (px) before the source's top reaches the viewport bottom where progress starts. */
|
|
252
|
+
offset?: number;
|
|
253
|
+
/** Smoothing 0–1 (0 = immediate, default 0). */
|
|
254
|
+
smooth?: number;
|
|
239
255
|
}
|
|
240
|
-
interface
|
|
241
|
-
/**
|
|
242
|
-
|
|
243
|
-
/**
|
|
256
|
+
interface Timeline {
|
|
257
|
+
/** Total length in ms. */
|
|
258
|
+
readonly duration: number;
|
|
259
|
+
/** Label positions in ms. */
|
|
260
|
+
readonly labels: Readonly<Record<string, number>>;
|
|
261
|
+
/** Current playhead in ms. */
|
|
262
|
+
readonly time: number;
|
|
263
|
+
/** Add a step: animate `target` with keyframes or a preset name (`fade-up`, `scale`…). */
|
|
264
|
+
to(target: string | Element | Element[] | NodeList, frames: Keyframe[] | string, options?: TimelineStepOptions): Timeline;
|
|
265
|
+
/** Name a position (default: the current end). */
|
|
266
|
+
label(name: string, at?: TimelinePosition): Timeline;
|
|
267
|
+
/** Run `fn` when the playhead passes `at`. */
|
|
268
|
+
call(fn: () => void, at?: TimelinePosition): Timeline;
|
|
269
|
+
/** Play forwards from the playhead (from 0 when at the end). Resolves at the end. */
|
|
270
|
+
play(from?: TimelinePosition): Promise<void>;
|
|
271
|
+
/** Play backwards to 0. */
|
|
272
|
+
reverse(): Promise<void>;
|
|
273
|
+
pause(): Timeline;
|
|
274
|
+
/** Jump to a time (ms) or label. */
|
|
275
|
+
seek(to: TimelinePosition): Timeline;
|
|
276
|
+
/** Get or set progress 0–1. */
|
|
277
|
+
progress(p?: number): number;
|
|
278
|
+
/** Tie progress to the scroll position of `source` (it moves through the viewport). Returns a stop function. */
|
|
279
|
+
scrub(source: Element, options?: ScrubOptions): () => void;
|
|
280
|
+
/** Stop and drop every animation (elements keep their last frame). */
|
|
244
281
|
cancel(): void;
|
|
245
|
-
/** Total duration of the timeline in ms (computed for the current DOM). */
|
|
246
|
-
duration(): number;
|
|
247
282
|
}
|
|
283
|
+
/** Keyframe presets usable by name in `to()` and `data-tl`. */
|
|
284
|
+
declare const TIMELINE_PRESETS: Record<string, Keyframe[]>;
|
|
285
|
+
/** Resolve a position against the previous step and labels (pure). */
|
|
286
|
+
declare function resolvePosition(pos: TimelinePosition | undefined, end: number, prevStart: number, labels?: Record<string, number>): number;
|
|
248
287
|
/**
|
|
249
|
-
*
|
|
288
|
+
* Choreograph animations on one clock: chain, overlap, label, seek, reverse and
|
|
289
|
+
* scrub them with scroll. Built on WAAPI (paused animations driven by one
|
|
290
|
+
* playhead); without WAAPI or under reduced motion it jumps to the end state.
|
|
250
291
|
*
|
|
251
292
|
* @example
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
* ], {
|
|
293
|
+
* const tl = timeline({ defaults: { duration: 500 } })
|
|
294
|
+
* .to('.title', 'fade-up')
|
|
295
|
+
* .label('cards')
|
|
296
|
+
* .to('.card', 'scale', { stagger: 80, at: '-=200' })
|
|
297
|
+
* .to('.cta', [{ opacity: 0 }, { opacity: 1 }], { at: 'cards+=400' });
|
|
298
|
+
* tl.play(); // or tl.scrub(document.querySelector('.hero'))
|
|
257
299
|
*/
|
|
258
|
-
declare function
|
|
300
|
+
declare function timeline(options?: TimelineOptions): Timeline;
|
|
259
301
|
|
|
260
302
|
/**
|
|
261
303
|
* use-scroll-animate - parallax() helper
|
|
@@ -330,5 +372,5 @@ declare function resolveEasing(easing: EasingType): string;
|
|
|
330
372
|
*/
|
|
331
373
|
declare const ScrollAnimate: ScrollAnimateInstance;
|
|
332
374
|
|
|
333
|
-
export { EASING_MAP, PRESETS, createScrollAnimate, ScrollAnimate as default, getScrollProgress, parallax, resolveEasing,
|
|
334
|
-
export type { AnimateOptions, AnimatedElement, AnimationKeyframe, AnimationPreset, CustomAnimation, EasingType, ParallaxHelperOptions, ProgressMode, ScrollAnimateConfig, ScrollAnimateInstance, ScrollEngine,
|
|
375
|
+
export { EASING_MAP, PRESETS, TIMELINE_PRESETS, createScrollAnimate, ScrollAnimate as default, getScrollProgress, parallax, resolveEasing, resolvePosition, resolvePreset, staggerChildren, supportsScrollTimeline, timeline };
|
|
376
|
+
export type { AnimateOptions, AnimatedElement, AnimationKeyframe, AnimationPreset, CustomAnimation, EasingType, ParallaxHelperOptions, ProgressMode, ScrollAnimateConfig, ScrollAnimateInstance, ScrollEngine, ScrubOptions, StaggerOptions, Timeline, TimelineOptions, TimelinePosition, TimelineStepOptions };
|
package/dist/index.js
CHANGED
|
@@ -1,107 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b as resolveTargets, h as hasDOM, s as supportsObserver, g as getScrollProgress, d as prefersReducedMotion, c as createScrollAnimate } from './chunks/core-mV_TPgG_.js';
|
|
2
2
|
export { E as EASING_MAP, P as PRESETS, e as resolveEasing, f as resolvePreset, i as supportsScrollTimeline } from './chunks/core-mV_TPgG_.js';
|
|
3
3
|
export { s as staggerChildren } from './chunks/stagger-BFAhKknX.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* use-scroll-animate - Sequence / timeline helper
|
|
7
|
-
* Chain animations on several targets, one after another (or overlapping).
|
|
8
|
-
*/
|
|
9
|
-
let fallback = null;
|
|
10
|
-
function plan(steps, defaults) {
|
|
11
|
-
const out = [];
|
|
12
|
-
let cursor = 0;
|
|
13
|
-
steps.forEach((step) => {
|
|
14
|
-
const { target, gap = 0, at, ...stepOpts } = step;
|
|
15
|
-
const opts = { ...defaults, ...stepOpts };
|
|
16
|
-
const duration = opts.duration ?? 600;
|
|
17
|
-
const start = Math.max(0, at ?? cursor + gap) + (opts.delay ?? 0);
|
|
18
|
-
let end = Math.max(cursor, start);
|
|
19
|
-
resolveTargets(target).forEach((el, i) => {
|
|
20
|
-
const delay = start + i * (opts.stagger ?? 0);
|
|
21
|
-
out.push({ el, opts: { ...opts, duration, delay, stagger: 0 }, end: delay + duration });
|
|
22
|
-
end = Math.max(end, delay + duration);
|
|
23
|
-
});
|
|
24
|
-
cursor = end;
|
|
25
|
-
});
|
|
26
|
-
return out;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Build a timeline of animations.
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* sequence([
|
|
33
|
-
* { target: '.title', animation: 'fade-in-up' },
|
|
34
|
-
* { target: '.subtitle', animation: 'blur-in', gap: -300 }, // overlap by 300ms
|
|
35
|
-
* { target: '.card', animation: 'scale-up', stagger: 80 },
|
|
36
|
-
* ], { trigger: '.hero' });
|
|
37
|
-
*/
|
|
38
|
-
function sequence(steps, options = {}) {
|
|
39
|
-
const { trigger, instance, ...defaults } = options;
|
|
40
|
-
const sa = () => instance || fallback || (fallback = createScrollAnimate());
|
|
41
|
-
let io;
|
|
42
|
-
let active = [];
|
|
43
|
-
let settle;
|
|
44
|
-
// Targets hidden while waiting for `trigger`; revealed if cancelled before it fires.
|
|
45
|
-
let prepared = [];
|
|
46
|
-
const controller = {
|
|
47
|
-
play() {
|
|
48
|
-
controller.cancel();
|
|
49
|
-
if (!hasDOM())
|
|
50
|
-
return Promise.resolve();
|
|
51
|
-
active = plan(steps, defaults);
|
|
52
|
-
return new Promise((resolve) => {
|
|
53
|
-
let left = active.length;
|
|
54
|
-
settle = () => {
|
|
55
|
-
settle = undefined;
|
|
56
|
-
resolve();
|
|
57
|
-
};
|
|
58
|
-
if (!left)
|
|
59
|
-
return settle();
|
|
60
|
-
const run = active;
|
|
61
|
-
run.forEach(({ el, opts }) => {
|
|
62
|
-
const done = opts.onComplete;
|
|
63
|
-
sa().animate(el, {
|
|
64
|
-
...opts,
|
|
65
|
-
onComplete: (node) => {
|
|
66
|
-
done?.(node);
|
|
67
|
-
if (run === active && --left === 0)
|
|
68
|
-
settle?.();
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
},
|
|
74
|
-
cancel() {
|
|
75
|
-
io?.disconnect();
|
|
76
|
-
io = undefined;
|
|
77
|
-
prepared.forEach((el) => stopAnimation(el));
|
|
78
|
-
prepared = [];
|
|
79
|
-
active.forEach(({ el }) => stopAnimation(el));
|
|
80
|
-
active = [];
|
|
81
|
-
settle?.();
|
|
82
|
-
},
|
|
83
|
-
duration() {
|
|
84
|
-
return plan(steps, defaults).reduce((max, p) => Math.max(max, p.end), 0);
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
if (trigger && hasDOM() && supportsObserver()) {
|
|
88
|
-
const el = resolveTargets(trigger)[0];
|
|
89
|
-
if (el) {
|
|
90
|
-
prepared = plan(steps, defaults).map(({ el: target }) => target);
|
|
91
|
-
prepared.forEach((target) => prepareElement(target));
|
|
92
|
-
io = new IntersectionObserver((entries) => {
|
|
93
|
-
if (!entries.some((e) => e.isIntersecting))
|
|
94
|
-
return;
|
|
95
|
-
io?.disconnect();
|
|
96
|
-
io = undefined;
|
|
97
|
-
prepared = []; // play() takes over from here
|
|
98
|
-
controller.play();
|
|
99
|
-
}, { threshold: defaults.threshold ?? 0.1, rootMargin: defaults.rootMargin ?? '0px' });
|
|
100
|
-
io.observe(el);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return controller;
|
|
104
|
-
}
|
|
4
|
+
export { T as TIMELINE_PRESETS, r as resolvePosition, t as timeline } from './chunks/core-Co-6AL0h.js';
|
|
5
|
+
import './chunks/base-ZARFccur.js';
|
|
105
6
|
|
|
106
7
|
/**
|
|
107
8
|
* use-scroll-animate - parallax() helper
|
|
@@ -224,5 +125,5 @@ function parallax(target, options = {}) {
|
|
|
224
125
|
*/
|
|
225
126
|
const ScrollAnimate = /* @__PURE__ */ createScrollAnimate();
|
|
226
127
|
|
|
227
|
-
export { createScrollAnimate, ScrollAnimate as default, getScrollProgress, parallax
|
|
128
|
+
export { createScrollAnimate, ScrollAnimate as default, getScrollProgress, parallax };
|
|
228
129
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/sequence.ts","../src/parallax.ts","../src/index.ts"],"sourcesContent":["/**\n * use-scroll-animate - Sequence / timeline helper\n * Chain animations on several targets, one after another (or overlapping).\n */\n\nimport type { AnimateOptions, ScrollAnimateInstance } from './types';\nimport { createScrollAnimate, hasDOM, prepareElement, resolveTargets, stopAnimation, supportsObserver } from './core';\n\nexport interface SequenceStep extends AnimateOptions {\n /** Selector, Element, NodeList or Element[] to animate in this step */\n target: string | Element | NodeList | Element[];\n /** Pause (ms) after the previous step ends before this one starts. Negative values overlap. (default: 0) */\n gap?: number;\n /** Absolute start time (ms) on the timeline; overrides `gap` */\n at?: number;\n}\n\nexport interface SequenceOptions extends AnimateOptions {\n /** Play automatically (once) when this element/selector enters the viewport */\n trigger?: string | Element;\n /** Instance whose global config (easing, classes, `disabled`) is used */\n instance?: ScrollAnimateInstance;\n}\n\nexport interface SequenceController {\n /** Play (or replay) the timeline. Resolves when every step has completed, or on `cancel()`. */\n play(): Promise<void>;\n /** Stop the trigger and running animations; elements are left visible. */\n cancel(): void;\n /** Total duration of the timeline in ms (computed for the current DOM). */\n duration(): number;\n}\n\nlet fallback: ScrollAnimateInstance | null = null;\n\ntype Planned = { el: Element; opts: AnimateOptions; end: number };\n\nfunction plan(steps: SequenceStep[], defaults: AnimateOptions): Planned[] {\n const out: Planned[] = [];\n let cursor = 0;\n steps.forEach((step) => {\n const { target, gap = 0, at, ...stepOpts } = step;\n const opts = { ...defaults, ...stepOpts };\n const duration = opts.duration ?? 600;\n const start = Math.max(0, at ?? cursor + gap) + (opts.delay ?? 0);\n let end = Math.max(cursor, start);\n resolveTargets(target).forEach((el, i) => {\n const delay = start + i * (opts.stagger ?? 0);\n out.push({ el, opts: { ...opts, duration, delay, stagger: 0 }, end: delay + duration });\n end = Math.max(end, delay + duration);\n });\n cursor = end;\n });\n return out;\n}\n\n/**\n * Build a timeline of animations.\n *\n * @example\n * sequence([\n * { target: '.title', animation: 'fade-in-up' },\n * { target: '.subtitle', animation: 'blur-in', gap: -300 }, // overlap by 300ms\n * { target: '.card', animation: 'scale-up', stagger: 80 },\n * ], { trigger: '.hero' });\n */\nexport function sequence(steps: SequenceStep[], options: SequenceOptions = {}): SequenceController {\n const { trigger, instance, ...defaults } = options;\n const sa = () => instance || fallback || (fallback = createScrollAnimate());\n let io: IntersectionObserver | undefined;\n let active: Planned[] = [];\n let settle: (() => void) | undefined;\n // Targets hidden while waiting for `trigger`; revealed if cancelled before it fires.\n let prepared: Element[] = [];\n\n const controller: SequenceController = {\n play() {\n controller.cancel();\n if (!hasDOM()) return Promise.resolve();\n active = plan(steps, defaults);\n return new Promise<void>((resolve) => {\n let left = active.length;\n settle = () => {\n settle = undefined;\n resolve();\n };\n if (!left) return settle();\n const run = active;\n run.forEach(({ el, opts }) => {\n const done = opts.onComplete;\n sa().animate(el, {\n ...opts,\n onComplete: (node) => {\n done?.(node);\n if (run === active && --left === 0) settle?.();\n },\n });\n });\n });\n },\n\n cancel() {\n io?.disconnect();\n io = undefined;\n prepared.forEach((el) => stopAnimation(el));\n prepared = [];\n active.forEach(({ el }) => stopAnimation(el));\n active = [];\n settle?.();\n },\n\n duration() {\n return plan(steps, defaults).reduce((max, p) => Math.max(max, p.end), 0);\n },\n };\n\n if (trigger && hasDOM() && supportsObserver()) {\n const el = resolveTargets(trigger)[0];\n if (el) {\n prepared = plan(steps, defaults).map(({ el: target }) => target);\n prepared.forEach((target) => prepareElement(target));\n io = new IntersectionObserver(\n (entries) => {\n if (!entries.some((e) => e.isIntersecting)) return;\n io?.disconnect();\n io = undefined;\n prepared = []; // play() takes over from here\n controller.play();\n },\n { threshold: defaults.threshold ?? 0.1, rootMargin: defaults.rootMargin ?? '0px' }\n );\n io.observe(el);\n }\n }\n\n return controller;\n}\n","/**\n * use-scroll-animate - parallax() helper\n *\n * Moves elements at a different speed than the page while they cross the\n * viewport. Built on the same scroll progress as `progressVar` (0 when the\n * element's top enters at the bottom, 1 when its bottom leaves at the top):\n * the progress is written to a CSS custom property (default `--sa-parallax`)\n * and the offset is applied with the individual `translate` property, so it\n * composes with entrance animations and other `transform`s.\n */\n\nimport { getScrollProgress, hasDOM, prefersReducedMotion, resolveTargets, supportsObserver } from './core';\n\nexport interface ParallaxHelperOptions {\n /**\n * Total distance the element shifts while it crosses the viewport, as a\n * fraction of the viewport size (`0.2` = 20vh on the y axis). Positive values\n * lag behind the scroll (background-like), negative values move ahead of it\n * (foreground-like). (default: `0.2`)\n */\n speed?: number;\n /** `'y'` (default) or `'x'` (horizontal drift, in `vw`) */\n axis?: 'x' | 'y';\n /** CSS custom property receiving the progress (default: `'--sa-parallax'`) */\n progressVar?: string;\n /** Scroll container (default: the viewport) */\n root?: Element | null;\n /**\n * Under `prefers-reduced-motion: reduce` no offset is applied (the progress\n * variable is still written). Set to `false` to move anyway. (default: `true`)\n */\n respectReducedMotion?: boolean;\n}\n\nconst PASSIVE: AddEventListenerOptions = { passive: true };\n\n/**\n * Apply a scroll parallax to `target` (selector, Element, NodeList or array).\n * Returns a function that stops it and removes the inline styles it set.\n * SSR-safe (no-op without a DOM / IntersectionObserver).\n *\n * @example\n * const stop = parallax('.hero-bg', { speed: 0.3 });\n * parallax('.badge', { speed: -0.15, axis: 'x' });\n */\nexport function parallax(\n target: string | Element | NodeList | Element[],\n options: ParallaxHelperOptions = {}\n): () => void {\n const els = resolveTargets(target);\n if (!els.length || !hasDOM() || !supportsObserver()) return () => undefined;\n const { speed = 0.2, axis = 'y', root = null, respectReducedMotion = true } = options;\n const name = options.progressVar ? (options.progressVar.startsWith('--') ? options.progressVar : `--${options.progressVar}`) : '--sa-parallax';\n const unit = axis === 'x' ? 'vw' : 'vh';\n const visible = new Set<Element>();\n let frame = 0;\n let listening = false;\n const scroller: EventTarget = root || window;\n\n const apply = (el: Element) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n const p = getScrollProgress(el, root);\n style.setProperty(name, String(+p.toFixed(4)));\n if (respectReducedMotion && prefersReducedMotion()) {\n style.removeProperty('translate');\n return;\n }\n const offset = `${+((p - 0.5) * speed * 100).toFixed(3)}${unit}`;\n style.setProperty('translate', axis === 'x' ? `${offset} 0px` : `0px ${offset}`);\n };\n\n const update = () => {\n frame = 0;\n visible.forEach(apply);\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(update);\n };\n const listen = (on: boolean) => {\n if (on === listening) return;\n listening = on;\n const method = on ? 'addEventListener' : 'removeEventListener';\n scroller[method]('scroll', schedule, PASSIVE);\n window[method]('resize', schedule, PASSIVE);\n if (!on && frame) {\n cancelAnimationFrame(frame);\n frame = 0;\n }\n };\n\n const io = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) visible.add(entry.target);\n else visible.delete(entry.target);\n apply(entry.target); // report the edges even on fast scrolls\n });\n listen(visible.size > 0);\n },\n { threshold: 0, root }\n );\n els.forEach((el) => {\n apply(el); // no jump before the first observer callback\n io.observe(el);\n });\n\n return () => {\n io.disconnect();\n listen(false);\n visible.clear();\n els.forEach((el) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n style.removeProperty('translate');\n style.removeProperty(name);\n });\n };\n}\n","/**\n * use-scroll-animate\n *\n * A lightweight, dependency-free scroll animation library for modern web\n * applications. Built with TypeScript, powered by IntersectionObserver and\n * the Web Animations API (or the native scroll-driven timeline). Safe to\n * import during SSR. Framework integrations live in the subpath entries:\n * `use-scroll-animate/react`, `/vue`, `/svelte`, `/solid`, `/element`.\n *\n * @license MIT\n * @see https://github.com/HarrisonCN/use-scroll-animate\n */\n\nexport { createScrollAnimate, getScrollProgress, supportsScrollTimeline } from './core';\nexport { staggerChildren } from './stagger';\nexport { sequence } from './sequence';\nexport { parallax } from './parallax';\nexport { PRESETS, resolvePreset, resolveEasing, EASING_MAP } from './presets';\nexport type {\n AnimationPreset,\n EasingType,\n AnimationKeyframe,\n CustomAnimation,\n ProgressMode,\n ScrollEngine,\n AnimateOptions,\n ScrollAnimateConfig,\n AnimatedElement,\n ScrollAnimateInstance,\n} from './types';\nexport type { StaggerOptions } from './stagger';\nexport type { ParallaxHelperOptions } from './parallax';\nexport type { SequenceStep, SequenceOptions, SequenceController } from './sequence';\n\n// Default export: a ready-to-use singleton instance\nimport { createScrollAnimate } from './core';\n\n/**\n * Default singleton instance of ScrollAnimate.\n * Ready to use out of the box with sensible defaults.\n *\n * @example\n * ```js\n * import ScrollAnimate from 'use-scroll-animate';\n *\n * // Auto-initialize all elements with data-sa attribute\n * ScrollAnimate.init();\n *\n * // Or manually observe elements\n * ScrollAnimate.observe('.my-element', { animation: 'fade-in-up' });\n * ```\n */\nconst ScrollAnimate = /* @__PURE__ */ createScrollAnimate();\nexport default ScrollAnimate;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/parallax.ts","../src/index.ts"],"sourcesContent":["/**\n * use-scroll-animate - parallax() helper\n *\n * Moves elements at a different speed than the page while they cross the\n * viewport. Built on the same scroll progress as `progressVar` (0 when the\n * element's top enters at the bottom, 1 when its bottom leaves at the top):\n * the progress is written to a CSS custom property (default `--sa-parallax`)\n * and the offset is applied with the individual `translate` property, so it\n * composes with entrance animations and other `transform`s.\n */\n\nimport { getScrollProgress, hasDOM, prefersReducedMotion, resolveTargets, supportsObserver } from './core';\n\nexport interface ParallaxHelperOptions {\n /**\n * Total distance the element shifts while it crosses the viewport, as a\n * fraction of the viewport size (`0.2` = 20vh on the y axis). Positive values\n * lag behind the scroll (background-like), negative values move ahead of it\n * (foreground-like). (default: `0.2`)\n */\n speed?: number;\n /** `'y'` (default) or `'x'` (horizontal drift, in `vw`) */\n axis?: 'x' | 'y';\n /** CSS custom property receiving the progress (default: `'--sa-parallax'`) */\n progressVar?: string;\n /** Scroll container (default: the viewport) */\n root?: Element | null;\n /**\n * Under `prefers-reduced-motion: reduce` no offset is applied (the progress\n * variable is still written). Set to `false` to move anyway. (default: `true`)\n */\n respectReducedMotion?: boolean;\n}\n\nconst PASSIVE: AddEventListenerOptions = { passive: true };\n\n/**\n * Apply a scroll parallax to `target` (selector, Element, NodeList or array).\n * Returns a function that stops it and removes the inline styles it set.\n * SSR-safe (no-op without a DOM / IntersectionObserver).\n *\n * @example\n * const stop = parallax('.hero-bg', { speed: 0.3 });\n * parallax('.badge', { speed: -0.15, axis: 'x' });\n */\nexport function parallax(\n target: string | Element | NodeList | Element[],\n options: ParallaxHelperOptions = {}\n): () => void {\n const els = resolveTargets(target);\n if (!els.length || !hasDOM() || !supportsObserver()) return () => undefined;\n const { speed = 0.2, axis = 'y', root = null, respectReducedMotion = true } = options;\n const name = options.progressVar ? (options.progressVar.startsWith('--') ? options.progressVar : `--${options.progressVar}`) : '--sa-parallax';\n const unit = axis === 'x' ? 'vw' : 'vh';\n const visible = new Set<Element>();\n let frame = 0;\n let listening = false;\n const scroller: EventTarget = root || window;\n\n const apply = (el: Element) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n const p = getScrollProgress(el, root);\n style.setProperty(name, String(+p.toFixed(4)));\n if (respectReducedMotion && prefersReducedMotion()) {\n style.removeProperty('translate');\n return;\n }\n const offset = `${+((p - 0.5) * speed * 100).toFixed(3)}${unit}`;\n style.setProperty('translate', axis === 'x' ? `${offset} 0px` : `0px ${offset}`);\n };\n\n const update = () => {\n frame = 0;\n visible.forEach(apply);\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(update);\n };\n const listen = (on: boolean) => {\n if (on === listening) return;\n listening = on;\n const method = on ? 'addEventListener' : 'removeEventListener';\n scroller[method]('scroll', schedule, PASSIVE);\n window[method]('resize', schedule, PASSIVE);\n if (!on && frame) {\n cancelAnimationFrame(frame);\n frame = 0;\n }\n };\n\n const io = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) visible.add(entry.target);\n else visible.delete(entry.target);\n apply(entry.target); // report the edges even on fast scrolls\n });\n listen(visible.size > 0);\n },\n { threshold: 0, root }\n );\n els.forEach((el) => {\n apply(el); // no jump before the first observer callback\n io.observe(el);\n });\n\n return () => {\n io.disconnect();\n listen(false);\n visible.clear();\n els.forEach((el) => {\n const style = (el as HTMLElement).style;\n if (!style) return;\n style.removeProperty('translate');\n style.removeProperty(name);\n });\n };\n}\n","/**\n * use-scroll-animate\n *\n * A lightweight, dependency-free scroll animation library for modern web\n * applications. Built with TypeScript, powered by IntersectionObserver and\n * the Web Animations API (or the native scroll-driven timeline). Safe to\n * import during SSR. Framework integrations live in the subpath entries:\n * `use-scroll-animate/react`, `/vue`, `/svelte`, `/solid`, `/element`.\n *\n * @license MIT\n * @see https://github.com/HarrisonCN/use-scroll-animate\n */\n\nexport { createScrollAnimate, getScrollProgress, supportsScrollTimeline } from './core';\nexport { staggerChildren } from './stagger';\nexport { timeline, resolvePosition, TIMELINE_PRESETS } from './components/timeline/core';\nexport { parallax } from './parallax';\nexport { PRESETS, resolvePreset, resolveEasing, EASING_MAP } from './presets';\nexport type {\n AnimationPreset,\n EasingType,\n AnimationKeyframe,\n CustomAnimation,\n ProgressMode,\n ScrollEngine,\n AnimateOptions,\n ScrollAnimateConfig,\n AnimatedElement,\n ScrollAnimateInstance,\n} from './types';\nexport type { StaggerOptions } from './stagger';\nexport type { ParallaxHelperOptions } from './parallax';\nexport type { Timeline, TimelineOptions, TimelineStepOptions, TimelinePosition, ScrubOptions } from './components/timeline/core';\n\n// Default export: a ready-to-use singleton instance\nimport { createScrollAnimate } from './core';\n\n/**\n * Default singleton instance of ScrollAnimate.\n * Ready to use out of the box with sensible defaults.\n *\n * @example\n * ```js\n * import ScrollAnimate from 'use-scroll-animate';\n *\n * // Auto-initialize all elements with data-sa attribute\n * ScrollAnimate.init();\n *\n * // Or manually observe elements\n * ScrollAnimate.observe('.my-element', { animation: 'fade-in-up' });\n * ```\n */\nconst ScrollAnimate = /* @__PURE__ */ createScrollAnimate();\nexport default ScrollAnimate;\n"],"names":[],"mappings":"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"}
|