angular-movement 0.0.2 → 0.1.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,
@@ -241,6 +241,75 @@ const MOVE_PRESETS = {
241
241
  leave: { scale: [1, 0.95, 1] },
242
242
  loop: { scale: [1, 1.05, 1] },
243
243
  },
244
+ shake: {
245
+ enter: { opacity: DEFAULT_FADE_OPACITY, x: [0, -10, 10, -10, 10, -5, 5, -5, 5, 0] },
246
+ leave: { opacity: DEFAULT_LEAVE_OPACITY, x: [0, 10, -10, 10, -10, 5, -5, 5, -5, 0] },
247
+ },
248
+ swing: {
249
+ enter: { opacity: DEFAULT_FADE_OPACITY, rotate: [0, 15, -10, 5, -5, 0] },
250
+ leave: { opacity: DEFAULT_LEAVE_OPACITY, rotate: [0, -15, 10, -5, 5, 0] },
251
+ },
252
+ wobble: {
253
+ enter: {
254
+ opacity: DEFAULT_FADE_OPACITY,
255
+ x: [0, -25, 20, -15, 10, -5, 0],
256
+ rotate: [0, -5, 3, -3, 2, -1, 0],
257
+ },
258
+ leave: {
259
+ opacity: DEFAULT_LEAVE_OPACITY,
260
+ x: [0, 25, -20, 15, -10, 5, 0],
261
+ rotate: [0, 5, -3, 3, -2, 1, 0],
262
+ },
263
+ },
264
+ 'rubber-band': {
265
+ enter: {
266
+ opacity: DEFAULT_FADE_OPACITY,
267
+ scaleX: [1, 1.25, 0.75, 1.15, 0.95, 1.05, 1],
268
+ scaleY: [1, 0.75, 1.25, 0.85, 1.05, 0.95, 1],
269
+ },
270
+ leave: {
271
+ opacity: DEFAULT_LEAVE_OPACITY,
272
+ scaleX: [1, 1.25, 0.75, 1.15, 0.95, 1.05, 1],
273
+ scaleY: [1, 0.75, 1.25, 0.85, 1.05, 0.95, 1],
274
+ },
275
+ },
276
+ 'heart-beat': {
277
+ enter: { opacity: DEFAULT_FADE_OPACITY, scale: [1, 1.3, 1, 1.3, 1] },
278
+ leave: { opacity: DEFAULT_LEAVE_OPACITY, scale: [1, 1.3, 1, 1.3, 1] },
279
+ loop: { scale: [1, 1.3, 1, 1.3, 1] },
280
+ },
281
+ tada: {
282
+ enter: {
283
+ opacity: DEFAULT_FADE_OPACITY,
284
+ scale: [1, 0.9, 1.1, 1.1, 1.1, 1],
285
+ rotate: [0, -3, 3, -3, 3, 0],
286
+ },
287
+ leave: {
288
+ opacity: DEFAULT_LEAVE_OPACITY,
289
+ scale: [1, 0.9, 1.1, 1.1, 1.1, 1],
290
+ rotate: [0, 3, -3, 3, -3, 0],
291
+ },
292
+ },
293
+ jello: {
294
+ enter: {
295
+ opacity: DEFAULT_FADE_OPACITY,
296
+ scaleX: [1, 1.25, 0.75, 1.15, 0.95, 1.05, 1],
297
+ scaleY: [1, 0.75, 1.25, 0.85, 1.05, 0.95, 1],
298
+ },
299
+ leave: {
300
+ opacity: DEFAULT_LEAVE_OPACITY,
301
+ scaleX: [1, 1.25, 0.75, 1.15, 0.95, 1.05, 1],
302
+ scaleY: [1, 0.75, 1.25, 0.85, 1.05, 0.95, 1],
303
+ },
304
+ },
305
+ 'light-speed': {
306
+ enter: { opacity: [0, 1], x: [200, 0], scaleX: [0, 1] },
307
+ leave: { opacity: [1, 0], x: [0, 200], scaleX: [1, 0] },
308
+ },
309
+ 'roll-in': {
310
+ enter: { opacity: [0, 1], x: [-100, 0], rotate: [-120, 0] },
311
+ leave: { opacity: [1, 0], x: [0, 100], rotate: [0, 120] },
312
+ },
244
313
  none: {
245
314
  enter: { opacity: [1, 1] },
246
315
  leave: { opacity: [1, 1] },
@@ -310,6 +379,63 @@ function applyInitialStyles(el, frames) {
310
379
  function clearInitialStyles(el) {
311
380
  clearComposedStyle(el);
312
381
  }
382
+ /**
383
+ * Validates MoveSpring configuration and returns sanitized values.
384
+ * Warns in development mode for invalid values.
385
+ */
386
+ function validateSpring(spring) {
387
+ if (!spring)
388
+ return undefined;
389
+ const validated = {};
390
+ if (spring.stiffness !== undefined) {
391
+ if (spring.stiffness <= 0 && typeof ngDevMode !== 'undefined' && ngDevMode) {
392
+ console.warn('[Movement] Spring stiffness must be > 0. Using default.');
393
+ }
394
+ validated.stiffness = spring.stiffness > 0 ? spring.stiffness : 100;
395
+ }
396
+ if (spring.damping !== undefined) {
397
+ if (spring.damping < 0 && typeof ngDevMode !== 'undefined' && ngDevMode) {
398
+ console.warn('[Movement] Spring damping must be >= 0. Using default.');
399
+ }
400
+ validated.damping = spring.damping >= 0 ? spring.damping : 10;
401
+ }
402
+ if (spring.mass !== undefined) {
403
+ if (spring.mass <= 0 && typeof ngDevMode !== 'undefined' && ngDevMode) {
404
+ console.warn('[Movement] Spring mass must be > 0. Using default.');
405
+ }
406
+ validated.mass = spring.mass > 0 ? spring.mass : 1;
407
+ }
408
+ if (spring.velocity !== undefined) {
409
+ validated.velocity = spring.velocity;
410
+ }
411
+ return validated;
412
+ }
413
+ /**
414
+ * Validates scroll offset string format "elFraction viewFraction".
415
+ * Returns true if valid, warns in dev mode if invalid.
416
+ */
417
+ function isValidScrollOffset(offset) {
418
+ const parts = offset.split(' ').map(parseFloat);
419
+ if (parts.length !== 2 || parts.some(Number.isNaN)) {
420
+ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
421
+ console.warn(`[Movement] Invalid scroll offset: "${offset}". Expected format "elFraction viewFraction" (e.g. "0 1").`);
422
+ }
423
+ return false;
424
+ }
425
+ return true;
426
+ }
427
+ /**
428
+ * Validates drag elastic factor. Must be between 0 and 1.
429
+ */
430
+ function validateDragElastic(elastic) {
431
+ if (elastic < 0 || elastic > 1) {
432
+ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
433
+ console.warn(`[Movement] Drag elastic must be between 0 and 1. Got ${elastic}. Clamping to range.`);
434
+ }
435
+ return Math.max(0, Math.min(1, elastic));
436
+ }
437
+ return elastic;
438
+ }
313
439
 
314
440
  class WaapiPlayer {
315
441
  #animation = null;
@@ -521,15 +647,18 @@ class AnimationEngine {
521
647
  return null;
522
648
  }
523
649
  if (options.disabled) {
650
+ this.#prepareSvgStrokeDraw(host, frames);
524
651
  this.#applyFinalStyles(host, frames);
525
652
  options.onDone?.();
526
653
  return null;
527
654
  }
655
+ this.#prepareSvgStrokeDraw(host, frames);
528
656
  const config = options.config ?? this.#defaults;
529
- const isSpring = options.spring || config.easing === 'spring';
657
+ const spring = validateSpring(options.spring);
658
+ const isSpring = spring || config.easing === 'spring';
530
659
  const iterations = options.iterations ?? config.iterations;
531
660
  if (isSpring) {
532
- return new SpringPlayer(host, frames, options.spring ?? {}, options.delay ?? config.delay, iterations, options.onDone);
661
+ return new SpringPlayer(host, frames, spring ?? {}, options.delay ?? config.delay, iterations, options.onDone);
533
662
  }
534
663
  else {
535
664
  return new WaapiPlayer(host, frames, {
@@ -544,6 +673,29 @@ class AnimationEngine {
544
673
  #applyFinalStyles(host, frames) {
545
674
  applyComposedStyle(host, composeFinalStyle(frames));
546
675
  }
676
+ #prepareSvgStrokeDraw(host, frames) {
677
+ if (!frames['strokeDashoffset'] || !this.#isSvgGeometryElement(host)) {
678
+ return;
679
+ }
680
+ let length = 28;
681
+ try {
682
+ length = host.getTotalLength() || length;
683
+ }
684
+ catch {
685
+ length = 28;
686
+ }
687
+ const styledHost = host;
688
+ styledHost.style.strokeDasharray = `${length}`;
689
+ styledHost.style.strokeDashoffset = `${length}`;
690
+ }
691
+ #isSvgGeometryElement(host) {
692
+ const view = host.ownerDocument?.defaultView;
693
+ const SvgGeometryElement = view?.SVGGeometryElement;
694
+ if (typeof SvgGeometryElement === 'function' && host instanceof SvgGeometryElement) {
695
+ return true;
696
+ }
697
+ return typeof host.getTotalLength === 'function';
698
+ }
547
699
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: AnimationEngine, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
548
700
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: AnimationEngine, providedIn: 'root' });
549
701
  }
@@ -1035,9 +1187,14 @@ class MoveStaggerDirective {
1035
1187
  if (!this.#children.has(el))
1036
1188
  return 0;
1037
1189
  const list = Array.from(this.#children).sort((a, b) => {
1038
- // Unreliable on detached elements, but they are in DOM when sorting
1190
+ if (a === b)
1191
+ return 0;
1039
1192
  const pos = a.compareDocumentPosition(b);
1040
- return pos & Node.DOCUMENT_POSITION_PRECEDING ? 1 : -1;
1193
+ if (pos & Node.DOCUMENT_POSITION_PRECEDING)
1194
+ return 1;
1195
+ if (pos & Node.DOCUMENT_POSITION_FOLLOWING)
1196
+ return -1;
1197
+ return 0;
1041
1198
  });
1042
1199
  const index = list.indexOf(el);
1043
1200
  if (index === -1)
@@ -1416,6 +1573,11 @@ class MoveScrollDirective {
1416
1573
  const view = this.#documentRef.defaultView;
1417
1574
  if (!view)
1418
1575
  return;
1576
+ // Validate scroll offsets
1577
+ const offsets = this.moveScrollOffset();
1578
+ if (!isValidScrollOffset(offsets[0]) || !isValidScrollOffset(offsets[1])) {
1579
+ return;
1580
+ }
1419
1581
  this.#player = this.#engine.play(this.#host.nativeElement, keyframes, {
1420
1582
  config: { duration: 1000, easing: 'linear', delay: 0, disabled: false, iterations: 1 },
1421
1583
  });
@@ -1658,7 +1820,9 @@ class MoveDragDirective {
1658
1820
  return;
1659
1821
  this.#isDragging = true;
1660
1822
  this.#pointerId = e.pointerId;
1661
- this.#host.nativeElement.setPointerCapture(e.pointerId);
1823
+ if (typeof this.#host.nativeElement.setPointerCapture === 'function') {
1824
+ this.#host.nativeElement.setPointerCapture(e.pointerId);
1825
+ }
1662
1826
  this.#player?.cancel();
1663
1827
  // read bounds cleanly before next render
1664
1828
  this.#dragBounds = this.resolveBounds();
@@ -1679,7 +1843,9 @@ class MoveDragDirective {
1679
1843
  if (!this.#isDragging || e.pointerId !== this.#pointerId)
1680
1844
  return;
1681
1845
  this.#isDragging = false;
1682
- this.#host.nativeElement.releasePointerCapture(e.pointerId);
1846
+ if (typeof this.#host.nativeElement.releasePointerCapture === 'function') {
1847
+ this.#host.nativeElement.releasePointerCapture(e.pointerId);
1848
+ }
1683
1849
  this.#pointerId = null;
1684
1850
  this.#host.nativeElement.style.touchAction = '';
1685
1851
  this.#host.nativeElement.style.userSelect = '';
@@ -1708,7 +1874,7 @@ class MoveDragDirective {
1708
1874
  let x = this.#_x;
1709
1875
  let y = this.#_y;
1710
1876
  if (this.#dragBounds) {
1711
- const elastic = this.moveDragElastic();
1877
+ const elastic = validateDragElastic(this.moveDragElastic());
1712
1878
  if (this.#dragBounds.left !== undefined && x < this.#dragBounds.left) {
1713
1879
  x = this.#dragBounds.left - (this.#dragBounds.left - x) * elastic;
1714
1880
  }
@@ -1742,7 +1908,7 @@ class MoveDragDirective {
1742
1908
  // Find the currently visible coordinates (which include elasticity)
1743
1909
  let currentVisX = this.#_x;
1744
1910
  let currentVisY = this.#_y;
1745
- const elastic = this.moveDragElastic();
1911
+ const elastic = validateDragElastic(this.moveDragElastic());
1746
1912
  if (this.#dragBounds.left !== undefined && this.#_x < this.#dragBounds.left) {
1747
1913
  currentVisX = this.#dragBounds.left - (this.#dragBounds.left - this.#_x) * elastic;
1748
1914
  }
@@ -1768,6 +1934,19 @@ class MoveDragDirective {
1768
1934
  }
1769
1935
  }
1770
1936
  ngOnDestroy() {
1937
+ if (this.#pointerId !== null) {
1938
+ try {
1939
+ if (typeof this.#host.nativeElement.releasePointerCapture === 'function') {
1940
+ this.#host.nativeElement.releasePointerCapture(this.#pointerId);
1941
+ }
1942
+ }
1943
+ catch {
1944
+ // Element may already be detached
1945
+ }
1946
+ this.#pointerId = null;
1947
+ }
1948
+ this.#host.nativeElement.style.touchAction = '';
1949
+ this.#host.nativeElement.style.userSelect = '';
1771
1950
  this.#player?.cancel();
1772
1951
  }
1773
1952
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveDragDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
@@ -1888,6 +2067,7 @@ class MoveTextDirective {
1888
2067
  #platformId = inject(PLATFORM_ID);
1889
2068
  #host = inject((ElementRef));
1890
2069
  #engine = inject(AnimationEngine);
2070
+ #renderer = inject(Renderer2);
1891
2071
  #players = [];
1892
2072
  #spans = [];
1893
2073
  #observer = null;
@@ -1948,21 +2128,24 @@ class MoveTextDirective {
1948
2128
  #splitText() {
1949
2129
  const el = this.#host.nativeElement;
1950
2130
  const text = (el.textContent ?? '').trim();
1951
- el.innerHTML = '';
1952
- el.setAttribute('aria-label', text);
2131
+ // Clear existing content safely via Renderer2
2132
+ while (el.firstChild) {
2133
+ this.#renderer.removeChild(el, el.firstChild);
2134
+ }
2135
+ this.#renderer.setAttribute(el, 'aria-label', text);
1953
2136
  const byChars = this.moveTextSplit() === 'chars';
1954
2137
  if (byChars) {
1955
2138
  // Split character by character, preserving spaces as text nodes
1956
2139
  [...text].forEach((char) => {
1957
2140
  if (char === ' ') {
1958
- el.appendChild(this.#documentRef.createTextNode(' '));
2141
+ this.#renderer.appendChild(el, this.#documentRef.createTextNode(' '));
1959
2142
  return;
1960
2143
  }
1961
- const span = this.#documentRef.createElement('span');
1962
- span.setAttribute('aria-hidden', 'true');
1963
- span.style.display = 'inline-block';
1964
- span.textContent = char;
1965
- el.appendChild(span);
2144
+ const span = this.#renderer.createElement('span');
2145
+ this.#renderer.setAttribute(span, 'aria-hidden', 'true');
2146
+ this.#renderer.setStyle(span, 'display', 'inline-block');
2147
+ this.#renderer.setProperty(span, 'textContent', char);
2148
+ this.#renderer.appendChild(el, span);
1966
2149
  this.#spans.push(span);
1967
2150
  });
1968
2151
  }
@@ -1970,12 +2153,12 @@ class MoveTextDirective {
1970
2153
  // Split word by word
1971
2154
  const words = text.split(/\s+/);
1972
2155
  words.forEach((word, index) => {
1973
- const span = this.#documentRef.createElement('span');
1974
- span.setAttribute('aria-hidden', 'true');
1975
- span.style.display = 'inline-block';
1976
- span.style.whiteSpace = 'pre';
1977
- span.textContent = index < words.length - 1 ? word + ' ' : word;
1978
- el.appendChild(span);
2156
+ const span = this.#renderer.createElement('span');
2157
+ this.#renderer.setAttribute(span, 'aria-hidden', 'true');
2158
+ this.#renderer.setStyle(span, 'display', 'inline-block');
2159
+ this.#renderer.setStyle(span, 'white-space', 'pre');
2160
+ this.#renderer.setProperty(span, 'textContent', index < words.length - 1 ? word + ' ' : word);
2161
+ this.#renderer.appendChild(el, span);
1979
2162
  this.#spans.push(span);
1980
2163
  });
1981
2164
  }
@@ -1983,6 +2166,8 @@ class MoveTextDirective {
1983
2166
  ngOnDestroy() {
1984
2167
  this.#observer?.disconnect();
1985
2168
  this.#players.forEach((p) => p.cancel());
2169
+ this.#players = [];
2170
+ this.#spans = [];
1986
2171
  }
1987
2172
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1988
2173
  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 +2455,85 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
2270
2455
  }]
2271
2456
  }], 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
2457
 
2458
+ function optionalNumberAttribute(value) {
2459
+ if (value === undefined || value === null || value === '') {
2460
+ return undefined;
2461
+ }
2462
+ return Number(value);
2463
+ }
2464
+ class MoveTargetDirective {
2465
+ moveTarget = input.required(...(ngDevMode ? [{ debugName: "moveTarget" }] : /* istanbul ignore next */ []));
2466
+ moveFrames = input.required(...(ngDevMode ? [{ debugName: "moveFrames" }] : /* istanbul ignore next */ []));
2467
+ moveDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
2468
+ moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
2469
+ moveDelay = input(undefined, { ...(ngDevMode ? { debugName: "moveDelay" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
2470
+ moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
2471
+ moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
2472
+ moveReverseDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveReverseDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
2473
+ moveReverseEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveReverseEasing" }] : /* istanbul ignore next */ []));
2474
+ #defaults = inject(MOVEMENT_CONFIG);
2475
+ #documentRef = inject(DOCUMENT);
2476
+ #host = inject((ElementRef));
2477
+ #engine = inject(AnimationEngine);
2478
+ #currentPlayer = null;
2479
+ #hasPlayedForward = false;
2480
+ #targetEffect = effect(() => {
2481
+ const active = this.moveTarget();
2482
+ const frames = this.moveFrames();
2483
+ if (active) {
2484
+ this.#playForward(frames);
2485
+ this.#hasPlayedForward = true;
2486
+ return;
2487
+ }
2488
+ if (this.#hasPlayedForward) {
2489
+ this.#playReverse(frames);
2490
+ }
2491
+ }, ...(ngDevMode ? [{ debugName: "#targetEffect" }] : /* istanbul ignore next */ []));
2492
+ #playForward(frames) {
2493
+ this.#currentPlayer?.cancel();
2494
+ const isReduced = prefersReducedMotion(this.#documentRef);
2495
+ const config = resolveMovementConfig(this.#defaults, {
2496
+ duration: this.moveDuration(),
2497
+ easing: this.moveEasing(),
2498
+ delay: this.moveDelay(),
2499
+ disabled: this.moveDisabled(),
2500
+ }, isReduced);
2501
+ this.#currentPlayer = this.#engine.play(this.#host.nativeElement, frames, {
2502
+ config,
2503
+ spring: this.moveSpring(),
2504
+ disabled: config.disabled,
2505
+ });
2506
+ }
2507
+ #playReverse(frames) {
2508
+ this.#currentPlayer?.cancel();
2509
+ const isReduced = prefersReducedMotion(this.#documentRef);
2510
+ const config = resolveMovementConfig({ ...this.#defaults, duration: 200, easing: 'ease-out', delay: 0 }, {
2511
+ duration: this.moveReverseDuration() ?? this.moveDuration(),
2512
+ easing: this.moveReverseEasing(),
2513
+ delay: 0,
2514
+ disabled: this.moveDisabled(),
2515
+ }, isReduced);
2516
+ this.#currentPlayer = this.#engine.play(this.#host.nativeElement, reverseFrames(frames), {
2517
+ config,
2518
+ spring: this.moveSpring(),
2519
+ disabled: config.disabled,
2520
+ });
2521
+ }
2522
+ ngOnDestroy() {
2523
+ this.#targetEffect.destroy();
2524
+ this.#currentPlayer?.cancel();
2525
+ }
2526
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTargetDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2527
+ 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 } }, ngImport: i0 });
2528
+ }
2529
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTargetDirective, decorators: [{
2530
+ type: Directive,
2531
+ args: [{
2532
+ selector: '[moveTarget]',
2533
+ standalone: true,
2534
+ }]
2535
+ }], 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 }] }] } });
2536
+
2273
2537
  function provideMovement(config = {}) {
2274
2538
  return makeEnvironmentProviders([
2275
2539
  {
@@ -2301,6 +2565,7 @@ const MOVEMENT_DIRECTIVES = [
2301
2565
  MoveParallaxDirective,
2302
2566
  MoveAnimationDirective,
2303
2567
  MoveLoopDirective,
2568
+ MoveTargetDirective,
2304
2569
  ];
2305
2570
 
2306
2571
  /*
@@ -2311,5 +2576,5 @@ const MOVEMENT_DIRECTIVES = [
2311
2576
  * Generated bundle index. Do not edit.
2312
2577
  */
2313
2578
 
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 };
2579
+ 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, MoveVariantsDirective, SmoothScrollService, SpringPlayer, WaapiPlayer, applyInitialStyles, clearInitialStyles, isValidScrollOffset, prefersReducedMotion, provideMovement, resolveMoveFrames, resolveMovementConfig, reverseFrames, validateDragElastic, validateSpring };
2315
2580
  //# sourceMappingURL=angular-movement.mjs.map