angular-movement 0.0.2 → 0.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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isPlatformBrowser, DOCUMENT } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { InjectionToken, inject, PLATFORM_ID, Injectable, input, ElementRef, computed, effect, forwardRef, Directive, afterEveryRender, NgZone, signal, ViewContainerRef, TemplateRef, makeEnvironmentProviders } from '@angular/core';
|
|
3
|
+
import { InjectionToken, inject, PLATFORM_ID, Injectable, input, ElementRef, computed, effect, forwardRef, Directive, afterEveryRender, NgZone, signal, ViewContainerRef, TemplateRef, Renderer2, makeEnvironmentProviders } from '@angular/core';
|
|
4
4
|
|
|
5
5
|
const MOVEMENT_DEFAULTS = {
|
|
6
6
|
duration: 300,
|
|
@@ -51,6 +51,9 @@ function getInterpolated(arr, i1, i2, p) {
|
|
|
51
51
|
return undefined;
|
|
52
52
|
const v1 = arr[Math.min(i1, arr.length - 1)];
|
|
53
53
|
const v2 = arr[Math.min(i2, arr.length - 1)];
|
|
54
|
+
if (typeof v1 === 'string' || typeof v2 === 'string') {
|
|
55
|
+
return p >= 1 ? v2 : v1;
|
|
56
|
+
}
|
|
54
57
|
return v1 + (v2 - v1) * p;
|
|
55
58
|
}
|
|
56
59
|
const KNOWN_KEYS = new Set([
|
|
@@ -69,36 +72,36 @@ function buildKeyframe(frames, getVal) {
|
|
|
69
72
|
const keyframe = {};
|
|
70
73
|
const opacity = getVal(frames.opacity);
|
|
71
74
|
if (opacity !== undefined) {
|
|
72
|
-
keyframe.opacity = opacity;
|
|
75
|
+
keyframe.opacity = Number(opacity);
|
|
73
76
|
}
|
|
74
77
|
const x = getVal(frames.x);
|
|
75
78
|
const y = getVal(frames.y);
|
|
76
79
|
if (x !== undefined || y !== undefined) {
|
|
77
|
-
keyframe.translate = `${x ?? 0}px ${y ?? 0}px`;
|
|
80
|
+
keyframe.translate = `${Number(x ?? 0)}px ${Number(y ?? 0)}px`;
|
|
78
81
|
}
|
|
79
82
|
const scale = getVal(frames.scale);
|
|
80
83
|
if (scale !== undefined) {
|
|
81
|
-
keyframe.scale = `${scale}`;
|
|
84
|
+
keyframe.scale = `${Number(scale)}`;
|
|
82
85
|
}
|
|
83
86
|
else {
|
|
84
87
|
const scaleX = getVal(frames.scaleX);
|
|
85
88
|
const scaleY = getVal(frames.scaleY);
|
|
86
89
|
if (scaleX !== undefined || scaleY !== undefined) {
|
|
87
|
-
keyframe.scale = `${scaleX ?? 1} ${scaleY ?? 1}`;
|
|
90
|
+
keyframe.scale = `${Number(scaleX ?? 1)} ${Number(scaleY ?? 1)}`;
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
const rotate = getVal(frames.rotate);
|
|
91
94
|
if (rotate !== undefined) {
|
|
92
|
-
keyframe.rotate = `${rotate}deg`;
|
|
95
|
+
keyframe.rotate = `${Number(rotate)}deg`;
|
|
93
96
|
}
|
|
94
97
|
const blur = getVal(frames.blur);
|
|
95
98
|
if (blur !== undefined) {
|
|
96
|
-
keyframe.filter = `blur(${blur}px)`;
|
|
99
|
+
keyframe.filter = `blur(${Number(blur)}px)`;
|
|
97
100
|
}
|
|
98
101
|
const rotateX = getVal(frames.rotateX);
|
|
99
102
|
const rotateY = getVal(frames.rotateY);
|
|
100
103
|
if (rotateX !== undefined || rotateY !== undefined) {
|
|
101
|
-
keyframe.transform = `perspective(${DEFAULT_PERSPECTIVE}) rotateX(${rotateX ?? 0}deg) rotateY(${rotateY ?? 0}deg)`;
|
|
104
|
+
keyframe.transform = `perspective(${DEFAULT_PERSPECTIVE}) rotateX(${Number(rotateX ?? 0)}deg) rotateY(${Number(rotateY ?? 0)}deg)`;
|
|
102
105
|
}
|
|
103
106
|
// Passthrough arbitrary properties for WAAPI (e.g. strokeDashoffset)
|
|
104
107
|
for (const key in frames) {
|
|
@@ -241,6 +244,89 @@ const MOVE_PRESETS = {
|
|
|
241
244
|
leave: { scale: [1, 0.95, 1] },
|
|
242
245
|
loop: { scale: [1, 1.05, 1] },
|
|
243
246
|
},
|
|
247
|
+
shake: {
|
|
248
|
+
enter: { opacity: DEFAULT_FADE_OPACITY, x: [0, -10, 10, -10, 10, -5, 5, -5, 5, 0] },
|
|
249
|
+
leave: { opacity: DEFAULT_LEAVE_OPACITY, x: [0, 10, -10, 10, -10, 5, -5, 5, -5, 0] },
|
|
250
|
+
},
|
|
251
|
+
swing: {
|
|
252
|
+
enter: { opacity: DEFAULT_FADE_OPACITY, rotate: [0, 15, -10, 5, -5, 0] },
|
|
253
|
+
leave: { opacity: DEFAULT_LEAVE_OPACITY, rotate: [0, -15, 10, -5, 5, 0] },
|
|
254
|
+
},
|
|
255
|
+
wobble: {
|
|
256
|
+
enter: {
|
|
257
|
+
opacity: DEFAULT_FADE_OPACITY,
|
|
258
|
+
x: [0, -25, 20, -15, 10, -5, 0],
|
|
259
|
+
rotate: [0, -5, 3, -3, 2, -1, 0],
|
|
260
|
+
},
|
|
261
|
+
leave: {
|
|
262
|
+
opacity: DEFAULT_LEAVE_OPACITY,
|
|
263
|
+
x: [0, 25, -20, 15, -10, 5, 0],
|
|
264
|
+
rotate: [0, 5, -3, 3, -2, 1, 0],
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
'rubber-band': {
|
|
268
|
+
enter: {
|
|
269
|
+
opacity: DEFAULT_FADE_OPACITY,
|
|
270
|
+
scaleX: [1, 1.25, 0.75, 1.15, 0.95, 1.05, 1],
|
|
271
|
+
scaleY: [1, 0.75, 1.25, 0.85, 1.05, 0.95, 1],
|
|
272
|
+
},
|
|
273
|
+
leave: {
|
|
274
|
+
opacity: DEFAULT_LEAVE_OPACITY,
|
|
275
|
+
scaleX: [1, 1.25, 0.75, 1.15, 0.95, 1.05, 1],
|
|
276
|
+
scaleY: [1, 0.75, 1.25, 0.85, 1.05, 0.95, 1],
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
'heart-beat': {
|
|
280
|
+
enter: { opacity: DEFAULT_FADE_OPACITY, scale: [1, 1.3, 1, 1.3, 1] },
|
|
281
|
+
leave: { opacity: DEFAULT_LEAVE_OPACITY, scale: [1, 1.3, 1, 1.3, 1] },
|
|
282
|
+
loop: { scale: [1, 1.3, 1, 1.3, 1] },
|
|
283
|
+
},
|
|
284
|
+
tada: {
|
|
285
|
+
enter: {
|
|
286
|
+
opacity: DEFAULT_FADE_OPACITY,
|
|
287
|
+
scale: [1, 0.9, 1.1, 1.1, 1.1, 1],
|
|
288
|
+
rotate: [0, -3, 3, -3, 3, 0],
|
|
289
|
+
},
|
|
290
|
+
leave: {
|
|
291
|
+
opacity: DEFAULT_LEAVE_OPACITY,
|
|
292
|
+
scale: [1, 0.9, 1.1, 1.1, 1.1, 1],
|
|
293
|
+
rotate: [0, 3, -3, 3, -3, 0],
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
jello: {
|
|
297
|
+
enter: {
|
|
298
|
+
opacity: DEFAULT_FADE_OPACITY,
|
|
299
|
+
scaleX: [1, 1.25, 0.75, 1.15, 0.95, 1.05, 1],
|
|
300
|
+
scaleY: [1, 0.75, 1.25, 0.85, 1.05, 0.95, 1],
|
|
301
|
+
},
|
|
302
|
+
leave: {
|
|
303
|
+
opacity: DEFAULT_LEAVE_OPACITY,
|
|
304
|
+
scaleX: [1, 1.25, 0.75, 1.15, 0.95, 1.05, 1],
|
|
305
|
+
scaleY: [1, 0.75, 1.25, 0.85, 1.05, 0.95, 1],
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
'light-speed': {
|
|
309
|
+
enter: { opacity: [0, 1], x: [200, 0], scaleX: [0, 1] },
|
|
310
|
+
leave: { opacity: [1, 0], x: [0, 200], scaleX: [1, 0] },
|
|
311
|
+
},
|
|
312
|
+
'roll-in': {
|
|
313
|
+
enter: { opacity: [0, 1], x: [-100, 0], rotate: [-120, 0] },
|
|
314
|
+
leave: { opacity: [1, 0], x: [0, 100], rotate: [0, 120] },
|
|
315
|
+
},
|
|
316
|
+
'icon-draw': {
|
|
317
|
+
enter: { pathLength: [0, 1], opacity: [0, 1] },
|
|
318
|
+
leave: { pathLength: [1, 0], opacity: [1, 0] },
|
|
319
|
+
},
|
|
320
|
+
'icon-pulse': {
|
|
321
|
+
enter: { scale: [1, 1.08, 1], opacity: [1, 0.85, 1] },
|
|
322
|
+
leave: { scale: [1, 0.92, 1], opacity: [1, 1, 1] },
|
|
323
|
+
loop: { scale: [1, 1.08, 1], opacity: [1, 0.85, 1] },
|
|
324
|
+
},
|
|
325
|
+
'icon-bounce': {
|
|
326
|
+
enter: { y: [0, -3, 0], opacity: [1, 1, 1] },
|
|
327
|
+
leave: { y: [0, 0, 0], opacity: [1, 1, 1] },
|
|
328
|
+
loop: { y: [0, -3, 0] },
|
|
329
|
+
},
|
|
244
330
|
none: {
|
|
245
331
|
enter: { opacity: [1, 1] },
|
|
246
332
|
leave: { opacity: [1, 1] },
|
|
@@ -310,6 +396,63 @@ function applyInitialStyles(el, frames) {
|
|
|
310
396
|
function clearInitialStyles(el) {
|
|
311
397
|
clearComposedStyle(el);
|
|
312
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* Validates MoveSpring configuration and returns sanitized values.
|
|
401
|
+
* Warns in development mode for invalid values.
|
|
402
|
+
*/
|
|
403
|
+
function validateSpring(spring) {
|
|
404
|
+
if (!spring)
|
|
405
|
+
return undefined;
|
|
406
|
+
const validated = {};
|
|
407
|
+
if (spring.stiffness !== undefined) {
|
|
408
|
+
if (spring.stiffness <= 0 && typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
409
|
+
console.warn('[Movement] Spring stiffness must be > 0. Using default.');
|
|
410
|
+
}
|
|
411
|
+
validated.stiffness = spring.stiffness > 0 ? spring.stiffness : 100;
|
|
412
|
+
}
|
|
413
|
+
if (spring.damping !== undefined) {
|
|
414
|
+
if (spring.damping < 0 && typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
415
|
+
console.warn('[Movement] Spring damping must be >= 0. Using default.');
|
|
416
|
+
}
|
|
417
|
+
validated.damping = spring.damping >= 0 ? spring.damping : 10;
|
|
418
|
+
}
|
|
419
|
+
if (spring.mass !== undefined) {
|
|
420
|
+
if (spring.mass <= 0 && typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
421
|
+
console.warn('[Movement] Spring mass must be > 0. Using default.');
|
|
422
|
+
}
|
|
423
|
+
validated.mass = spring.mass > 0 ? spring.mass : 1;
|
|
424
|
+
}
|
|
425
|
+
if (spring.velocity !== undefined) {
|
|
426
|
+
validated.velocity = spring.velocity;
|
|
427
|
+
}
|
|
428
|
+
return validated;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Validates scroll offset string format "elFraction viewFraction".
|
|
432
|
+
* Returns true if valid, warns in dev mode if invalid.
|
|
433
|
+
*/
|
|
434
|
+
function isValidScrollOffset(offset) {
|
|
435
|
+
const parts = offset.split(' ').map(parseFloat);
|
|
436
|
+
if (parts.length !== 2 || parts.some(Number.isNaN)) {
|
|
437
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
438
|
+
console.warn(`[Movement] Invalid scroll offset: "${offset}". Expected format "elFraction viewFraction" (e.g. "0 1").`);
|
|
439
|
+
}
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
return true;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Validates drag elastic factor. Must be between 0 and 1.
|
|
446
|
+
*/
|
|
447
|
+
function validateDragElastic(elastic) {
|
|
448
|
+
if (elastic < 0 || elastic > 1) {
|
|
449
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
450
|
+
console.warn(`[Movement] Drag elastic must be between 0 and 1. Got ${elastic}. Clamping to range.`);
|
|
451
|
+
}
|
|
452
|
+
return Math.max(0, Math.min(1, elastic));
|
|
453
|
+
}
|
|
454
|
+
return elastic;
|
|
455
|
+
}
|
|
313
456
|
|
|
314
457
|
class WaapiPlayer {
|
|
315
458
|
#animation = null;
|
|
@@ -323,7 +466,9 @@ class WaapiPlayer {
|
|
|
323
466
|
onDone?.();
|
|
324
467
|
return;
|
|
325
468
|
}
|
|
326
|
-
const keyframes =
|
|
469
|
+
const keyframes = Array.isArray(frames)
|
|
470
|
+
? frames
|
|
471
|
+
: this.#toWAAPIKeyframes(frames);
|
|
327
472
|
const iterations = config.iterations ?? 1;
|
|
328
473
|
this.#animation = host.animate(keyframes, {
|
|
329
474
|
duration: config.duration,
|
|
@@ -512,24 +657,129 @@ class SpringPlayer {
|
|
|
512
657
|
}
|
|
513
658
|
}
|
|
514
659
|
|
|
660
|
+
function isPropertyTransition(value) {
|
|
661
|
+
return (typeof value === 'object' &&
|
|
662
|
+
value !== null &&
|
|
663
|
+
('duration' in value || 'easing' in value || 'delay' in value));
|
|
664
|
+
}
|
|
665
|
+
function composeTransitionKeyframes(frames, transition, baseConfig) {
|
|
666
|
+
const globalDuration = transition.duration ?? baseConfig.duration;
|
|
667
|
+
const globalEasing = transition.easing ?? baseConfig.easing;
|
|
668
|
+
const globalDelay = transition.delay ?? baseConfig.delay;
|
|
669
|
+
const propNames = Object.keys(frames).filter((k) => k !== 'transition');
|
|
670
|
+
if (propNames.length === 0)
|
|
671
|
+
return null;
|
|
672
|
+
const timings = propNames.map((prop) => {
|
|
673
|
+
const pt = transition[prop];
|
|
674
|
+
const parsed = isPropertyTransition(pt) ? pt : {};
|
|
675
|
+
return {
|
|
676
|
+
prop,
|
|
677
|
+
duration: parsed.duration ?? globalDuration,
|
|
678
|
+
easing: parsed.easing ?? globalEasing,
|
|
679
|
+
delay: parsed.delay ?? globalDelay,
|
|
680
|
+
values: frames[prop].map((v) => Number(v)),
|
|
681
|
+
};
|
|
682
|
+
});
|
|
683
|
+
const allSame = timings.every((t) => t.duration === timings[0].duration &&
|
|
684
|
+
t.easing === timings[0].easing &&
|
|
685
|
+
t.delay === timings[0].delay);
|
|
686
|
+
if (allSame) {
|
|
687
|
+
return null;
|
|
688
|
+
}
|
|
689
|
+
const uniqueEasings = new Set(timings.map((t) => t.easing));
|
|
690
|
+
let finalEasing = timings[0].easing;
|
|
691
|
+
if (uniqueEasings.size > 1) {
|
|
692
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
693
|
+
console.warn('[Movement] Per-property easing differences are not supported yet. Using global easing.');
|
|
694
|
+
}
|
|
695
|
+
finalEasing = globalEasing;
|
|
696
|
+
}
|
|
697
|
+
const totalDuration = Math.max(...timings.map((t) => t.delay + t.duration));
|
|
698
|
+
const totalDelay = Math.min(...timings.map((t) => t.delay));
|
|
699
|
+
// Collect all keyframe times
|
|
700
|
+
const timeSet = new Set();
|
|
701
|
+
for (const t of timings) {
|
|
702
|
+
const n = t.values.length;
|
|
703
|
+
for (let i = 0; i < n; i++) {
|
|
704
|
+
const time = t.delay + (t.duration * i) / Math.max(1, n - 1);
|
|
705
|
+
timeSet.add(time);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
const sortedTimes = Array.from(timeSet).sort((a, b) => a - b);
|
|
709
|
+
const resultKeyframes = [];
|
|
710
|
+
for (const time of sortedTimes) {
|
|
711
|
+
const offset = totalDuration > totalDelay ? (time - totalDelay) / (totalDuration - totalDelay) : 0;
|
|
712
|
+
const kf = { offset };
|
|
713
|
+
for (const t of timings) {
|
|
714
|
+
const localTime = time - t.delay;
|
|
715
|
+
const n = t.values.length;
|
|
716
|
+
if (n === 1) {
|
|
717
|
+
kf[t.prop] = t.values[0];
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
if (localTime <= 0) {
|
|
721
|
+
kf[t.prop] = t.values[0];
|
|
722
|
+
}
|
|
723
|
+
else if (localTime >= t.duration) {
|
|
724
|
+
kf[t.prop] = t.values[n - 1];
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
const progress = t.duration > 0 ? localTime / t.duration : 0;
|
|
728
|
+
const maxIdx = n - 1;
|
|
729
|
+
const idx = progress * maxIdx;
|
|
730
|
+
const i1 = Math.floor(idx);
|
|
731
|
+
const i2 = Math.min(Math.ceil(idx), maxIdx);
|
|
732
|
+
const p = idx - i1;
|
|
733
|
+
const v1 = t.values[i1];
|
|
734
|
+
const v2 = t.values[i2];
|
|
735
|
+
kf[t.prop] = v1 + (v2 - v1) * p;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
resultKeyframes.push(kf);
|
|
739
|
+
}
|
|
740
|
+
return {
|
|
741
|
+
keyframes: resultKeyframes,
|
|
742
|
+
duration: totalDuration,
|
|
743
|
+
easing: finalEasing,
|
|
744
|
+
delay: totalDelay,
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
|
|
515
748
|
class AnimationEngine {
|
|
516
749
|
#platformId = inject(PLATFORM_ID);
|
|
517
750
|
#defaults = inject(MOVEMENT_CONFIG);
|
|
518
|
-
play(host,
|
|
751
|
+
play(host, rawFrames, options = {}) {
|
|
519
752
|
if (!isPlatformBrowser(this.#platformId)) {
|
|
520
753
|
options.onDone?.();
|
|
521
754
|
return null;
|
|
522
755
|
}
|
|
756
|
+
const frames = this.#resolveSvgFrames(host, rawFrames);
|
|
523
757
|
if (options.disabled) {
|
|
758
|
+
this.#prepareSvgPathDraw(host, frames);
|
|
524
759
|
this.#applyFinalStyles(host, frames);
|
|
525
760
|
options.onDone?.();
|
|
526
761
|
return null;
|
|
527
762
|
}
|
|
763
|
+
this.#prepareSvgPathDraw(host, frames);
|
|
528
764
|
const config = options.config ?? this.#defaults;
|
|
529
|
-
const
|
|
765
|
+
const spring = validateSpring(options.spring);
|
|
766
|
+
const isSpring = spring || config.easing === 'spring';
|
|
530
767
|
const iterations = options.iterations ?? config.iterations;
|
|
768
|
+
// Per-property transitions only supported with WaapiPlayer (not spring)
|
|
769
|
+
if (options.transition && !isSpring) {
|
|
770
|
+
const resolved = composeTransitionKeyframes(frames, options.transition, config);
|
|
771
|
+
if (resolved) {
|
|
772
|
+
return new WaapiPlayer(host, resolved.keyframes, {
|
|
773
|
+
duration: resolved.duration,
|
|
774
|
+
easing: resolved.easing,
|
|
775
|
+
delay: resolved.delay,
|
|
776
|
+
disabled: false,
|
|
777
|
+
iterations,
|
|
778
|
+
}, options.onDone);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
531
781
|
if (isSpring) {
|
|
532
|
-
return new SpringPlayer(host, frames,
|
|
782
|
+
return new SpringPlayer(host, frames, spring ?? {}, options.delay ?? config.delay, iterations, options.onDone);
|
|
533
783
|
}
|
|
534
784
|
else {
|
|
535
785
|
return new WaapiPlayer(host, frames, {
|
|
@@ -544,6 +794,67 @@ class AnimationEngine {
|
|
|
544
794
|
#applyFinalStyles(host, frames) {
|
|
545
795
|
applyComposedStyle(host, composeFinalStyle(frames));
|
|
546
796
|
}
|
|
797
|
+
#resolveSvgFrames(host, frames) {
|
|
798
|
+
if (!frames.pathLength && !frames.pathOffset) {
|
|
799
|
+
return frames;
|
|
800
|
+
}
|
|
801
|
+
const L = this.#getPathLength(host);
|
|
802
|
+
const resolved = { ...frames };
|
|
803
|
+
const pValues = frames.pathLength ? frames.pathLength.map((v) => Number(v)) : [1];
|
|
804
|
+
const oValues = frames.pathOffset ? frames.pathOffset.map((v) => Number(v)) : [0];
|
|
805
|
+
const maxLen = Math.max(pValues.length, oValues.length);
|
|
806
|
+
const strokeDasharray = [];
|
|
807
|
+
const strokeDashoffset = [];
|
|
808
|
+
for (let i = 0; i < maxLen; i++) {
|
|
809
|
+
const p = pValues[Math.min(i, pValues.length - 1)];
|
|
810
|
+
const o = oValues[Math.min(i, oValues.length - 1)];
|
|
811
|
+
strokeDasharray.push(`${p * L} ${L}`);
|
|
812
|
+
strokeDashoffset.push(-o * L);
|
|
813
|
+
}
|
|
814
|
+
resolved['strokeDasharray'] = strokeDasharray;
|
|
815
|
+
resolved['strokeDashoffset'] = strokeDashoffset;
|
|
816
|
+
delete resolved['pathLength'];
|
|
817
|
+
delete resolved['pathOffset'];
|
|
818
|
+
return resolved;
|
|
819
|
+
}
|
|
820
|
+
#prepareSvgPathDraw(host, frames) {
|
|
821
|
+
const hasPathProps = frames.strokeDashoffset || frames.strokeDasharray || frames.pathLength || frames.pathOffset;
|
|
822
|
+
if (!hasPathProps || !this.#isSvgGeometryElement(host)) {
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
const styledHost = host;
|
|
826
|
+
const L = this.#getPathLength(host);
|
|
827
|
+
if (frames.strokeDasharray && frames.strokeDasharray.length > 0) {
|
|
828
|
+
styledHost.style.strokeDasharray = String(frames.strokeDasharray[0]);
|
|
829
|
+
}
|
|
830
|
+
else if (frames.strokeDashoffset || frames.pathLength || frames.pathOffset) {
|
|
831
|
+
styledHost.style.strokeDasharray = `${L}`;
|
|
832
|
+
}
|
|
833
|
+
if (frames.strokeDashoffset && frames.strokeDashoffset.length > 0) {
|
|
834
|
+
styledHost.style.strokeDashoffset = String(frames.strokeDashoffset[0]);
|
|
835
|
+
}
|
|
836
|
+
else if (frames.pathLength && frames.pathLength.length > 0) {
|
|
837
|
+
styledHost.style.strokeDashoffset = `${Number(frames.pathLength[0]) * L}`;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
#getPathLength(host) {
|
|
841
|
+
if (!this.#isSvgGeometryElement(host))
|
|
842
|
+
return 28;
|
|
843
|
+
try {
|
|
844
|
+
return host.getTotalLength() || 28;
|
|
845
|
+
}
|
|
846
|
+
catch {
|
|
847
|
+
return 28;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
#isSvgGeometryElement(host) {
|
|
851
|
+
const view = host.ownerDocument?.defaultView;
|
|
852
|
+
const SvgGeometryElement = view?.SVGGeometryElement;
|
|
853
|
+
if (typeof SvgGeometryElement === 'function' && host instanceof SvgGeometryElement) {
|
|
854
|
+
return true;
|
|
855
|
+
}
|
|
856
|
+
return typeof host.getTotalLength === 'function';
|
|
857
|
+
}
|
|
547
858
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: AnimationEngine, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
548
859
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: AnimationEngine, providedIn: 'root' });
|
|
549
860
|
}
|
|
@@ -590,7 +901,7 @@ class MoveVariantsDirective {
|
|
|
590
901
|
if (!state)
|
|
591
902
|
return;
|
|
592
903
|
this.#currentPlayer?.cancel();
|
|
593
|
-
const { spring, duration, easing, delay, ...keyframesMap } = state;
|
|
904
|
+
const { spring, duration, easing, delay, transition, ...keyframesMap } = state;
|
|
594
905
|
const keyframes = keyframesMap;
|
|
595
906
|
const staggerDelay = this.#stagger?.getDelay(this.#host.nativeElement) ?? 0;
|
|
596
907
|
const config = resolveMovementConfig(this.#defaults, {
|
|
@@ -603,6 +914,7 @@ class MoveVariantsDirective {
|
|
|
603
914
|
config,
|
|
604
915
|
spring: spring ?? this.moveSpring(),
|
|
605
916
|
disabled: config.disabled,
|
|
917
|
+
transition,
|
|
606
918
|
});
|
|
607
919
|
});
|
|
608
920
|
}
|
|
@@ -778,7 +1090,7 @@ function statesToKeyframes(from, to) {
|
|
|
778
1090
|
for (const key of Object.keys(from)) {
|
|
779
1091
|
const f = from[key];
|
|
780
1092
|
const t = to[key];
|
|
781
|
-
if (f
|
|
1093
|
+
if (typeof f === 'number' && typeof t === 'number') {
|
|
782
1094
|
result[key] = [f, t];
|
|
783
1095
|
}
|
|
784
1096
|
}
|
|
@@ -877,13 +1189,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
|
|
|
877
1189
|
}]
|
|
878
1190
|
}], propDecorators: { moveLeave: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveLeave", required: false }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }] } });
|
|
879
1191
|
|
|
1192
|
+
function optionalNumberAttribute$3(value) {
|
|
1193
|
+
if (value === undefined || value === null || value === '') {
|
|
1194
|
+
return undefined;
|
|
1195
|
+
}
|
|
1196
|
+
return Number(value);
|
|
1197
|
+
}
|
|
880
1198
|
class MoveHoverDirective {
|
|
881
1199
|
moveWhileHover = input.required(...(ngDevMode ? [{ debugName: "moveWhileHover" }] : /* istanbul ignore next */ []));
|
|
882
|
-
moveDuration = input(undefined, ...(ngDevMode ?
|
|
1200
|
+
moveDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$3 });
|
|
883
1201
|
moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
|
|
884
|
-
moveDelay = input(undefined, ...(ngDevMode ?
|
|
1202
|
+
moveDelay = input(undefined, { ...(ngDevMode ? { debugName: "moveDelay" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$3 });
|
|
885
1203
|
moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
|
|
886
1204
|
moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
|
|
1205
|
+
moveReverseDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveReverseDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$3 });
|
|
1206
|
+
moveReverseEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveReverseEasing" }] : /* istanbul ignore next */ []));
|
|
887
1207
|
#defaults = inject(MOVEMENT_CONFIG);
|
|
888
1208
|
#documentRef = inject(DOCUMENT);
|
|
889
1209
|
#host = inject((ElementRef));
|
|
@@ -928,10 +1248,22 @@ class MoveHoverDirective {
|
|
|
928
1248
|
return;
|
|
929
1249
|
let frames = resolveMoveFrames(this.moveWhileHover(), 'enter');
|
|
930
1250
|
if (reverse) {
|
|
1251
|
+
const reverseDuration = this.moveReverseDuration();
|
|
1252
|
+
if (reverseDuration === 0) {
|
|
1253
|
+
clearComposedStyle(this.#host.nativeElement, Object.keys(frames));
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
931
1256
|
frames = reverseFrames(frames);
|
|
932
1257
|
}
|
|
1258
|
+
const reverseConfig = reverse
|
|
1259
|
+
? resolveMovementConfig({ ...this.#defaults, duration: 200, easing: 'ease-out', delay: 0 }, {
|
|
1260
|
+
duration: this.moveReverseDuration() ?? this.moveDuration(),
|
|
1261
|
+
easing: this.moveReverseEasing(),
|
|
1262
|
+
delay: 0,
|
|
1263
|
+
}, isReduced)
|
|
1264
|
+
: config;
|
|
933
1265
|
this.#currentPlayer = this.#engine.play(this.#host.nativeElement, frames, {
|
|
934
|
-
config,
|
|
1266
|
+
config: reverseConfig,
|
|
935
1267
|
spring: this.moveSpring(),
|
|
936
1268
|
disabled: false,
|
|
937
1269
|
});
|
|
@@ -940,7 +1272,7 @@ class MoveHoverDirective {
|
|
|
940
1272
|
this.#currentPlayer?.cancel();
|
|
941
1273
|
}
|
|
942
1274
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveHoverDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
943
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveHoverDirective, isStandalone: true, selector: "[moveWhileHover]", inputs: { moveWhileHover: { classPropertyName: "moveWhileHover", publicName: "moveWhileHover", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "touchstart": "onTouchStart($event)", "touchend": "onTouchEnd()", "touchcancel": "onTouchEnd()" } }, ngImport: i0 });
|
|
1275
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveHoverDirective, isStandalone: true, selector: "[moveWhileHover]", inputs: { moveWhileHover: { classPropertyName: "moveWhileHover", publicName: "moveWhileHover", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null }, moveReverseDuration: { classPropertyName: "moveReverseDuration", publicName: "moveReverseDuration", isSignal: true, isRequired: false, transformFunction: null }, moveReverseEasing: { classPropertyName: "moveReverseEasing", publicName: "moveReverseEasing", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "touchstart": "onTouchStart($event)", "touchend": "onTouchEnd()", "touchcancel": "onTouchEnd()" } }, ngImport: i0 });
|
|
944
1276
|
}
|
|
945
1277
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveHoverDirective, decorators: [{
|
|
946
1278
|
type: Directive,
|
|
@@ -954,15 +1286,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
|
|
|
954
1286
|
'(touchcancel)': 'onTouchEnd()',
|
|
955
1287
|
},
|
|
956
1288
|
}]
|
|
957
|
-
}], propDecorators: { moveWhileHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveWhileHover", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }] } });
|
|
1289
|
+
}], propDecorators: { moveWhileHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveWhileHover", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }], moveReverseDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseDuration", required: false }] }], moveReverseEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseEasing", required: false }] }] } });
|
|
958
1290
|
|
|
1291
|
+
function optionalNumberAttribute$2(value) {
|
|
1292
|
+
if (value === undefined || value === null || value === '') {
|
|
1293
|
+
return undefined;
|
|
1294
|
+
}
|
|
1295
|
+
return Number(value);
|
|
1296
|
+
}
|
|
959
1297
|
class MoveTapDirective {
|
|
960
1298
|
moveWhileTap = input.required(...(ngDevMode ? [{ debugName: "moveWhileTap" }] : /* istanbul ignore next */ []));
|
|
961
|
-
moveDuration = input(undefined, ...(ngDevMode ?
|
|
1299
|
+
moveDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$2 });
|
|
962
1300
|
moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
|
|
963
|
-
moveDelay = input(undefined, ...(ngDevMode ?
|
|
1301
|
+
moveDelay = input(undefined, { ...(ngDevMode ? { debugName: "moveDelay" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$2 });
|
|
964
1302
|
moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
|
|
965
1303
|
moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
|
|
1304
|
+
moveReverseDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveReverseDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$2 });
|
|
1305
|
+
moveReverseEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveReverseEasing" }] : /* istanbul ignore next */ []));
|
|
966
1306
|
#defaults = inject(MOVEMENT_CONFIG);
|
|
967
1307
|
#documentRef = inject(DOCUMENT);
|
|
968
1308
|
#host = inject((ElementRef));
|
|
@@ -994,10 +1334,22 @@ class MoveTapDirective {
|
|
|
994
1334
|
return;
|
|
995
1335
|
let frames = resolveMoveFrames(this.moveWhileTap(), 'enter');
|
|
996
1336
|
if (reverse) {
|
|
1337
|
+
const reverseDuration = this.moveReverseDuration();
|
|
1338
|
+
if (reverseDuration === 0) {
|
|
1339
|
+
clearComposedStyle(this.#host.nativeElement, Object.keys(frames));
|
|
1340
|
+
return;
|
|
1341
|
+
}
|
|
997
1342
|
frames = reverseFrames(frames);
|
|
998
1343
|
}
|
|
1344
|
+
const reverseConfig = reverse
|
|
1345
|
+
? resolveMovementConfig({ ...this.#defaults, duration: 200, easing: 'ease-out', delay: 0 }, {
|
|
1346
|
+
duration: this.moveReverseDuration() ?? this.moveDuration(),
|
|
1347
|
+
easing: this.moveReverseEasing(),
|
|
1348
|
+
delay: 0,
|
|
1349
|
+
}, isReduced)
|
|
1350
|
+
: config;
|
|
999
1351
|
this.#currentPlayer = this.#engine.play(this.#host.nativeElement, frames, {
|
|
1000
|
-
config,
|
|
1352
|
+
config: reverseConfig,
|
|
1001
1353
|
spring: this.moveSpring(),
|
|
1002
1354
|
disabled: false,
|
|
1003
1355
|
});
|
|
@@ -1006,7 +1358,7 @@ class MoveTapDirective {
|
|
|
1006
1358
|
this.#currentPlayer?.cancel();
|
|
1007
1359
|
}
|
|
1008
1360
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTapDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1009
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveTapDirective, isStandalone: true, selector: "[moveWhileTap]", inputs: { moveWhileTap: { classPropertyName: "moveWhileTap", publicName: "moveWhileTap", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointerdown": "onPointerDown()", "pointerup": "onPointerUp()", "pointercancel": "onPointerUp()", "pointerleave": "onPointerUp()" } }, ngImport: i0 });
|
|
1361
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveTapDirective, isStandalone: true, selector: "[moveWhileTap]", inputs: { moveWhileTap: { classPropertyName: "moveWhileTap", publicName: "moveWhileTap", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null }, moveReverseDuration: { classPropertyName: "moveReverseDuration", publicName: "moveReverseDuration", isSignal: true, isRequired: false, transformFunction: null }, moveReverseEasing: { classPropertyName: "moveReverseEasing", publicName: "moveReverseEasing", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointerdown": "onPointerDown()", "pointerup": "onPointerUp()", "pointercancel": "onPointerUp()", "pointerleave": "onPointerUp()" } }, ngImport: i0 });
|
|
1010
1362
|
}
|
|
1011
1363
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTapDirective, decorators: [{
|
|
1012
1364
|
type: Directive,
|
|
@@ -1019,7 +1371,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
|
|
|
1019
1371
|
'(pointerleave)': 'onPointerUp()',
|
|
1020
1372
|
},
|
|
1021
1373
|
}]
|
|
1022
|
-
}], propDecorators: { moveWhileTap: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveWhileTap", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }] } });
|
|
1374
|
+
}], propDecorators: { moveWhileTap: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveWhileTap", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }], moveReverseDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseDuration", required: false }] }], moveReverseEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseEasing", required: false }] }] } });
|
|
1023
1375
|
|
|
1024
1376
|
class MoveStaggerDirective {
|
|
1025
1377
|
moveStagger = input.required(...(ngDevMode ? [{ debugName: "moveStagger" }] : /* istanbul ignore next */ []));
|
|
@@ -1035,9 +1387,14 @@ class MoveStaggerDirective {
|
|
|
1035
1387
|
if (!this.#children.has(el))
|
|
1036
1388
|
return 0;
|
|
1037
1389
|
const list = Array.from(this.#children).sort((a, b) => {
|
|
1038
|
-
|
|
1390
|
+
if (a === b)
|
|
1391
|
+
return 0;
|
|
1039
1392
|
const pos = a.compareDocumentPosition(b);
|
|
1040
|
-
|
|
1393
|
+
if (pos & Node.DOCUMENT_POSITION_PRECEDING)
|
|
1394
|
+
return 1;
|
|
1395
|
+
if (pos & Node.DOCUMENT_POSITION_FOLLOWING)
|
|
1396
|
+
return -1;
|
|
1397
|
+
return 0;
|
|
1041
1398
|
});
|
|
1042
1399
|
const index = list.indexOf(el);
|
|
1043
1400
|
if (index === -1)
|
|
@@ -1416,6 +1773,11 @@ class MoveScrollDirective {
|
|
|
1416
1773
|
const view = this.#documentRef.defaultView;
|
|
1417
1774
|
if (!view)
|
|
1418
1775
|
return;
|
|
1776
|
+
// Validate scroll offsets
|
|
1777
|
+
const offsets = this.moveScrollOffset();
|
|
1778
|
+
if (!isValidScrollOffset(offsets[0]) || !isValidScrollOffset(offsets[1])) {
|
|
1779
|
+
return;
|
|
1780
|
+
}
|
|
1419
1781
|
this.#player = this.#engine.play(this.#host.nativeElement, keyframes, {
|
|
1420
1782
|
config: { duration: 1000, easing: 'linear', delay: 0, disabled: false, iterations: 1 },
|
|
1421
1783
|
});
|
|
@@ -1658,7 +2020,9 @@ class MoveDragDirective {
|
|
|
1658
2020
|
return;
|
|
1659
2021
|
this.#isDragging = true;
|
|
1660
2022
|
this.#pointerId = e.pointerId;
|
|
1661
|
-
this.#host.nativeElement.setPointerCapture
|
|
2023
|
+
if (typeof this.#host.nativeElement.setPointerCapture === 'function') {
|
|
2024
|
+
this.#host.nativeElement.setPointerCapture(e.pointerId);
|
|
2025
|
+
}
|
|
1662
2026
|
this.#player?.cancel();
|
|
1663
2027
|
// read bounds cleanly before next render
|
|
1664
2028
|
this.#dragBounds = this.resolveBounds();
|
|
@@ -1679,7 +2043,9 @@ class MoveDragDirective {
|
|
|
1679
2043
|
if (!this.#isDragging || e.pointerId !== this.#pointerId)
|
|
1680
2044
|
return;
|
|
1681
2045
|
this.#isDragging = false;
|
|
1682
|
-
this.#host.nativeElement.releasePointerCapture
|
|
2046
|
+
if (typeof this.#host.nativeElement.releasePointerCapture === 'function') {
|
|
2047
|
+
this.#host.nativeElement.releasePointerCapture(e.pointerId);
|
|
2048
|
+
}
|
|
1683
2049
|
this.#pointerId = null;
|
|
1684
2050
|
this.#host.nativeElement.style.touchAction = '';
|
|
1685
2051
|
this.#host.nativeElement.style.userSelect = '';
|
|
@@ -1708,7 +2074,7 @@ class MoveDragDirective {
|
|
|
1708
2074
|
let x = this.#_x;
|
|
1709
2075
|
let y = this.#_y;
|
|
1710
2076
|
if (this.#dragBounds) {
|
|
1711
|
-
const elastic = this.moveDragElastic();
|
|
2077
|
+
const elastic = validateDragElastic(this.moveDragElastic());
|
|
1712
2078
|
if (this.#dragBounds.left !== undefined && x < this.#dragBounds.left) {
|
|
1713
2079
|
x = this.#dragBounds.left - (this.#dragBounds.left - x) * elastic;
|
|
1714
2080
|
}
|
|
@@ -1742,7 +2108,7 @@ class MoveDragDirective {
|
|
|
1742
2108
|
// Find the currently visible coordinates (which include elasticity)
|
|
1743
2109
|
let currentVisX = this.#_x;
|
|
1744
2110
|
let currentVisY = this.#_y;
|
|
1745
|
-
const elastic = this.moveDragElastic();
|
|
2111
|
+
const elastic = validateDragElastic(this.moveDragElastic());
|
|
1746
2112
|
if (this.#dragBounds.left !== undefined && this.#_x < this.#dragBounds.left) {
|
|
1747
2113
|
currentVisX = this.#dragBounds.left - (this.#dragBounds.left - this.#_x) * elastic;
|
|
1748
2114
|
}
|
|
@@ -1768,6 +2134,19 @@ class MoveDragDirective {
|
|
|
1768
2134
|
}
|
|
1769
2135
|
}
|
|
1770
2136
|
ngOnDestroy() {
|
|
2137
|
+
if (this.#pointerId !== null) {
|
|
2138
|
+
try {
|
|
2139
|
+
if (typeof this.#host.nativeElement.releasePointerCapture === 'function') {
|
|
2140
|
+
this.#host.nativeElement.releasePointerCapture(this.#pointerId);
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
catch {
|
|
2144
|
+
// Element may already be detached
|
|
2145
|
+
}
|
|
2146
|
+
this.#pointerId = null;
|
|
2147
|
+
}
|
|
2148
|
+
this.#host.nativeElement.style.touchAction = '';
|
|
2149
|
+
this.#host.nativeElement.style.userSelect = '';
|
|
1771
2150
|
this.#player?.cancel();
|
|
1772
2151
|
}
|
|
1773
2152
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveDragDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
@@ -1888,6 +2267,7 @@ class MoveTextDirective {
|
|
|
1888
2267
|
#platformId = inject(PLATFORM_ID);
|
|
1889
2268
|
#host = inject((ElementRef));
|
|
1890
2269
|
#engine = inject(AnimationEngine);
|
|
2270
|
+
#renderer = inject(Renderer2);
|
|
1891
2271
|
#players = [];
|
|
1892
2272
|
#spans = [];
|
|
1893
2273
|
#observer = null;
|
|
@@ -1948,21 +2328,24 @@ class MoveTextDirective {
|
|
|
1948
2328
|
#splitText() {
|
|
1949
2329
|
const el = this.#host.nativeElement;
|
|
1950
2330
|
const text = (el.textContent ?? '').trim();
|
|
1951
|
-
|
|
1952
|
-
el.
|
|
2331
|
+
// Clear existing content safely via Renderer2
|
|
2332
|
+
while (el.firstChild) {
|
|
2333
|
+
this.#renderer.removeChild(el, el.firstChild);
|
|
2334
|
+
}
|
|
2335
|
+
this.#renderer.setAttribute(el, 'aria-label', text);
|
|
1953
2336
|
const byChars = this.moveTextSplit() === 'chars';
|
|
1954
2337
|
if (byChars) {
|
|
1955
2338
|
// Split character by character, preserving spaces as text nodes
|
|
1956
2339
|
[...text].forEach((char) => {
|
|
1957
2340
|
if (char === ' ') {
|
|
1958
|
-
|
|
2341
|
+
this.#renderer.appendChild(el, this.#documentRef.createTextNode(' '));
|
|
1959
2342
|
return;
|
|
1960
2343
|
}
|
|
1961
|
-
const span = this.#
|
|
1962
|
-
|
|
1963
|
-
span
|
|
1964
|
-
span
|
|
1965
|
-
|
|
2344
|
+
const span = this.#renderer.createElement('span');
|
|
2345
|
+
this.#renderer.setAttribute(span, 'aria-hidden', 'true');
|
|
2346
|
+
this.#renderer.setStyle(span, 'display', 'inline-block');
|
|
2347
|
+
this.#renderer.setProperty(span, 'textContent', char);
|
|
2348
|
+
this.#renderer.appendChild(el, span);
|
|
1966
2349
|
this.#spans.push(span);
|
|
1967
2350
|
});
|
|
1968
2351
|
}
|
|
@@ -1970,12 +2353,12 @@ class MoveTextDirective {
|
|
|
1970
2353
|
// Split word by word
|
|
1971
2354
|
const words = text.split(/\s+/);
|
|
1972
2355
|
words.forEach((word, index) => {
|
|
1973
|
-
const span = this.#
|
|
1974
|
-
|
|
1975
|
-
span
|
|
1976
|
-
span
|
|
1977
|
-
span
|
|
1978
|
-
|
|
2356
|
+
const span = this.#renderer.createElement('span');
|
|
2357
|
+
this.#renderer.setAttribute(span, 'aria-hidden', 'true');
|
|
2358
|
+
this.#renderer.setStyle(span, 'display', 'inline-block');
|
|
2359
|
+
this.#renderer.setStyle(span, 'white-space', 'pre');
|
|
2360
|
+
this.#renderer.setProperty(span, 'textContent', index < words.length - 1 ? word + ' ' : word);
|
|
2361
|
+
this.#renderer.appendChild(el, span);
|
|
1979
2362
|
this.#spans.push(span);
|
|
1980
2363
|
});
|
|
1981
2364
|
}
|
|
@@ -1983,6 +2366,8 @@ class MoveTextDirective {
|
|
|
1983
2366
|
ngOnDestroy() {
|
|
1984
2367
|
this.#observer?.disconnect();
|
|
1985
2368
|
this.#players.forEach((p) => p.cancel());
|
|
2369
|
+
this.#players = [];
|
|
2370
|
+
this.#spans = [];
|
|
1986
2371
|
}
|
|
1987
2372
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1988
2373
|
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveTextDirective, isStandalone: true, selector: "[moveText]", inputs: { moveText: { classPropertyName: "moveText", publicName: "moveText", isSignal: true, isRequired: false, transformFunction: null }, moveTextSplit: { classPropertyName: "moveTextSplit", publicName: "moveTextSplit", isSignal: true, isRequired: false, transformFunction: null }, moveTextStagger: { classPropertyName: "moveTextStagger", publicName: "moveTextStagger", isSignal: true, isRequired: false, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
@@ -2270,6 +2655,283 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
|
|
|
2270
2655
|
}]
|
|
2271
2656
|
}], propDecorators: { moveLoop: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveLoop", required: false }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }] } });
|
|
2272
2657
|
|
|
2658
|
+
function optionalNumberAttribute$1(value) {
|
|
2659
|
+
if (value === undefined || value === null || value === '') {
|
|
2660
|
+
return undefined;
|
|
2661
|
+
}
|
|
2662
|
+
return Number(value);
|
|
2663
|
+
}
|
|
2664
|
+
class MoveTargetDirective {
|
|
2665
|
+
moveTarget = input.required(...(ngDevMode ? [{ debugName: "moveTarget" }] : /* istanbul ignore next */ []));
|
|
2666
|
+
moveFrames = input.required(...(ngDevMode ? [{ debugName: "moveFrames" }] : /* istanbul ignore next */ []));
|
|
2667
|
+
moveDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$1 });
|
|
2668
|
+
moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
|
|
2669
|
+
moveDelay = input(undefined, { ...(ngDevMode ? { debugName: "moveDelay" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$1 });
|
|
2670
|
+
moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
|
|
2671
|
+
moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
|
|
2672
|
+
moveReverseDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveReverseDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$1 });
|
|
2673
|
+
moveReverseEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveReverseEasing" }] : /* istanbul ignore next */ []));
|
|
2674
|
+
moveTransition = input(undefined, ...(ngDevMode ? [{ debugName: "moveTransition" }] : /* istanbul ignore next */ []));
|
|
2675
|
+
#defaults = inject(MOVEMENT_CONFIG);
|
|
2676
|
+
#documentRef = inject(DOCUMENT);
|
|
2677
|
+
#host = inject((ElementRef));
|
|
2678
|
+
#engine = inject(AnimationEngine);
|
|
2679
|
+
#currentPlayer = null;
|
|
2680
|
+
#hasPlayedForward = false;
|
|
2681
|
+
#targetEffect = effect(() => {
|
|
2682
|
+
const active = this.moveTarget();
|
|
2683
|
+
const frames = this.moveFrames();
|
|
2684
|
+
if (active) {
|
|
2685
|
+
this.#playForward(frames);
|
|
2686
|
+
this.#hasPlayedForward = true;
|
|
2687
|
+
return;
|
|
2688
|
+
}
|
|
2689
|
+
if (this.#hasPlayedForward) {
|
|
2690
|
+
this.#playReverse(frames);
|
|
2691
|
+
}
|
|
2692
|
+
}, ...(ngDevMode ? [{ debugName: "#targetEffect" }] : /* istanbul ignore next */ []));
|
|
2693
|
+
#playForward(frames) {
|
|
2694
|
+
this.#currentPlayer?.cancel();
|
|
2695
|
+
const isReduced = prefersReducedMotion(this.#documentRef);
|
|
2696
|
+
const config = resolveMovementConfig(this.#defaults, {
|
|
2697
|
+
duration: this.moveDuration(),
|
|
2698
|
+
easing: this.moveEasing(),
|
|
2699
|
+
delay: this.moveDelay(),
|
|
2700
|
+
disabled: this.moveDisabled(),
|
|
2701
|
+
}, isReduced);
|
|
2702
|
+
this.#currentPlayer = this.#engine.play(this.#host.nativeElement, frames, {
|
|
2703
|
+
config,
|
|
2704
|
+
spring: this.moveSpring(),
|
|
2705
|
+
disabled: config.disabled,
|
|
2706
|
+
transition: this.moveTransition(),
|
|
2707
|
+
});
|
|
2708
|
+
}
|
|
2709
|
+
#playReverse(frames) {
|
|
2710
|
+
this.#currentPlayer?.cancel();
|
|
2711
|
+
const isReduced = prefersReducedMotion(this.#documentRef);
|
|
2712
|
+
const config = resolveMovementConfig({ ...this.#defaults, duration: 200, easing: 'ease-out', delay: 0 }, {
|
|
2713
|
+
duration: this.moveReverseDuration() ?? this.moveDuration(),
|
|
2714
|
+
easing: this.moveReverseEasing(),
|
|
2715
|
+
delay: 0,
|
|
2716
|
+
disabled: this.moveDisabled(),
|
|
2717
|
+
}, isReduced);
|
|
2718
|
+
this.#currentPlayer = this.#engine.play(this.#host.nativeElement, reverseFrames(frames), {
|
|
2719
|
+
config,
|
|
2720
|
+
spring: this.moveSpring(),
|
|
2721
|
+
disabled: config.disabled,
|
|
2722
|
+
transition: this.moveTransition(),
|
|
2723
|
+
});
|
|
2724
|
+
}
|
|
2725
|
+
ngOnDestroy() {
|
|
2726
|
+
this.#targetEffect.destroy();
|
|
2727
|
+
this.#currentPlayer?.cancel();
|
|
2728
|
+
}
|
|
2729
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTargetDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2730
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveTargetDirective, isStandalone: true, selector: "[moveTarget]", inputs: { moveTarget: { classPropertyName: "moveTarget", publicName: "moveTarget", isSignal: true, isRequired: true, transformFunction: null }, moveFrames: { classPropertyName: "moveFrames", publicName: "moveFrames", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveReverseDuration: { classPropertyName: "moveReverseDuration", publicName: "moveReverseDuration", isSignal: true, isRequired: false, transformFunction: null }, moveReverseEasing: { classPropertyName: "moveReverseEasing", publicName: "moveReverseEasing", isSignal: true, isRequired: false, transformFunction: null }, moveTransition: { classPropertyName: "moveTransition", publicName: "moveTransition", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
2731
|
+
}
|
|
2732
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTargetDirective, decorators: [{
|
|
2733
|
+
type: Directive,
|
|
2734
|
+
args: [{
|
|
2735
|
+
selector: '[moveTarget]',
|
|
2736
|
+
standalone: true,
|
|
2737
|
+
}]
|
|
2738
|
+
}], propDecorators: { moveTarget: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveTarget", required: true }] }], moveFrames: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveFrames", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveReverseDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseDuration", required: false }] }], moveReverseEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseEasing", required: false }] }], moveTransition: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveTransition", required: false }] }] } });
|
|
2739
|
+
|
|
2740
|
+
function optionalNumberAttribute(value) {
|
|
2741
|
+
if (value === undefined || value === null || value === '') {
|
|
2742
|
+
return undefined;
|
|
2743
|
+
}
|
|
2744
|
+
return Number(value);
|
|
2745
|
+
}
|
|
2746
|
+
class MoveTriggerDirective {
|
|
2747
|
+
moveTrigger = input.required(...(ngDevMode ? [{ debugName: "moveTrigger" }] : /* istanbul ignore next */ []));
|
|
2748
|
+
moveFrames = input.required(...(ngDevMode ? [{ debugName: "moveFrames" }] : /* istanbul ignore next */ []));
|
|
2749
|
+
moveResetFrames = input(undefined, ...(ngDevMode ? [{ debugName: "moveResetFrames" }] : /* istanbul ignore next */ []));
|
|
2750
|
+
moveResetState = input('clear', ...(ngDevMode ? [{ debugName: "moveResetState" }] : /* istanbul ignore next */ []));
|
|
2751
|
+
moveDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
|
|
2752
|
+
moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
|
|
2753
|
+
moveDelay = input(undefined, { ...(ngDevMode ? { debugName: "moveDelay" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
|
|
2754
|
+
moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
|
|
2755
|
+
moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
|
|
2756
|
+
moveReverseDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveReverseDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
|
|
2757
|
+
moveReverseEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveReverseEasing" }] : /* istanbul ignore next */ []));
|
|
2758
|
+
#defaults = inject(MOVEMENT_CONFIG);
|
|
2759
|
+
#documentRef = inject(DOCUMENT);
|
|
2760
|
+
#host = inject((ElementRef));
|
|
2761
|
+
#engine = inject(AnimationEngine);
|
|
2762
|
+
#currentPlayer = null;
|
|
2763
|
+
#hasPlayedForward = false;
|
|
2764
|
+
#triggerEffect = effect(() => {
|
|
2765
|
+
const active = this.moveTrigger();
|
|
2766
|
+
const frames = this.moveFrames();
|
|
2767
|
+
if (active) {
|
|
2768
|
+
this.#playForward(frames);
|
|
2769
|
+
this.#hasPlayedForward = true;
|
|
2770
|
+
return;
|
|
2771
|
+
}
|
|
2772
|
+
if (this.#hasPlayedForward) {
|
|
2773
|
+
this.#playReset(frames);
|
|
2774
|
+
}
|
|
2775
|
+
}, ...(ngDevMode ? [{ debugName: "#triggerEffect" }] : /* istanbul ignore next */ []));
|
|
2776
|
+
play(frames) {
|
|
2777
|
+
const targetFrames = frames ?? this.moveFrames();
|
|
2778
|
+
this.#playForward(targetFrames);
|
|
2779
|
+
this.#hasPlayedForward = true;
|
|
2780
|
+
return this.#currentPlayer?.finished ?? Promise.resolve();
|
|
2781
|
+
}
|
|
2782
|
+
reset() {
|
|
2783
|
+
this.#currentPlayer?.cancel();
|
|
2784
|
+
const frames = this.moveFrames();
|
|
2785
|
+
this.#applyReset(frames);
|
|
2786
|
+
}
|
|
2787
|
+
set(state) {
|
|
2788
|
+
this.#currentPlayer?.cancel();
|
|
2789
|
+
applyComposedStyle(this.#host.nativeElement, state);
|
|
2790
|
+
}
|
|
2791
|
+
#playForward(frames) {
|
|
2792
|
+
this.#currentPlayer?.cancel();
|
|
2793
|
+
const isReduced = prefersReducedMotion(this.#documentRef);
|
|
2794
|
+
const config = resolveMovementConfig(this.#defaults, {
|
|
2795
|
+
duration: this.moveDuration(),
|
|
2796
|
+
easing: this.moveEasing(),
|
|
2797
|
+
delay: this.moveDelay(),
|
|
2798
|
+
disabled: this.moveDisabled(),
|
|
2799
|
+
}, isReduced);
|
|
2800
|
+
this.#currentPlayer = this.#engine.play(this.#host.nativeElement, frames, {
|
|
2801
|
+
config,
|
|
2802
|
+
spring: this.moveSpring(),
|
|
2803
|
+
disabled: config.disabled,
|
|
2804
|
+
});
|
|
2805
|
+
}
|
|
2806
|
+
#playReset(frames) {
|
|
2807
|
+
this.#currentPlayer?.cancel();
|
|
2808
|
+
const resetFrames = this.moveResetFrames();
|
|
2809
|
+
if (resetFrames) {
|
|
2810
|
+
const isReduced = prefersReducedMotion(this.#documentRef);
|
|
2811
|
+
const config = resolveMovementConfig({ ...this.#defaults, duration: 200, easing: 'ease-out', delay: 0 }, {
|
|
2812
|
+
duration: this.moveReverseDuration() ?? this.moveDuration(),
|
|
2813
|
+
easing: this.moveReverseEasing(),
|
|
2814
|
+
delay: 0,
|
|
2815
|
+
disabled: this.moveDisabled(),
|
|
2816
|
+
}, isReduced);
|
|
2817
|
+
this.#currentPlayer = this.#engine.play(this.#host.nativeElement, resetFrames, {
|
|
2818
|
+
config,
|
|
2819
|
+
spring: this.moveSpring(),
|
|
2820
|
+
disabled: config.disabled,
|
|
2821
|
+
});
|
|
2822
|
+
return;
|
|
2823
|
+
}
|
|
2824
|
+
const reverseDuration = this.moveReverseDuration();
|
|
2825
|
+
if (reverseDuration === 0) {
|
|
2826
|
+
this.#applyReset(frames);
|
|
2827
|
+
return;
|
|
2828
|
+
}
|
|
2829
|
+
const isReduced = prefersReducedMotion(this.#documentRef);
|
|
2830
|
+
const config = resolveMovementConfig({ ...this.#defaults, duration: 200, easing: 'ease-out', delay: 0 }, {
|
|
2831
|
+
duration: reverseDuration ?? this.moveDuration(),
|
|
2832
|
+
easing: this.moveReverseEasing(),
|
|
2833
|
+
delay: 0,
|
|
2834
|
+
disabled: this.moveDisabled(),
|
|
2835
|
+
}, isReduced);
|
|
2836
|
+
if (config.disabled) {
|
|
2837
|
+
this.#applyReset(frames);
|
|
2838
|
+
return;
|
|
2839
|
+
}
|
|
2840
|
+
// For triggers, reverse is typically not desired; we reset to initial/clear.
|
|
2841
|
+
// We apply the initial style of the forward frames to restore state.
|
|
2842
|
+
this.#applyReset(frames);
|
|
2843
|
+
}
|
|
2844
|
+
#applyReset(frames) {
|
|
2845
|
+
const mode = this.moveResetState();
|
|
2846
|
+
const host = this.#host.nativeElement;
|
|
2847
|
+
if (mode === 'clear') {
|
|
2848
|
+
clearComposedStyle(host, Object.keys(frames));
|
|
2849
|
+
return;
|
|
2850
|
+
}
|
|
2851
|
+
if (mode === 'initial') {
|
|
2852
|
+
clearComposedStyle(host, Object.keys(frames));
|
|
2853
|
+
applyComposedStyle(host, composeInitialStyle(frames));
|
|
2854
|
+
return;
|
|
2855
|
+
}
|
|
2856
|
+
if (mode === 'final') {
|
|
2857
|
+
clearComposedStyle(host, Object.keys(frames));
|
|
2858
|
+
applyComposedStyle(host, composeFinalStyle(frames));
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
ngOnDestroy() {
|
|
2862
|
+
this.#triggerEffect.destroy();
|
|
2863
|
+
this.#currentPlayer?.cancel();
|
|
2864
|
+
const frames = this.moveFrames();
|
|
2865
|
+
if (frames) {
|
|
2866
|
+
clearComposedStyle(this.#host.nativeElement, Object.keys(frames));
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2870
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveTriggerDirective, isStandalone: true, selector: "[moveTrigger]", inputs: { moveTrigger: { classPropertyName: "moveTrigger", publicName: "moveTrigger", isSignal: true, isRequired: true, transformFunction: null }, moveFrames: { classPropertyName: "moveFrames", publicName: "moveFrames", isSignal: true, isRequired: true, transformFunction: null }, moveResetFrames: { classPropertyName: "moveResetFrames", publicName: "moveResetFrames", isSignal: true, isRequired: false, transformFunction: null }, moveResetState: { classPropertyName: "moveResetState", publicName: "moveResetState", isSignal: true, isRequired: false, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveReverseDuration: { classPropertyName: "moveReverseDuration", publicName: "moveReverseDuration", isSignal: true, isRequired: false, transformFunction: null }, moveReverseEasing: { classPropertyName: "moveReverseEasing", publicName: "moveReverseEasing", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["moveTrigger"], ngImport: i0 });
|
|
2871
|
+
}
|
|
2872
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTriggerDirective, decorators: [{
|
|
2873
|
+
type: Directive,
|
|
2874
|
+
args: [{
|
|
2875
|
+
selector: '[moveTrigger]',
|
|
2876
|
+
standalone: true,
|
|
2877
|
+
exportAs: 'moveTrigger',
|
|
2878
|
+
}]
|
|
2879
|
+
}], propDecorators: { moveTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveTrigger", required: true }] }], moveFrames: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveFrames", required: true }] }], moveResetFrames: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveResetFrames", required: false }] }], moveResetState: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveResetState", required: false }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveReverseDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseDuration", required: false }] }], moveReverseEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseEasing", required: false }] }] } });
|
|
2880
|
+
|
|
2881
|
+
/**
|
|
2882
|
+
* Returns keyframes for a path-drawing animation.
|
|
2883
|
+
* Ideal for SVG `<path>`, `<circle>`, `<line>`, etc.
|
|
2884
|
+
*
|
|
2885
|
+
* @example
|
|
2886
|
+
* ```html
|
|
2887
|
+
* <path [moveTarget]="animate()" [moveFrames]="movePathDraw({ opacity: [0, 1] })" moveDuration="700" />
|
|
2888
|
+
* ```
|
|
2889
|
+
*/
|
|
2890
|
+
function movePathDraw(overrides) {
|
|
2891
|
+
return {
|
|
2892
|
+
pathLength: [0, 1],
|
|
2893
|
+
opacity: [0, 1],
|
|
2894
|
+
...overrides,
|
|
2895
|
+
};
|
|
2896
|
+
}
|
|
2897
|
+
/**
|
|
2898
|
+
* Returns keyframes for a subtle pulse animation on an icon.
|
|
2899
|
+
*/
|
|
2900
|
+
function moveIconPulse(overrides) {
|
|
2901
|
+
return {
|
|
2902
|
+
scale: [1, 1.08, 1],
|
|
2903
|
+
opacity: [1, 0.85, 1],
|
|
2904
|
+
...overrides,
|
|
2905
|
+
};
|
|
2906
|
+
}
|
|
2907
|
+
/**
|
|
2908
|
+
* Returns keyframes for a subtle bounce animation on an icon.
|
|
2909
|
+
*/
|
|
2910
|
+
function moveIconBounce(overrides) {
|
|
2911
|
+
return {
|
|
2912
|
+
y: [0, -3, 0],
|
|
2913
|
+
...overrides,
|
|
2914
|
+
};
|
|
2915
|
+
}
|
|
2916
|
+
/**
|
|
2917
|
+
* Returns keyframes for a subtle shake animation on an icon.
|
|
2918
|
+
*/
|
|
2919
|
+
function moveIconShake(overrides) {
|
|
2920
|
+
return {
|
|
2921
|
+
rotate: [0, -8, 8, -8, 8, 0],
|
|
2922
|
+
...overrides,
|
|
2923
|
+
};
|
|
2924
|
+
}
|
|
2925
|
+
/**
|
|
2926
|
+
* Returns keyframes for a subtle rotate animation on an icon.
|
|
2927
|
+
*/
|
|
2928
|
+
function moveIconRotate(overrides) {
|
|
2929
|
+
return {
|
|
2930
|
+
rotate: [0, 15, 0],
|
|
2931
|
+
...overrides,
|
|
2932
|
+
};
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2273
2935
|
function provideMovement(config = {}) {
|
|
2274
2936
|
return makeEnvironmentProviders([
|
|
2275
2937
|
{
|
|
@@ -2301,6 +2963,8 @@ const MOVEMENT_DIRECTIVES = [
|
|
|
2301
2963
|
MoveParallaxDirective,
|
|
2302
2964
|
MoveAnimationDirective,
|
|
2303
2965
|
MoveLoopDirective,
|
|
2966
|
+
MoveTargetDirective,
|
|
2967
|
+
MoveTriggerDirective,
|
|
2304
2968
|
];
|
|
2305
2969
|
|
|
2306
2970
|
/*
|
|
@@ -2311,5 +2975,5 @@ const MOVEMENT_DIRECTIVES = [
|
|
|
2311
2975
|
* Generated bundle index. Do not edit.
|
|
2312
2976
|
*/
|
|
2313
2977
|
|
|
2314
|
-
export { AnimationEngine, MOVEMENT_CONFIG, MOVEMENT_DEFAULTS, MOVEMENT_DIRECTIVES, MOVE_PRESENCE_PARENT, MOVE_PRESETS, MOVE_STAGGER_PARENT, MOVE_VARIANTS_PARENT, MoveAnimateDirective, MoveAnimationDirective, MoveDragDirective, MoveEnterDirective, MoveFocusDirective, MoveHoverDirective, MoveInViewDirective, MoveLayoutDirective, MoveLeaveDirective, MoveLoopDirective, MoveParallaxDirective, MovePresenceDirective, MoveScrollDirective, MoveSmoothScrollDirective, MoveStaggerDirective, MoveTapDirective, MoveTextDirective, MoveVariantsDirective, SmoothScrollService, SpringPlayer, WaapiPlayer, applyInitialStyles, clearInitialStyles, prefersReducedMotion, provideMovement, resolveMoveFrames, resolveMovementConfig, reverseFrames };
|
|
2978
|
+
export { AnimationEngine, MOVEMENT_CONFIG, MOVEMENT_DEFAULTS, MOVEMENT_DIRECTIVES, MOVE_PRESENCE_PARENT, MOVE_PRESETS, MOVE_STAGGER_PARENT, MOVE_VARIANTS_PARENT, MoveAnimateDirective, MoveAnimationDirective, MoveDragDirective, MoveEnterDirective, MoveFocusDirective, MoveHoverDirective, MoveInViewDirective, MoveLayoutDirective, MoveLeaveDirective, MoveLoopDirective, MoveParallaxDirective, MovePresenceDirective, MoveScrollDirective, MoveSmoothScrollDirective, MoveStaggerDirective, MoveTapDirective, MoveTargetDirective, MoveTextDirective, MoveTriggerDirective, MoveVariantsDirective, SmoothScrollService, SpringPlayer, WaapiPlayer, applyInitialStyles, clearComposedStyle, clearInitialStyles, composeTransitionKeyframes, isValidScrollOffset, moveIconBounce, moveIconPulse, moveIconRotate, moveIconShake, movePathDraw, prefersReducedMotion, provideMovement, resolveMoveFrames, resolveMovementConfig, reverseFrames, validateDragElastic, validateSpring };
|
|
2315
2979
|
//# sourceMappingURL=angular-movement.mjs.map
|