use-scroll-animate 2.1.0 → 2.3.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +31 -2
  3. package/README_ja.md +19 -0
  4. package/README_zh.md +30 -0
  5. package/dist/chunks/base-CJ7XfidP.cjs +233 -0
  6. package/dist/chunks/base-CJ7XfidP.cjs.map +1 -0
  7. package/dist/chunks/base-CuvCgqLy.js +219 -0
  8. package/dist/chunks/base-CuvCgqLy.js.map +1 -0
  9. package/dist/components/background.cjs +395 -0
  10. package/dist/components/background.cjs.map +1 -0
  11. package/dist/components/background.css +7 -0
  12. package/dist/components/background.d.cts +132 -0
  13. package/dist/components/background.d.ts +132 -0
  14. package/dist/components/background.js +387 -0
  15. package/dist/components/background.js.map +1 -0
  16. package/dist/components/feedback.cjs +444 -0
  17. package/dist/components/feedback.cjs.map +1 -0
  18. package/dist/components/feedback.css +7 -0
  19. package/dist/components/feedback.d.cts +170 -0
  20. package/dist/components/feedback.d.ts +170 -0
  21. package/dist/components/feedback.js +434 -0
  22. package/dist/components/feedback.js.map +1 -0
  23. package/dist/components/interaction.cjs +426 -0
  24. package/dist/components/interaction.cjs.map +1 -0
  25. package/dist/components/interaction.css +8 -0
  26. package/dist/components/interaction.d.cts +142 -0
  27. package/dist/components/interaction.d.ts +142 -0
  28. package/dist/components/interaction.js +417 -0
  29. package/dist/components/interaction.js.map +1 -0
  30. package/dist/components/physics.cjs +664 -0
  31. package/dist/components/physics.cjs.map +1 -0
  32. package/dist/components/physics.css +5 -0
  33. package/dist/components/physics.d.cts +216 -0
  34. package/dist/components/physics.d.ts +216 -0
  35. package/dist/components/physics.js +644 -0
  36. package/dist/components/physics.js.map +1 -0
  37. package/dist/components/reveal.cjs +360 -0
  38. package/dist/components/reveal.cjs.map +1 -0
  39. package/dist/components/reveal.css +5 -0
  40. package/dist/components/reveal.d.cts +132 -0
  41. package/dist/components/reveal.d.ts +132 -0
  42. package/dist/components/reveal.js +350 -0
  43. package/dist/components/reveal.js.map +1 -0
  44. package/dist/components/text.cjs +528 -0
  45. package/dist/components/text.cjs.map +1 -0
  46. package/dist/components/text.css +7 -0
  47. package/dist/components/text.d.cts +164 -0
  48. package/dist/components/text.d.ts +164 -0
  49. package/dist/components/text.js +517 -0
  50. package/dist/components/text.js.map +1 -0
  51. package/dist/components/transitions.cjs +546 -0
  52. package/dist/components/transitions.cjs.map +1 -0
  53. package/dist/components/transitions.css +6 -0
  54. package/dist/components/transitions.d.cts +180 -0
  55. package/dist/components/transitions.d.ts +180 -0
  56. package/dist/components/transitions.js +536 -0
  57. package/dist/components/transitions.js.map +1 -0
  58. package/dist/components.cjs +127 -0
  59. package/dist/components.cjs.map +1 -0
  60. package/dist/components.css +33 -0
  61. package/dist/components.d.cts +919 -0
  62. package/dist/components.d.ts +919 -0
  63. package/dist/components.js +65 -0
  64. package/dist/components.js.map +1 -0
  65. package/dist/components.umd.js +22 -0
  66. package/dist/components.umd.js.map +1 -0
  67. package/docs/API.md +2 -0
  68. package/docs/components.md +169 -0
  69. package/docs/windows-apps.md +108 -0
  70. package/package.json +105 -5
@@ -0,0 +1,644 @@
1
+ import { p as prefersReducedMotion, g as applyFrame, e as EASE_SPRING, n as now, r as raf, b as caf, d as defineElement, a as clamp } from '../chunks/base-CuvCgqLy.js';
2
+ export { c as configureComponents } from '../chunks/base-CuvCgqLy.js';
3
+
4
+ const SPRING_PRESETS = {
5
+ default: { stiffness: 170, damping: 26, mass: 1 },
6
+ gentle: { stiffness: 120, damping: 14, mass: 1 },
7
+ wobbly: { stiffness: 180, damping: 12, mass: 1 },
8
+ stiff: { stiffness: 210, damping: 20, mass: 1 },
9
+ bouncy: { stiffness: 300, damping: 10, mass: 1 },
10
+ slow: { stiffness: 280, damping: 60, mass: 1 },
11
+ molasses: { stiffness: 280, damping: 120, mass: 1 },
12
+ };
13
+ /** Resolve a preset name or a partial config to a full config. */
14
+ function resolveSpring(input) {
15
+ const base = typeof input === 'string' ? SPRING_PRESETS[input] || SPRING_PRESETS.default : { ...SPRING_PRESETS.default, ...(input || {}) };
16
+ const pos = (v, d) => (typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : d);
17
+ const o = (typeof input === 'object' && input) || {};
18
+ return {
19
+ stiffness: pos(base.stiffness, 170),
20
+ damping: Math.max(0, Number.isFinite(base.damping) ? base.damping : 26),
21
+ mass: pos(base.mass, 1),
22
+ velocity: Number.isFinite(o.velocity) ? o.velocity : 0,
23
+ precision: pos(o.precision, 0.001),
24
+ };
25
+ }
26
+ /** One integration step (semi-implicit Euler) towards `to`. Returns [x, v]. */
27
+ function stepSpring(cfg, x, v, to, dt) {
28
+ const a = (-cfg.stiffness * (x - to) - cfg.damping * v) / cfg.mass;
29
+ const nv = v + a * dt;
30
+ return [x + nv * dt, nv];
31
+ }
32
+ const cache = new Map();
33
+ /**
34
+ * Sample the spring from 0 to 1 at `fps` (default 60). `values` may exceed 1
35
+ * (overshoot); `duration` is the time to rest, in ms (max 10 s).
36
+ */
37
+ function springSamples(input, fps = 60) {
38
+ const cfg = resolveSpring(input);
39
+ const key = `${cfg.stiffness}|${cfg.damping}|${cfg.mass}|${cfg.velocity}|${cfg.precision}|${fps}`;
40
+ const hit = cache.get(key);
41
+ if (hit)
42
+ return hit;
43
+ const values = [0];
44
+ let x = 0;
45
+ let v = cfg.velocity;
46
+ const frame = 1000 / fps;
47
+ let t = 0;
48
+ let next = frame;
49
+ while (t < 10000) {
50
+ [x, v] = stepSpring(cfg, x, v, 1, 0.001);
51
+ t += 1;
52
+ if (t >= next) {
53
+ values.push(x);
54
+ next += frame;
55
+ if (Math.abs(1 - x) < cfg.precision && Math.abs(v) < cfg.precision * 10)
56
+ break;
57
+ }
58
+ }
59
+ values[values.length - 1] = 1;
60
+ const out = { values, duration: Math.round(t) };
61
+ if (cache.size > 64)
62
+ cache.clear();
63
+ cache.set(key, out);
64
+ return out;
65
+ }
66
+ /** `true` when CSS `linear()` easing is supported. */
67
+ function supportsLinearEasing() {
68
+ return typeof CSS !== 'undefined' && typeof CSS.supports === 'function' && CSS.supports('animation-timing-function', 'linear(0, 1)');
69
+ }
70
+ /**
71
+ * The spring as `{ easing, duration }` for `el.animate()` / CSS. `easing` is
72
+ * a `linear(…)` function with at most `points` stops (default 48), or a
73
+ * cubic-bezier overshoot where `linear()` is unsupported.
74
+ */
75
+ function springEasing(input, points = 48) {
76
+ const { values, duration } = springSamples(input);
77
+ if (!supportsLinearEasing())
78
+ return { easing: EASE_SPRING, duration: Math.min(duration, 1200) };
79
+ return { easing: linearEasing(values, points), duration };
80
+ }
81
+ /** Build a CSS `linear()` easing from samples (down-sampled to `points`). */
82
+ function linearEasing(values, points = 48) {
83
+ const n = values.length;
84
+ const step = Math.max(1, Math.ceil((n - 1) / Math.max(2, points - 1)));
85
+ const out = [];
86
+ for (let i = 0; i < n - 1; i += step)
87
+ out.push(String(Math.round(values[i] * 1000) / 1000));
88
+ out.push('1');
89
+ return `linear(${out.join(', ')})`;
90
+ }
91
+ /**
92
+ * Animate `el` between keyframes with spring timing (WAAPI). Under reduced
93
+ * motion the final frame is applied immediately. Returns the Animation (or
94
+ * `null` without WAAPI / under reduced motion).
95
+ */
96
+ function spring(el, keyframes, input, options = {}) {
97
+ const target = el;
98
+ if (prefersReducedMotion() || typeof target.animate !== 'function') {
99
+ applyFrame(target, keyframes[keyframes.length - 1]);
100
+ return null;
101
+ }
102
+ const { easing, duration } = springEasing(input);
103
+ return target.animate(keyframes, { duration, easing, fill: 'both', ...options });
104
+ }
105
+ /**
106
+ * An interruptible spring-animated number: call `set()` as often as you like,
107
+ * the motion keeps its velocity (like iOS / Framer springs). Reduced motion
108
+ * jumps straight to the target.
109
+ */
110
+ function createSpring(opts = {}) {
111
+ let cfg = resolveSpring(opts.spring);
112
+ let x = opts.value ?? 0;
113
+ let v = 0;
114
+ let to = x;
115
+ let id = 0;
116
+ let last = 0;
117
+ let running = false;
118
+ const stop = () => {
119
+ if (running)
120
+ caf(id);
121
+ running = false;
122
+ };
123
+ const loop = () => {
124
+ const t = now();
125
+ let dt = Math.min(64, Math.max(1, t - last));
126
+ last = t;
127
+ while (dt > 0) {
128
+ const s = Math.min(dt, 4);
129
+ [x, v] = stepSpring(cfg, x, v, to, s / 1000);
130
+ dt -= s;
131
+ }
132
+ const scale = Math.max(1, Math.abs(to) * 0.0005);
133
+ if (Math.abs(to - x) < cfg.precision * scale * 10 && Math.abs(v) < cfg.precision * scale * 100) {
134
+ x = to;
135
+ v = 0;
136
+ running = false;
137
+ opts.onUpdate?.(x, 0);
138
+ opts.onRest?.(x);
139
+ return;
140
+ }
141
+ opts.onUpdate?.(x, v);
142
+ id = raf(loop);
143
+ };
144
+ const api = {
145
+ get value() {
146
+ return x;
147
+ },
148
+ get velocity() {
149
+ return v;
150
+ },
151
+ get target() {
152
+ return to;
153
+ },
154
+ get animating() {
155
+ return running;
156
+ },
157
+ set(target, velocity) {
158
+ to = target;
159
+ if (velocity !== undefined && Number.isFinite(velocity))
160
+ v = velocity;
161
+ if (prefersReducedMotion()) {
162
+ api.jump(target);
163
+ opts.onRest?.(target);
164
+ return;
165
+ }
166
+ if (!running) {
167
+ running = true;
168
+ last = now();
169
+ id = raf(loop);
170
+ }
171
+ },
172
+ jump(value) {
173
+ stop();
174
+ x = to = value;
175
+ v = 0;
176
+ opts.onUpdate?.(x, 0);
177
+ },
178
+ stop() {
179
+ stop();
180
+ v = 0;
181
+ to = x;
182
+ },
183
+ configure(input) {
184
+ cfg = resolveSpring(input);
185
+ },
186
+ };
187
+ return api;
188
+ }
189
+ /* ------------------------------------------------------------------ */
190
+ /* Inertia + snapping */
191
+ /* ------------------------------------------------------------------ */
192
+ /**
193
+ * Where a flick at `velocity` (units/s) comes to rest with exponential
194
+ * decay: `value + velocity · timeConstant` (default 0.325 s, iOS-like).
195
+ */
196
+ function projectInertia(value, velocity, timeConstant = 0.325) {
197
+ return value + velocity * timeConstant;
198
+ }
199
+ /** Snap to a grid (`number`) or the nearest of a list of points. */
200
+ function snapTo(value, to) {
201
+ if (Array.isArray(to)) {
202
+ if (!to.length)
203
+ return value;
204
+ return to.reduce((best, p) => (Math.abs(p - value) < Math.abs(best - value) ? p : best), to[0]);
205
+ }
206
+ if (typeof to === 'number' && to > 0)
207
+ return Math.round(value / to) * to;
208
+ return value;
209
+ }
210
+ /** iOS-style rubber-band resistance: how far content moves when pulled `distance` past an edge. */
211
+ function rubberBand(distance, dimension, constant = 0.55) {
212
+ if (dimension <= 0)
213
+ return 0;
214
+ const sign = distance < 0 ? -1 : 1;
215
+ const d = Math.abs(distance);
216
+ return sign * (1 - 1 / ((d * constant) / dimension + 1)) * dimension;
217
+ }
218
+
219
+ var css$2 = "usa-spring{display:inline-block;transform-origin:50% 70%}usa-spring[block]{display:block}usa-spring[effect=\"drop\"]{transform-origin:50% 100%}usa-spring[data-state=\"hidden\"]{opacity:0}usa-spring[trigger=\"click\"],usa-spring[trigger=\"hover\"]{cursor:pointer;-webkit-tap-highlight-color:transparent}";
220
+
221
+ const SPRING_EFFECTS = ['bounce-in', 'pop', 'drop', 'jelly', 'rubber-band'];
222
+ /** Entrance effects start hidden; attention effects (jelly, rubber-band) play on visible content. */
223
+ const ENTRANCE = new Set(['bounce-in', 'pop', 'drop']);
224
+ /** Keyframes of a spring effect (entrances use spring timing, attention effects fixed frames). */
225
+ function springEffectKeyframes(effect, reduced = false) {
226
+ if (reduced)
227
+ return ENTRANCE.has(effect) ? [{ opacity: 0 }, { opacity: 1 }] : [{ opacity: 1 }, { opacity: 1 }];
228
+ switch (effect) {
229
+ case 'pop':
230
+ return [{ opacity: 0, transform: 'scale(0.5)' }, { opacity: 1, transform: 'scale(1)' }];
231
+ case 'drop':
232
+ return [{ opacity: 0, transform: 'translate3d(0, -120%, 0)' }, { opacity: 1, transform: 'translate3d(0, 0, 0)' }];
233
+ case 'jelly':
234
+ return [
235
+ { transform: 'scale3d(1, 1, 1)' },
236
+ { transform: 'scale3d(1.25, 0.75, 1)', offset: 0.3 },
237
+ { transform: 'scale3d(0.75, 1.25, 1)', offset: 0.4 },
238
+ { transform: 'scale3d(1.15, 0.85, 1)', offset: 0.5 },
239
+ { transform: 'scale3d(0.95, 1.05, 1)', offset: 0.65 },
240
+ { transform: 'scale3d(1.05, 0.95, 1)', offset: 0.75 },
241
+ { transform: 'scale3d(1, 1, 1)' },
242
+ ];
243
+ case 'rubber-band':
244
+ return [
245
+ { transform: 'scale3d(1, 1, 1)' },
246
+ { transform: 'scale3d(1.3, 0.7, 1)', offset: 0.3 },
247
+ { transform: 'scale3d(0.8, 1.2, 1)', offset: 0.45 },
248
+ { transform: 'scale3d(1.1, 0.9, 1)', offset: 0.6 },
249
+ { transform: 'scale3d(0.97, 1.03, 1)', offset: 0.8 },
250
+ { transform: 'scale3d(1, 1, 1)' },
251
+ ];
252
+ default:
253
+ return [{ opacity: 0, transform: 'scale(0.3)' }, { opacity: 1, transform: 'scale(1)' }];
254
+ }
255
+ }
256
+ const DEFAULT_PRESET = { 'bounce-in': 'bouncy', pop: 'wobbly', drop: 'bouncy' };
257
+ function defineSpring(tag = 'usa-spring') {
258
+ return defineElement(tag, (Base) => class UsaSpring extends Base {
259
+ constructor() {
260
+ super(...arguments);
261
+ this._anim = null;
262
+ }
263
+ static get observedAttributes() {
264
+ return ['effect', 'trigger', 'repeat'];
265
+ }
266
+ get effect() {
267
+ return this.str('effect', 'bounce-in');
268
+ }
269
+ set effect(v) {
270
+ this.setAttribute('effect', v);
271
+ }
272
+ config() {
273
+ if (this.hasAttribute('stiffness') || this.hasAttribute('damping') || this.hasAttribute('mass'))
274
+ return { stiffness: this.num('stiffness', 170), damping: this.num('damping', 26), mass: this.num('mass', 1) };
275
+ return this.str('preset', DEFAULT_PRESET[this.effect] || 'wobbly');
276
+ }
277
+ mount() {
278
+ const trigger = this.str('trigger', 'view');
279
+ const entrance = ENTRANCE.has(this.effect);
280
+ if (trigger === 'view') {
281
+ if (entrance)
282
+ this.setAttribute('data-state', 'hidden');
283
+ this.inView((visible) => {
284
+ if (visible)
285
+ this.play();
286
+ else if (this.flag('repeat') && entrance)
287
+ this.reset();
288
+ }, { threshold: 0.15 });
289
+ }
290
+ else {
291
+ if (trigger === 'hover')
292
+ this.listen(this, 'pointerenter', () => this.play());
293
+ if (trigger === 'click') {
294
+ this.listen(this, 'click', () => this.play());
295
+ this.listen(this, 'keydown', (e) => (e.key === 'Enter' || e.key === ' ') && !e.repeat && this.play());
296
+ }
297
+ }
298
+ }
299
+ unmount() {
300
+ this._anim?.cancel();
301
+ this._anim = null;
302
+ }
303
+ reset() {
304
+ this._anim?.cancel();
305
+ this._anim = null;
306
+ if (ENTRANCE.has(this.effect))
307
+ this.setAttribute('data-state', 'hidden');
308
+ }
309
+ async play() {
310
+ const effect = this.effect;
311
+ const reduced = this.reduced;
312
+ this._anim?.cancel();
313
+ this.setAttribute('data-state', 'playing');
314
+ const frames = springEffectKeyframes(effect, reduced);
315
+ const timing = ENTRANCE.has(effect) && !reduced
316
+ ? springEasing(this.config())
317
+ : { duration: reduced ? 250 : this.num('duration', 900), easing: 'ease-out' };
318
+ const a = this.motion(this, frames, { ...timing, delay: this.num('delay', 0), fill: 'backwards' });
319
+ this._anim = a;
320
+ if (a) {
321
+ try {
322
+ await a.finished;
323
+ }
324
+ catch {
325
+ return;
326
+ }
327
+ if (this._anim !== a)
328
+ return;
329
+ }
330
+ this._anim = null;
331
+ this.setAttribute('data-state', 'done');
332
+ this.emit('complete', { effect });
333
+ }
334
+ }, { id: 'spring', text: css$2 });
335
+ }
336
+
337
+ var css$1 = "usa-draggable{display:inline-block;touch-action:none;user-select:none;-webkit-user-select:none;cursor:grab;will-change:transform;-webkit-tap-highlight-color:transparent}usa-draggable[axis=\"x\"]{touch-action:pan-y}usa-draggable[axis=\"y\"]{touch-action:pan-x}usa-draggable[block]{display:block}usa-draggable[data-dragging]{cursor:grabbing}usa-draggable[disabled]{cursor:default}usa-draggable:focus-visible{outline:2px solid var(--usa-accent,#7c5cff);outline-offset:3px}";
338
+
339
+ const parseSnap = (s) => {
340
+ if (!s.trim())
341
+ return null;
342
+ const parts = s.split(',').map((p) => Number(p.trim())).filter((n) => Number.isFinite(n));
343
+ if (!parts.length)
344
+ return null;
345
+ return s.includes(',') ? parts : parts[0];
346
+ };
347
+ function defineDraggable(tag = 'usa-draggable') {
348
+ return defineElement(tag, (Base) => class UsaDraggable extends Base {
349
+ constructor() {
350
+ super(...arguments);
351
+ this._x = 0;
352
+ this._y = 0;
353
+ this._drag = null;
354
+ }
355
+ static get observedAttributes() {
356
+ return ['axis', 'disabled', 'preset'];
357
+ }
358
+ get x() {
359
+ return this._x;
360
+ }
361
+ get y() {
362
+ return this._y;
363
+ }
364
+ get dragging() {
365
+ return !!this._drag;
366
+ }
367
+ render() {
368
+ this.style.transform = `translate3d(${this._x}px, ${this._y}px, 0)`;
369
+ this.style.setProperty('--usa-drag-x', `${this._x}px`);
370
+ this.style.setProperty('--usa-drag-y', `${this._y}px`);
371
+ }
372
+ axis() {
373
+ return this.str('axis', 'both');
374
+ }
375
+ /** Bounds relative to the origin, from the parent box. */
376
+ limits() {
377
+ if (this.str('bounds') !== 'parent' || !this.parentElement)
378
+ return null;
379
+ const p = this.parentElement.getBoundingClientRect();
380
+ const r = this.getBoundingClientRect();
381
+ const ox = r.left - this._x;
382
+ const oy = r.top - this._y;
383
+ return { minX: p.left - ox, maxX: p.right - ox - r.width, minY: p.top - oy, maxY: p.bottom - oy - r.height };
384
+ }
385
+ mount() {
386
+ let settled = 0;
387
+ const rest = () => {
388
+ if (++settled >= 2) {
389
+ settled = 0;
390
+ this.removeAttribute('data-moving');
391
+ this.emit('settle', { x: this._x, y: this._y });
392
+ }
393
+ };
394
+ const spring = this.str('preset', 'wobbly');
395
+ this._sx = createSpring({ value: this._x, spring, onUpdate: (v) => ((this._x = v), this.render()), onRest: rest });
396
+ this._sy = createSpring({ value: this._y, spring, onUpdate: (v) => ((this._y = v), this.render()), onRest: rest });
397
+ if (!this.hasAttribute('tabindex'))
398
+ this.tabIndex = 0;
399
+ this.setAttribute('aria-roledescription', 'draggable');
400
+ this.listen(this, 'pointerdown', (e) => this.start(e));
401
+ this.listen(this, 'pointermove', (e) => this.move(e));
402
+ this.listen(this, 'pointerup', (e) => this.end(e));
403
+ this.listen(this, 'pointercancel', (e) => this.end(e));
404
+ this.listen(this, 'keydown', (e) => this.key(e));
405
+ this.render();
406
+ }
407
+ unmount() {
408
+ this._sx?.stop();
409
+ this._sy?.stop();
410
+ this._drag = null;
411
+ }
412
+ start(e) {
413
+ if (this.flag('disabled') || (e.pointerType === 'mouse' && e.button !== 0))
414
+ return;
415
+ this._sx.stop();
416
+ this._sy.stop();
417
+ this._drag = { id: e.pointerId, px: e.clientX, py: e.clientY, ox: this._x, oy: this._y, samples: [[e.clientX, e.clientY, typeof e.timeStamp === 'number' ? e.timeStamp : Date.now()]] };
418
+ try {
419
+ this.setPointerCapture?.(e.pointerId);
420
+ }
421
+ catch {
422
+ /* synthetic events */
423
+ }
424
+ this.setAttribute('data-dragging', '');
425
+ this.emit('drag-start', { x: this._x, y: this._y });
426
+ }
427
+ move(e) {
428
+ const d = this._drag;
429
+ if (!d || e.pointerId !== d.id)
430
+ return;
431
+ const axis = this.axis();
432
+ let x = axis === 'y' ? d.ox : d.ox + e.clientX - d.px;
433
+ let y = axis === 'x' ? d.oy : d.oy + e.clientY - d.py;
434
+ const b = this.limits();
435
+ if (b) {
436
+ const band = (v, lo, hi, dim) => (v < lo ? lo + rubberBand(v - lo, dim) : v > hi ? hi + rubberBand(v - hi, dim) : v);
437
+ x = band(x, b.minX, b.maxX, 200);
438
+ y = band(y, b.minY, b.maxY, 200);
439
+ }
440
+ this._x = x;
441
+ this._y = y;
442
+ d.samples.push([e.clientX, e.clientY, typeof e.timeStamp === 'number' ? e.timeStamp : Date.now()]);
443
+ if (d.samples.length > 6)
444
+ d.samples.shift();
445
+ this.render();
446
+ this.emit('drag', { x, y });
447
+ }
448
+ velocity() {
449
+ const s = this._drag?.samples || [];
450
+ if (s.length < 2)
451
+ return [0, 0];
452
+ const a = s[0];
453
+ const b = s[s.length - 1];
454
+ const dt = (b[2] - a[2]) / 1000;
455
+ if (dt <= 0 || dt > 0.3)
456
+ return [0, 0];
457
+ return [(b[0] - a[0]) / dt, (b[1] - a[1]) / dt];
458
+ }
459
+ end(e) {
460
+ const d = this._drag;
461
+ if (!d || e.pointerId !== d.id)
462
+ return;
463
+ let [vx, vy] = this.velocity();
464
+ const axis = this.axis();
465
+ if (axis === 'y')
466
+ vx = 0;
467
+ if (axis === 'x')
468
+ vy = 0;
469
+ this._drag = null;
470
+ this.removeAttribute('data-dragging');
471
+ let tx = this._x;
472
+ let ty = this._y;
473
+ if (this.flag('spring-back')) {
474
+ tx = 0;
475
+ ty = 0;
476
+ }
477
+ else {
478
+ if (this.flag('inertia') && !this.reduced) {
479
+ tx = projectInertia(tx, vx);
480
+ ty = projectInertia(ty, vy);
481
+ }
482
+ [tx, ty] = this.constrain(tx, ty);
483
+ }
484
+ this.emit('drag-end', { x: tx, y: ty, vx, vy });
485
+ this.go(tx, ty, vx, vy);
486
+ }
487
+ constrain(x, y) {
488
+ const snap = parseSnap(this.str('snap'));
489
+ let tx = snapTo(x, snap);
490
+ let ty = snapTo(y, snap);
491
+ const b = this.limits();
492
+ if (b) {
493
+ tx = clamp(tx, b.minX, Math.max(b.minX, b.maxX));
494
+ ty = clamp(ty, b.minY, Math.max(b.minY, b.maxY));
495
+ }
496
+ const axis = this.axis();
497
+ return [axis === 'y' ? 0 : tx, axis === 'x' ? 0 : ty];
498
+ }
499
+ go(x, y, vx = 0, vy = 0) {
500
+ this.setAttribute('data-moving', '');
501
+ this._sx.set(x, vx);
502
+ this._sy.set(y, vy);
503
+ }
504
+ key(e) {
505
+ if (this.flag('disabled'))
506
+ return;
507
+ const step = this.num('step', 16);
508
+ const snap = parseSnap(this.str('snap'));
509
+ const s = typeof snap === 'number' ? snap : step;
510
+ const map = { ArrowLeft: [-s, 0], ArrowRight: [s, 0], ArrowUp: [0, -s], ArrowDown: [0, s] };
511
+ if (e.key === 'Home' || e.key === 'Escape') {
512
+ e.preventDefault();
513
+ this.reset();
514
+ return;
515
+ }
516
+ const m = map[e.key];
517
+ if (!m)
518
+ return;
519
+ e.preventDefault();
520
+ const [tx, ty] = this.flag('spring-back') ? [this._sx.target + m[0], this._sy.target + m[1]] : this.constrain(this._sx.target + m[0], this._sy.target + m[1]);
521
+ this.go(tx, ty);
522
+ }
523
+ moveTo(x, y, animate = true) {
524
+ if (!animate) {
525
+ this._sx.jump(x);
526
+ this._sy.jump(y);
527
+ return;
528
+ }
529
+ this.go(x, y);
530
+ }
531
+ reset() {
532
+ this.go(0, 0);
533
+ }
534
+ }, { id: 'draggable', text: css$1 });
535
+ }
536
+
537
+ var css = "usa-overscroll{display:block;overflow:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}usa-overscroll[axis=\"x\"]{overflow-y:hidden}usa-overscroll>*{transform:translate3d(0,var(--usa-overscroll,0px),0)}usa-overscroll[axis=\"x\"]>*{transform:translate3d(var(--usa-overscroll,0px),0,0)}usa-overscroll[data-stretched]>*{will-change:transform}";
538
+
539
+ function defineOverscroll(tag = 'usa-overscroll') {
540
+ return defineElement(tag, (Base) => class UsaOverscroll extends Base {
541
+ constructor() {
542
+ super(...arguments);
543
+ this._off = 0;
544
+ }
545
+ static get observedAttributes() {
546
+ return ['axis', 'disabled'];
547
+ }
548
+ get offset() {
549
+ return this._off;
550
+ }
551
+ set(v) {
552
+ this._off = v;
553
+ this.style.setProperty('--usa-overscroll', `${v}px`);
554
+ this.toggleAttribute('data-stretched', Math.abs(v) > 0.5);
555
+ }
556
+ edge(delta) {
557
+ const x = this.str('axis', 'y') === 'x';
558
+ const pos = x ? this.scrollLeft : this.scrollTop;
559
+ const max = (x ? this.scrollWidth - this.clientWidth : this.scrollHeight - this.clientHeight) - 1;
560
+ return (delta < 0 && pos <= 0) || (delta > 0 && pos >= max);
561
+ }
562
+ stretch(raw) {
563
+ const max = this.num('max', 120);
564
+ this.set(Math.max(-max, Math.min(max, rubberBand(raw, max * 2.5))));
565
+ }
566
+ mount() {
567
+ this._spring = createSpring({ spring: this.str('preset', 'default'), onUpdate: (v) => this.set(v) });
568
+ const x = this.str('axis', 'y') === 'x';
569
+ const off = () => this.flag('disabled') || this.reduced;
570
+ // Wheel / trackpad: accumulate past the edge, spring back when it stops.
571
+ let pull = 0;
572
+ let timer;
573
+ this.listen(this, 'wheel', (e) => {
574
+ const d = x ? e.deltaX || e.deltaY : e.deltaY;
575
+ if (off() || !d || !this.edge(d))
576
+ return;
577
+ this._spring.stop();
578
+ pull -= d;
579
+ this.stretch(pull);
580
+ clearTimeout(timer);
581
+ timer = setTimeout(() => {
582
+ pull = 0;
583
+ this._spring.jump(this._off);
584
+ this._spring.set(0);
585
+ }, 140);
586
+ }, { passive: true });
587
+ this.onCleanup(() => clearTimeout(timer));
588
+ // Touch: rubber-band while the finger pulls past the edge.
589
+ let start = 0;
590
+ let active = false;
591
+ this.listen(this, 'touchstart', (e) => {
592
+ if (off())
593
+ return;
594
+ const t = e.touches[0];
595
+ start = x ? t.clientX : t.clientY;
596
+ active = false;
597
+ this._spring.stop();
598
+ }, { passive: true });
599
+ this.listen(this, 'touchmove', (e) => {
600
+ if (off())
601
+ return;
602
+ const t = e.touches[0];
603
+ const dist = (x ? t.clientX : t.clientY) - start;
604
+ if (!active && dist !== 0 && this.edge(-dist))
605
+ active = true;
606
+ if (!active)
607
+ return;
608
+ if (e.cancelable)
609
+ e.preventDefault();
610
+ this.stretch(dist);
611
+ }, { passive: false });
612
+ const release = () => {
613
+ if (!active)
614
+ return;
615
+ active = false;
616
+ this._spring.jump(this._off);
617
+ this._spring.set(0);
618
+ };
619
+ this.listen(this, 'touchend', release);
620
+ this.listen(this, 'touchcancel', release);
621
+ }
622
+ unmount() {
623
+ this._spring?.stop();
624
+ this.set(0);
625
+ }
626
+ }, { id: 'overscroll', text: css });
627
+ }
628
+
629
+ /**
630
+ * use-scroll-animate/components/physics — spring & bounce physics (v2.3).
631
+ * `<usa-spring>` (bounce-in, pop, drop, jelly, rubber-band), `<usa-draggable>`
632
+ * (spring-back, inertia, snap) and `<usa-overscroll>` (elastic edges), plus
633
+ * the spring core: `spring()`, `springEasing()`, `createSpring()`,
634
+ * `SPRING_PRESETS`, `projectInertia()`, `snapTo()`, `rubberBand()`.
635
+ */
636
+ /** Register every component of this category under its default tag. */
637
+ function definePhysicsComponents() {
638
+ defineSpring();
639
+ defineDraggable();
640
+ defineOverscroll();
641
+ }
642
+
643
+ export { SPRING_EFFECTS, SPRING_PRESETS, createSpring, defineDraggable, defineOverscroll, definePhysicsComponents, defineSpring, linearEasing, prefersReducedMotion, projectInertia, resolveSpring, rubberBand, snapTo, spring, springEasing, springEffectKeyframes, springSamples, stepSpring, supportsLinearEasing };
644
+ //# sourceMappingURL=physics.js.map