angular-movement 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +115 -33
- package/fesm2022/angular-movement.mjs +223 -98
- package/fesm2022/angular-movement.mjs.map +1 -1
- package/package.json +1 -1
- package/types/angular-movement.d.ts +64 -15
|
@@ -1,12 +1,13 @@
|
|
|
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,
|
|
3
|
+
import { InjectionToken, inject, PLATFORM_ID, Injectable, input, ElementRef, computed, effect, forwardRef, Directive, afterEveryRender, NgZone, signal, ViewContainerRef, TemplateRef, makeEnvironmentProviders } from '@angular/core';
|
|
4
4
|
|
|
5
5
|
const MOVEMENT_DEFAULTS = {
|
|
6
6
|
duration: 300,
|
|
7
7
|
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
|
|
8
8
|
delay: 0,
|
|
9
9
|
disabled: false,
|
|
10
|
+
iterations: 1,
|
|
10
11
|
};
|
|
11
12
|
const MOVEMENT_CONFIG = new InjectionToken('MOVEMENT_CONFIG', {
|
|
12
13
|
factory: () => ({ ...MOVEMENT_DEFAULTS }),
|
|
@@ -52,6 +53,18 @@ function getInterpolated(arr, i1, i2, p) {
|
|
|
52
53
|
const v2 = arr[Math.min(i2, arr.length - 1)];
|
|
53
54
|
return v1 + (v2 - v1) * p;
|
|
54
55
|
}
|
|
56
|
+
const KNOWN_KEYS = new Set([
|
|
57
|
+
'opacity',
|
|
58
|
+
'x',
|
|
59
|
+
'y',
|
|
60
|
+
'scale',
|
|
61
|
+
'scaleX',
|
|
62
|
+
'scaleY',
|
|
63
|
+
'rotate',
|
|
64
|
+
'rotateX',
|
|
65
|
+
'rotateY',
|
|
66
|
+
'blur',
|
|
67
|
+
]);
|
|
55
68
|
function buildKeyframe(frames, getVal) {
|
|
56
69
|
const keyframe = {};
|
|
57
70
|
const opacity = getVal(frames.opacity);
|
|
@@ -87,6 +100,16 @@ function buildKeyframe(frames, getVal) {
|
|
|
87
100
|
if (rotateX !== undefined || rotateY !== undefined) {
|
|
88
101
|
keyframe.transform = `perspective(${DEFAULT_PERSPECTIVE}) rotateX(${rotateX ?? 0}deg) rotateY(${rotateY ?? 0}deg)`;
|
|
89
102
|
}
|
|
103
|
+
// Passthrough arbitrary properties for WAAPI (e.g. strokeDashoffset)
|
|
104
|
+
for (const key in frames) {
|
|
105
|
+
if (KNOWN_KEYS.has(key))
|
|
106
|
+
continue;
|
|
107
|
+
const arr = frames[key];
|
|
108
|
+
const val = getVal(arr);
|
|
109
|
+
if (val !== undefined) {
|
|
110
|
+
keyframe[key] = val;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
90
113
|
return keyframe;
|
|
91
114
|
}
|
|
92
115
|
function composeKeyframeAt(frames, index) {
|
|
@@ -101,27 +124,51 @@ function composeInitialStyle(frames) {
|
|
|
101
124
|
function composeFinalStyle(frames) {
|
|
102
125
|
return buildKeyframe(frames, (arr) => (arr && arr.length > 0 ? arr[arr.length - 1] : undefined));
|
|
103
126
|
}
|
|
127
|
+
const KNOWN_STYLE_KEYS = new Set([
|
|
128
|
+
'opacity',
|
|
129
|
+
'translate',
|
|
130
|
+
'scale',
|
|
131
|
+
'rotate',
|
|
132
|
+
'transform',
|
|
133
|
+
'filter',
|
|
134
|
+
]);
|
|
104
135
|
function applyComposedStyle(el, style) {
|
|
136
|
+
const styledEl = el;
|
|
105
137
|
if (style.opacity !== undefined)
|
|
106
|
-
|
|
138
|
+
styledEl.style.opacity = `${style.opacity}`;
|
|
107
139
|
if (style.translate !== undefined)
|
|
108
|
-
|
|
140
|
+
styledEl.style.translate = style.translate;
|
|
109
141
|
if (style.scale !== undefined)
|
|
110
|
-
|
|
142
|
+
styledEl.style.scale = style.scale;
|
|
111
143
|
if (style.rotate !== undefined)
|
|
112
|
-
|
|
144
|
+
styledEl.style.rotate = style.rotate;
|
|
113
145
|
if (style.transform !== undefined)
|
|
114
|
-
|
|
146
|
+
styledEl.style.transform = style.transform;
|
|
115
147
|
if (style.filter !== undefined)
|
|
116
|
-
|
|
148
|
+
styledEl.style.filter = style.filter;
|
|
149
|
+
// Passthrough arbitrary properties (e.g. strokeDashoffset)
|
|
150
|
+
for (const key in style) {
|
|
151
|
+
if (KNOWN_STYLE_KEYS.has(key))
|
|
152
|
+
continue;
|
|
153
|
+
const val = style[key];
|
|
154
|
+
if (val !== undefined) {
|
|
155
|
+
styledEl.style[key] = String(val);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
117
158
|
}
|
|
118
|
-
function clearComposedStyle(el) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
159
|
+
function clearComposedStyle(el, extraKeys) {
|
|
160
|
+
const styledEl = el;
|
|
161
|
+
styledEl.style.opacity = '';
|
|
162
|
+
styledEl.style.translate = '';
|
|
163
|
+
styledEl.style.scale = '';
|
|
164
|
+
styledEl.style.rotate = '';
|
|
165
|
+
styledEl.style.transform = '';
|
|
166
|
+
styledEl.style.filter = '';
|
|
167
|
+
if (extraKeys) {
|
|
168
|
+
for (const key of extraKeys) {
|
|
169
|
+
styledEl.style[key] = '';
|
|
170
|
+
}
|
|
171
|
+
}
|
|
125
172
|
}
|
|
126
173
|
|
|
127
174
|
const DEFAULT_FADE_OPACITY = [0, 1];
|
|
@@ -178,6 +225,7 @@ const MOVE_PRESETS = {
|
|
|
178
225
|
'bounce-in': {
|
|
179
226
|
enter: { opacity: DEFAULT_FADE_OPACITY, y: [30, 0], scale: [0.85, 1] },
|
|
180
227
|
leave: { opacity: DEFAULT_LEAVE_OPACITY, y: [0, -20], scale: [1, 0.9] },
|
|
228
|
+
loop: { y: [0, -10, 0], scale: [1, 0.95, 1] },
|
|
181
229
|
},
|
|
182
230
|
'blur-in': {
|
|
183
231
|
enter: { opacity: DEFAULT_FADE_OPACITY, blur: [10, 0] },
|
|
@@ -186,10 +234,12 @@ const MOVE_PRESETS = {
|
|
|
186
234
|
spin: {
|
|
187
235
|
enter: { opacity: DEFAULT_FADE_OPACITY, rotate: [-360, 0] },
|
|
188
236
|
leave: { opacity: DEFAULT_LEAVE_OPACITY, rotate: [0, 360] },
|
|
237
|
+
loop: { rotate: [0, 360] },
|
|
189
238
|
},
|
|
190
239
|
pulse: {
|
|
191
240
|
enter: { scale: [1, 1.05, 1] },
|
|
192
241
|
leave: { scale: [1, 0.95, 1] },
|
|
242
|
+
loop: { scale: [1, 1.05, 1] },
|
|
193
243
|
},
|
|
194
244
|
none: {
|
|
195
245
|
enter: { opacity: [1, 1] },
|
|
@@ -207,6 +257,7 @@ function resolveMovementConfig(defaults, overrides, reducedMotion) {
|
|
|
207
257
|
easing: overrides.easing ?? defaults.easing,
|
|
208
258
|
delay: Math.max(0, overrides.delay ?? defaults.delay),
|
|
209
259
|
disabled: reducedMotion || (overrides.disabled ?? defaults.disabled),
|
|
260
|
+
iterations: overrides.iterations ?? defaults.iterations,
|
|
210
261
|
};
|
|
211
262
|
}
|
|
212
263
|
function resolveMoveFrames(value, phase) {
|
|
@@ -216,9 +267,9 @@ function resolveMoveFrames(value, phase) {
|
|
|
216
267
|
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
217
268
|
console.warn(`[Movement] Unknown preset: "${value}". Using "none" preset.`);
|
|
218
269
|
}
|
|
219
|
-
return MOVE_PRESETS['none'][phase];
|
|
270
|
+
return MOVE_PRESETS['none'][phase] ?? MOVE_PRESETS['none'].enter;
|
|
220
271
|
}
|
|
221
|
-
return preset[phase];
|
|
272
|
+
return preset[phase] ?? preset.enter;
|
|
222
273
|
}
|
|
223
274
|
return value;
|
|
224
275
|
}
|
|
@@ -273,12 +324,18 @@ class WaapiPlayer {
|
|
|
273
324
|
return;
|
|
274
325
|
}
|
|
275
326
|
const keyframes = this.#toWAAPIKeyframes(frames);
|
|
327
|
+
const iterations = config.iterations ?? 1;
|
|
276
328
|
this.#animation = host.animate(keyframes, {
|
|
277
329
|
duration: config.duration,
|
|
278
330
|
easing: config.easing,
|
|
279
331
|
delay: config.delay,
|
|
280
332
|
fill: 'both',
|
|
333
|
+
iterations,
|
|
281
334
|
});
|
|
335
|
+
if (iterations === Infinity) {
|
|
336
|
+
// Infinite loops never finish; consumer must call cancel() manually.
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
282
339
|
this.#animation.addEventListener('finish', () => {
|
|
283
340
|
this.#animation?.commitStyles?.();
|
|
284
341
|
this.#animation?.cancel();
|
|
@@ -328,22 +385,28 @@ class SpringPlayer {
|
|
|
328
385
|
host;
|
|
329
386
|
frames;
|
|
330
387
|
delay;
|
|
388
|
+
iterations;
|
|
331
389
|
onDone;
|
|
332
390
|
#resolveFinished;
|
|
333
391
|
finished = new Promise((resolve) => {
|
|
334
392
|
this.#resolveFinished = resolve;
|
|
335
393
|
});
|
|
336
394
|
#animation = null;
|
|
337
|
-
constructor(host, frames, userConfig, delay, onDone) {
|
|
395
|
+
constructor(host, frames, userConfig, delay, iterations = 1, onDone) {
|
|
338
396
|
this.host = host;
|
|
339
397
|
this.frames = frames;
|
|
340
398
|
this.delay = delay;
|
|
399
|
+
this.iterations = iterations;
|
|
341
400
|
this.onDone = onDone;
|
|
342
401
|
if (typeof host.animate !== 'function') {
|
|
343
402
|
this.#resolveFinished();
|
|
344
403
|
onDone?.();
|
|
345
404
|
return;
|
|
346
405
|
}
|
|
406
|
+
if (this.iterations !== 1 && typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
407
|
+
console.warn('[Movement] Spring animations with iterations !== 1 may produce visual glitches. ' +
|
|
408
|
+
'Consider using WaapiPlayer (no spring) for loops.');
|
|
409
|
+
}
|
|
347
410
|
const config = {
|
|
348
411
|
stiffness: 100,
|
|
349
412
|
damping: 10,
|
|
@@ -366,7 +429,12 @@ class SpringPlayer {
|
|
|
366
429
|
delay: this.delay,
|
|
367
430
|
fill: 'both',
|
|
368
431
|
easing: 'linear', // Spring physics already has the easing baked into the frames
|
|
432
|
+
iterations: this.iterations,
|
|
369
433
|
});
|
|
434
|
+
if (this.iterations === Infinity) {
|
|
435
|
+
// Infinite loops never finish; consumer must call cancel() manually.
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
370
438
|
this.#animation.addEventListener('finish', () => {
|
|
371
439
|
this.#animation?.commitStyles?.();
|
|
372
440
|
this.#animation?.cancel();
|
|
@@ -459,8 +527,9 @@ class AnimationEngine {
|
|
|
459
527
|
}
|
|
460
528
|
const config = options.config ?? this.#defaults;
|
|
461
529
|
const isSpring = options.spring || config.easing === 'spring';
|
|
530
|
+
const iterations = options.iterations ?? config.iterations;
|
|
462
531
|
if (isSpring) {
|
|
463
|
-
return new SpringPlayer(host, frames, options.spring ?? {}, options.delay ?? config.delay, options.onDone);
|
|
532
|
+
return new SpringPlayer(host, frames, options.spring ?? {}, options.delay ?? config.delay, iterations, options.onDone);
|
|
464
533
|
}
|
|
465
534
|
else {
|
|
466
535
|
return new WaapiPlayer(host, frames, {
|
|
@@ -468,6 +537,7 @@ class AnimationEngine {
|
|
|
468
537
|
easing: config.easing,
|
|
469
538
|
delay: options.delay ?? config.delay,
|
|
470
539
|
disabled: false,
|
|
540
|
+
iterations,
|
|
471
541
|
}, options.onDone);
|
|
472
542
|
}
|
|
473
543
|
}
|
|
@@ -486,6 +556,81 @@ const MOVE_STAGGER_PARENT = new InjectionToken('MOVE_STAGGER_PARENT');
|
|
|
486
556
|
|
|
487
557
|
const MOVE_PRESENCE_PARENT = new InjectionToken('MOVE_PRESENCE_PARENT');
|
|
488
558
|
|
|
559
|
+
const MOVE_VARIANTS_PARENT = new InjectionToken('MOVE_VARIANTS_PARENT');
|
|
560
|
+
class MoveVariantsDirective {
|
|
561
|
+
moveVariants = input.required(...(ngDevMode ? [{ debugName: "moveVariants" }] : /* istanbul ignore next */ []));
|
|
562
|
+
moveAnimate = input(undefined, ...(ngDevMode ? [{ debugName: "moveAnimate" }] : /* istanbul ignore next */ []));
|
|
563
|
+
moveDuration = input(undefined, ...(ngDevMode ? [{ debugName: "moveDuration" }] : /* istanbul ignore next */ []));
|
|
564
|
+
moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
|
|
565
|
+
moveDelay = input(undefined, ...(ngDevMode ? [{ debugName: "moveDelay" }] : /* istanbul ignore next */ []));
|
|
566
|
+
moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
|
|
567
|
+
moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
|
|
568
|
+
#parent = inject(MOVE_VARIANTS_PARENT, { optional: true, skipSelf: true });
|
|
569
|
+
#engine = inject(AnimationEngine);
|
|
570
|
+
#defaults = inject(MOVEMENT_CONFIG);
|
|
571
|
+
#documentRef = inject(DOCUMENT);
|
|
572
|
+
#host = inject((ElementRef));
|
|
573
|
+
#stagger = inject(MOVE_STAGGER_PARENT, { optional: true });
|
|
574
|
+
#currentPlayer = null;
|
|
575
|
+
#isReducedMotion = false;
|
|
576
|
+
activeVariant = computed(() => {
|
|
577
|
+
return this.moveAnimate() ?? this.#parent?.activeVariant();
|
|
578
|
+
}, ...(ngDevMode ? [{ debugName: "activeVariant" }] : /* istanbul ignore next */ []));
|
|
579
|
+
constructor() {
|
|
580
|
+
this.#isReducedMotion = prefersReducedMotion(this.#documentRef);
|
|
581
|
+
this.#stagger?.register(this.#host.nativeElement);
|
|
582
|
+
effect(() => {
|
|
583
|
+
const variantName = this.activeVariant();
|
|
584
|
+
if (!variantName)
|
|
585
|
+
return;
|
|
586
|
+
const variants = this.moveVariants();
|
|
587
|
+
if (!variants)
|
|
588
|
+
return;
|
|
589
|
+
const state = variants[variantName];
|
|
590
|
+
if (!state)
|
|
591
|
+
return;
|
|
592
|
+
this.#currentPlayer?.cancel();
|
|
593
|
+
const { spring, duration, easing, delay, ...keyframesMap } = state;
|
|
594
|
+
const keyframes = keyframesMap;
|
|
595
|
+
const staggerDelay = this.#stagger?.getDelay(this.#host.nativeElement) ?? 0;
|
|
596
|
+
const config = resolveMovementConfig(this.#defaults, {
|
|
597
|
+
duration: duration ?? this.moveDuration(),
|
|
598
|
+
easing: easing ?? this.moveEasing(),
|
|
599
|
+
delay: (delay ?? this.moveDelay() ?? 0) + staggerDelay,
|
|
600
|
+
disabled: this.moveDisabled(),
|
|
601
|
+
}, this.#isReducedMotion);
|
|
602
|
+
this.#currentPlayer = this.#engine.play(this.#host.nativeElement, keyframes, {
|
|
603
|
+
config,
|
|
604
|
+
spring: spring ?? this.moveSpring(),
|
|
605
|
+
disabled: config.disabled,
|
|
606
|
+
});
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
ngOnDestroy() {
|
|
610
|
+
this.#stagger?.unregister(this.#host.nativeElement);
|
|
611
|
+
this.#currentPlayer?.cancel();
|
|
612
|
+
}
|
|
613
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveVariantsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
614
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveVariantsDirective, isStandalone: true, selector: "[moveVariants]", inputs: { moveVariants: { classPropertyName: "moveVariants", publicName: "moveVariants", isSignal: true, isRequired: true, transformFunction: null }, moveAnimate: { classPropertyName: "moveAnimate", publicName: "moveAnimate", 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 } }, providers: [
|
|
615
|
+
{
|
|
616
|
+
provide: MOVE_VARIANTS_PARENT,
|
|
617
|
+
useExisting: forwardRef(() => MoveVariantsDirective),
|
|
618
|
+
},
|
|
619
|
+
], ngImport: i0 });
|
|
620
|
+
}
|
|
621
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveVariantsDirective, decorators: [{
|
|
622
|
+
type: Directive,
|
|
623
|
+
args: [{
|
|
624
|
+
selector: '[moveVariants]',
|
|
625
|
+
providers: [
|
|
626
|
+
{
|
|
627
|
+
provide: MOVE_VARIANTS_PARENT,
|
|
628
|
+
useExisting: forwardRef(() => MoveVariantsDirective),
|
|
629
|
+
},
|
|
630
|
+
],
|
|
631
|
+
}]
|
|
632
|
+
}], ctorParameters: () => [], propDecorators: { moveVariants: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveVariants", required: true }] }], moveAnimate: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveAnimate", 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 }] }] } });
|
|
633
|
+
|
|
489
634
|
class MoveAnimateDirective {
|
|
490
635
|
move = input(undefined, ...(ngDevMode ? [{ debugName: "move" }] : /* istanbul ignore next */ []));
|
|
491
636
|
moveAnimate = input(undefined, ...(ngDevMode ? [{ debugName: "moveAnimate" }] : /* istanbul ignore next */ []));
|
|
@@ -501,10 +646,15 @@ class MoveAnimateDirective {
|
|
|
501
646
|
#engine = inject(AnimationEngine);
|
|
502
647
|
#stagger = inject(MOVE_STAGGER_PARENT, { optional: true });
|
|
503
648
|
#presence = inject(MOVE_PRESENCE_PARENT, { optional: true });
|
|
649
|
+
#variantsParent = inject(MOVE_VARIANTS_PARENT, { optional: true });
|
|
504
650
|
#config = this.#defaults;
|
|
505
651
|
#enterPlayer = null;
|
|
506
652
|
#leavePlayer = null;
|
|
507
653
|
ngOnInit() {
|
|
654
|
+
// If moveVariants is on the same host, let it handle animation
|
|
655
|
+
if (this.#variantsParent) {
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
508
658
|
this.#stagger?.register(this.#host.nativeElement);
|
|
509
659
|
this.#presence?.register(this);
|
|
510
660
|
Promise.resolve().then(() => {
|
|
@@ -530,7 +680,7 @@ class MoveAnimateDirective {
|
|
|
530
680
|
this.#leavePlayer?.cancel();
|
|
531
681
|
}
|
|
532
682
|
playLeave() {
|
|
533
|
-
if (this.#config.disabled) {
|
|
683
|
+
if (this.#variantsParent || this.#config.disabled) {
|
|
534
684
|
return Promise.resolve();
|
|
535
685
|
}
|
|
536
686
|
this.#enterPlayer?.cancel();
|
|
@@ -871,81 +1021,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
|
|
|
871
1021
|
}]
|
|
872
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 }] }] } });
|
|
873
1023
|
|
|
874
|
-
const MOVE_VARIANTS_PARENT = new InjectionToken('MOVE_VARIANTS_PARENT');
|
|
875
|
-
class MoveVariantsDirective {
|
|
876
|
-
moveVariants = input.required(...(ngDevMode ? [{ debugName: "moveVariants" }] : /* istanbul ignore next */ []));
|
|
877
|
-
moveAnimate = input(undefined, ...(ngDevMode ? [{ debugName: "moveAnimate" }] : /* istanbul ignore next */ []));
|
|
878
|
-
moveDuration = input(undefined, ...(ngDevMode ? [{ debugName: "moveDuration" }] : /* istanbul ignore next */ []));
|
|
879
|
-
moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
|
|
880
|
-
moveDelay = input(undefined, ...(ngDevMode ? [{ debugName: "moveDelay" }] : /* istanbul ignore next */ []));
|
|
881
|
-
moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
|
|
882
|
-
moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
|
|
883
|
-
#parent = inject(MOVE_VARIANTS_PARENT, { optional: true, skipSelf: true });
|
|
884
|
-
#engine = inject(AnimationEngine);
|
|
885
|
-
#defaults = inject(MOVEMENT_CONFIG);
|
|
886
|
-
#documentRef = inject(DOCUMENT);
|
|
887
|
-
#host = inject((ElementRef));
|
|
888
|
-
#stagger = inject(MOVE_STAGGER_PARENT, { optional: true });
|
|
889
|
-
#currentPlayer = null;
|
|
890
|
-
#isReducedMotion = false;
|
|
891
|
-
activeVariant = computed(() => {
|
|
892
|
-
return this.moveAnimate() ?? this.#parent?.activeVariant();
|
|
893
|
-
}, ...(ngDevMode ? [{ debugName: "activeVariant" }] : /* istanbul ignore next */ []));
|
|
894
|
-
constructor() {
|
|
895
|
-
this.#isReducedMotion = prefersReducedMotion(this.#documentRef);
|
|
896
|
-
this.#stagger?.register(this.#host.nativeElement);
|
|
897
|
-
effect(() => {
|
|
898
|
-
const variantName = this.activeVariant();
|
|
899
|
-
if (!variantName)
|
|
900
|
-
return;
|
|
901
|
-
const variants = this.moveVariants();
|
|
902
|
-
if (!variants)
|
|
903
|
-
return;
|
|
904
|
-
const state = variants[variantName];
|
|
905
|
-
if (!state)
|
|
906
|
-
return;
|
|
907
|
-
this.#currentPlayer?.cancel();
|
|
908
|
-
const { spring, duration, easing, delay, ...keyframesMap } = state;
|
|
909
|
-
const keyframes = keyframesMap;
|
|
910
|
-
const staggerDelay = this.#stagger?.getDelay(this.#host.nativeElement) ?? 0;
|
|
911
|
-
const config = resolveMovementConfig(this.#defaults, {
|
|
912
|
-
duration: duration ?? this.moveDuration(),
|
|
913
|
-
easing: easing ?? this.moveEasing(),
|
|
914
|
-
delay: (delay ?? this.moveDelay() ?? 0) + staggerDelay,
|
|
915
|
-
disabled: this.moveDisabled(),
|
|
916
|
-
}, this.#isReducedMotion);
|
|
917
|
-
this.#currentPlayer = this.#engine.play(this.#host.nativeElement, keyframes, {
|
|
918
|
-
config,
|
|
919
|
-
spring: spring ?? this.moveSpring(),
|
|
920
|
-
disabled: config.disabled,
|
|
921
|
-
});
|
|
922
|
-
});
|
|
923
|
-
}
|
|
924
|
-
ngOnDestroy() {
|
|
925
|
-
this.#stagger?.unregister(this.#host.nativeElement);
|
|
926
|
-
this.#currentPlayer?.cancel();
|
|
927
|
-
}
|
|
928
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveVariantsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
929
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveVariantsDirective, isStandalone: true, selector: "[moveVariants]", inputs: { moveVariants: { classPropertyName: "moveVariants", publicName: "moveVariants", isSignal: true, isRequired: true, transformFunction: null }, moveAnimate: { classPropertyName: "moveAnimate", publicName: "moveAnimate", 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 } }, providers: [
|
|
930
|
-
{
|
|
931
|
-
provide: MOVE_VARIANTS_PARENT,
|
|
932
|
-
useExisting: forwardRef(() => MoveVariantsDirective),
|
|
933
|
-
},
|
|
934
|
-
], ngImport: i0 });
|
|
935
|
-
}
|
|
936
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveVariantsDirective, decorators: [{
|
|
937
|
-
type: Directive,
|
|
938
|
-
args: [{
|
|
939
|
-
selector: '[moveVariants]',
|
|
940
|
-
providers: [
|
|
941
|
-
{
|
|
942
|
-
provide: MOVE_VARIANTS_PARENT,
|
|
943
|
-
useExisting: forwardRef(() => MoveVariantsDirective),
|
|
944
|
-
},
|
|
945
|
-
],
|
|
946
|
-
}]
|
|
947
|
-
}], ctorParameters: () => [], propDecorators: { moveVariants: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveVariants", required: true }] }], moveAnimate: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveAnimate", 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 }] }] } });
|
|
948
|
-
|
|
949
1024
|
class MoveStaggerDirective {
|
|
950
1025
|
moveStagger = input.required(...(ngDevMode ? [{ debugName: "moveStagger" }] : /* istanbul ignore next */ []));
|
|
951
1026
|
moveStaggerDirection = input('first', ...(ngDevMode ? [{ debugName: "moveStaggerDirection" }] : /* istanbul ignore next */ []));
|
|
@@ -1029,7 +1104,11 @@ class MoveLayoutDirective {
|
|
|
1029
1104
|
this.#isAnimating) {
|
|
1030
1105
|
return null;
|
|
1031
1106
|
}
|
|
1032
|
-
const
|
|
1107
|
+
const el = this.#host.nativeElement;
|
|
1108
|
+
if (typeof el.getBoundingClientRect !== 'function') {
|
|
1109
|
+
return null;
|
|
1110
|
+
}
|
|
1111
|
+
const currentRect = el.getBoundingClientRect();
|
|
1033
1112
|
if (this.#snapshot) {
|
|
1034
1113
|
const dx = this.#snapshot.left - currentRect.left;
|
|
1035
1114
|
const dy = this.#snapshot.top - currentRect.top;
|
|
@@ -1338,7 +1417,7 @@ class MoveScrollDirective {
|
|
|
1338
1417
|
if (!view)
|
|
1339
1418
|
return;
|
|
1340
1419
|
this.#player = this.#engine.play(this.#host.nativeElement, keyframes, {
|
|
1341
|
-
config: { duration: 1000, easing: 'linear', delay: 0, disabled: false },
|
|
1420
|
+
config: { duration: 1000, easing: 'linear', delay: 0, disabled: false, iterations: 1 },
|
|
1342
1421
|
});
|
|
1343
1422
|
this.#player?.pause();
|
|
1344
1423
|
// Sync the new player to the current scroll position immediately.
|
|
@@ -2101,7 +2180,7 @@ class MoveParallaxDirective {
|
|
|
2101
2180
|
}
|
|
2102
2181
|
this.#player?.cancel();
|
|
2103
2182
|
this.#player = this.#engine.play(this.#host.nativeElement, frames, {
|
|
2104
|
-
config: { duration: 1000, delay: 0, easing: 'linear', disabled: false },
|
|
2183
|
+
config: { duration: 1000, delay: 0, easing: 'linear', disabled: false, iterations: 1 },
|
|
2105
2184
|
});
|
|
2106
2185
|
this.#player?.pause();
|
|
2107
2186
|
if (this.#player) {
|
|
@@ -2146,6 +2225,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
|
|
|
2146
2225
|
}]
|
|
2147
2226
|
}], ctorParameters: () => [], propDecorators: { moveParallax: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveParallax", required: false }] }], moveParallaxAxis: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveParallaxAxis", required: false }] }] } });
|
|
2148
2227
|
|
|
2228
|
+
class MoveLoopDirective {
|
|
2229
|
+
moveLoop = input('none', ...(ngDevMode ? [{ debugName: "moveLoop" }] : /* istanbul ignore next */ []));
|
|
2230
|
+
moveDuration = input(undefined, ...(ngDevMode ? [{ debugName: "moveDuration" }] : /* istanbul ignore next */ []));
|
|
2231
|
+
moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
|
|
2232
|
+
moveDelay = input(undefined, ...(ngDevMode ? [{ debugName: "moveDelay" }] : /* istanbul ignore next */ []));
|
|
2233
|
+
moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
|
|
2234
|
+
moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
|
|
2235
|
+
#defaults = inject(MOVEMENT_CONFIG);
|
|
2236
|
+
#documentRef = inject(DOCUMENT);
|
|
2237
|
+
#host = inject((ElementRef));
|
|
2238
|
+
#engine = inject(AnimationEngine);
|
|
2239
|
+
#player = null;
|
|
2240
|
+
ngOnInit() {
|
|
2241
|
+
const frames = resolveMoveFrames(this.moveLoop(), 'loop');
|
|
2242
|
+
// Skip noop presets to avoid creating an infinite animation that does nothing
|
|
2243
|
+
if (this.moveLoop() === 'none' || Object.keys(frames).length === 0) {
|
|
2244
|
+
return;
|
|
2245
|
+
}
|
|
2246
|
+
const isReduced = prefersReducedMotion(this.#documentRef);
|
|
2247
|
+
const config = resolveMovementConfig(this.#defaults, {
|
|
2248
|
+
duration: this.moveDuration(),
|
|
2249
|
+
easing: this.moveEasing(),
|
|
2250
|
+
delay: this.moveDelay(),
|
|
2251
|
+
disabled: this.moveDisabled(),
|
|
2252
|
+
}, isReduced);
|
|
2253
|
+
this.#player = this.#engine.play(this.#host.nativeElement, frames, {
|
|
2254
|
+
config,
|
|
2255
|
+
spring: this.moveSpring(),
|
|
2256
|
+
disabled: config.disabled,
|
|
2257
|
+
iterations: Infinity,
|
|
2258
|
+
});
|
|
2259
|
+
}
|
|
2260
|
+
ngOnDestroy() {
|
|
2261
|
+
this.#player?.cancel();
|
|
2262
|
+
}
|
|
2263
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveLoopDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2264
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveLoopDirective, isStandalone: true, selector: "[moveLoop]", inputs: { moveLoop: { classPropertyName: "moveLoop", publicName: "moveLoop", 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 });
|
|
2265
|
+
}
|
|
2266
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveLoopDirective, decorators: [{
|
|
2267
|
+
type: Directive,
|
|
2268
|
+
args: [{
|
|
2269
|
+
selector: '[moveLoop]',
|
|
2270
|
+
}]
|
|
2271
|
+
}], 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
|
+
|
|
2149
2273
|
function provideMovement(config = {}) {
|
|
2150
2274
|
return makeEnvironmentProviders([
|
|
2151
2275
|
{
|
|
@@ -2176,6 +2300,7 @@ const MOVEMENT_DIRECTIVES = [
|
|
|
2176
2300
|
MoveFocusDirective,
|
|
2177
2301
|
MoveParallaxDirective,
|
|
2178
2302
|
MoveAnimationDirective,
|
|
2303
|
+
MoveLoopDirective,
|
|
2179
2304
|
];
|
|
2180
2305
|
|
|
2181
2306
|
/*
|
|
@@ -2186,5 +2311,5 @@ const MOVEMENT_DIRECTIVES = [
|
|
|
2186
2311
|
* Generated bundle index. Do not edit.
|
|
2187
2312
|
*/
|
|
2188
2313
|
|
|
2189
|
-
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, MoveParallaxDirective, MovePresenceDirective, MoveScrollDirective, MoveSmoothScrollDirective, MoveStaggerDirective, MoveTapDirective, MoveTextDirective, MoveVariantsDirective, SmoothScrollService, SpringPlayer, WaapiPlayer, provideMovement };
|
|
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 };
|
|
2190
2315
|
//# sourceMappingURL=angular-movement.mjs.map
|