@praxisjs/motion 0.2.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/__tests__/decorators.test.d.ts +2 -0
  3. package/dist/__tests__/decorators.test.d.ts.map +1 -0
  4. package/dist/__tests__/decorators.test.js +139 -0
  5. package/dist/__tests__/decorators.test.js.map +1 -0
  6. package/dist/__tests__/easings.test.js +64 -55
  7. package/dist/__tests__/easings.test.js.map +1 -1
  8. package/dist/__tests__/spring.test.js +59 -34
  9. package/dist/__tests__/spring.test.js.map +1 -1
  10. package/dist/__tests__/transition.test.js +71 -44
  11. package/dist/__tests__/transition.test.js.map +1 -1
  12. package/dist/__tests__/tween.test.js +74 -94
  13. package/dist/__tests__/tween.test.js.map +1 -1
  14. package/dist/decorators.d.ts +3 -1
  15. package/dist/decorators.d.ts.map +1 -1
  16. package/dist/decorators.js +39 -16
  17. package/dist/decorators.js.map +1 -1
  18. package/dist/index.d.ts +2 -10
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1 -6
  21. package/dist/index.js.map +1 -1
  22. package/package.json +3 -2
  23. package/src/__tests__/decorators.test.ts +152 -0
  24. package/src/__tests__/easings.test.ts +66 -59
  25. package/src/__tests__/spring.test.ts +66 -34
  26. package/src/__tests__/transition.test.ts +74 -46
  27. package/src/__tests__/tween.test.ts +77 -95
  28. package/src/decorators.ts +42 -15
  29. package/src/index.ts +2 -15
  30. package/dist/__tests__/use-motion.test.d.ts +0 -2
  31. package/dist/__tests__/use-motion.test.d.ts.map +0 -1
  32. package/dist/__tests__/use-motion.test.js +0 -139
  33. package/dist/__tests__/use-motion.test.js.map +0 -1
  34. package/dist/use-motion.d.ts +0 -20
  35. package/dist/use-motion.d.ts.map +0 -1
  36. package/dist/use-motion.js +0 -58
  37. package/dist/use-motion.js.map +0 -1
  38. package/src/__tests__/use-motion.test.ts +0 -172
  39. package/src/use-motion.ts +0 -89
@@ -1,136 +1,118 @@
1
1
  // @vitest-environment jsdom
2
- import { describe, it, expect, vi } from "vitest";
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
3
3
 
4
- import { Animate } from "../decorators";
5
4
  import { tween } from "../tween";
6
5
 
7
- // ── tween ─────────────────────────────────────────────────────────────────────
6
+ beforeEach(() => {
7
+ vi.useFakeTimers();
8
+ });
9
+
10
+ afterEach(() => {
11
+ vi.clearAllTimers();
12
+ vi.useRealTimers();
13
+ });
14
+
15
+ function flushRaf(frames = 60) {
16
+ for (let i = 0; i < frames; i++) {
17
+ vi.runAllTicks();
18
+ const cbs = (globalThis as unknown as { __rafCallbacks?: Array<(t: number) => void> }).__rafCallbacks;
19
+ if (cbs?.length) {
20
+ const batch = [...cbs];
21
+ cbs.length = 0;
22
+ batch.forEach((cb) => cb(performance.now()));
23
+ }
24
+ }
25
+ }
8
26
 
9
- describe("tween", () => {
10
- it("starts with the from value", () => {
11
- vi.useFakeTimers();
27
+ describe("tween()", () => {
28
+ it("starts at the `from` value", () => {
12
29
  const t = tween(0, 100);
13
30
  expect(t.value()).toBe(0);
14
- vi.clearAllTimers();
15
- vi.useRealTimers();
31
+ t.stop();
16
32
  });
17
33
 
18
- it("target starts at the to value", () => {
19
- vi.useFakeTimers();
34
+ it("exposes the target signal", () => {
20
35
  const t = tween(0, 100);
21
36
  expect(t.target()).toBe(100);
22
- vi.clearAllTimers();
23
- vi.useRealTimers();
37
+ t.stop();
24
38
  });
25
39
 
26
- it("playing is initially true (animation started immediately)", () => {
27
- vi.useFakeTimers();
40
+ it("playing is true when animating", () => {
28
41
  const t = tween(0, 100);
29
42
  expect(t.playing()).toBe(true);
30
- vi.clearAllTimers();
31
- vi.useRealTimers();
43
+ t.stop();
32
44
  });
33
45
 
34
- it("stop() sets playing to false", () => {
35
- vi.useFakeTimers();
46
+ it("stop() halts animation and sets playing to false", () => {
36
47
  const t = tween(0, 100);
37
48
  t.stop();
38
49
  expect(t.playing()).toBe(false);
39
- vi.clearAllTimers();
40
- vi.useRealTimers();
41
50
  });
42
51
 
43
- it("reset() restores to from value and clears progress", () => {
44
- vi.useFakeTimers();
45
- const t = tween(5, 100);
52
+ it("reset() returns value to `from` and resets progress", () => {
53
+ const t = tween(0, 100);
54
+ t.stop();
46
55
  t.reset();
47
- expect(t.value()).toBe(5);
56
+ expect(t.value()).toBe(0);
48
57
  expect(t.progress()).toBe(0);
49
- vi.clearAllTimers();
50
- vi.useRealTimers();
51
58
  });
52
59
 
53
- it("progress moves towards 1 as animation advances", () => {
54
- vi.useFakeTimers();
55
- const t = tween(0, 100, { duration: 300 });
56
- vi.advanceTimersByTime(300);
57
- // After full duration, value should be near the target
58
- expect(t.progress()).toBeGreaterThanOrEqual(0);
59
- vi.clearAllTimers();
60
- vi.useRealTimers();
60
+ it("progress starts at 0", () => {
61
+ const t = tween(0, 100);
62
+ expect(t.progress()).toBe(0);
63
+ t.stop();
61
64
  });
62
65
 
63
- it("changing target restarts animation", () => {
64
- vi.useFakeTimers();
65
- const t = tween(0, 50);
66
- t.target.set(200);
67
- expect(t.playing()).toBe(true);
66
+ it("accepts custom easing as function", () => {
67
+ const t = tween(0, 100, { easing: (x) => x, duration: 300 });
68
+ expect(t.value()).toBe(0);
68
69
  t.stop();
69
- vi.clearAllTimers();
70
- vi.useRealTimers();
71
70
  });
72
71
 
73
- it("accepts custom easing and delay options", () => {
74
- vi.useFakeTimers();
75
- const t = tween(0, 100, { easing: "linear", delay: 100, duration: 200 });
72
+ it("accepts custom duration and delay", () => {
73
+ const t = tween(0, 100, { duration: 500, delay: 100 });
76
74
  expect(t.value()).toBe(0);
77
- vi.clearAllTimers();
78
- vi.useRealTimers();
75
+ t.stop();
79
76
  });
80
- });
81
77
 
82
- // ── Animate decorator ─────────────────────────────────────────────────────────
83
-
84
- describe("Animate decorator", () => {
85
- function makeCtx(name: string) {
86
- const initializers: Array<(this: unknown) => void> = [];
87
- return {
88
- ctx: {
89
- name,
90
- kind: "field" as const,
91
- addInitializer(fn: (this: unknown) => void) {
92
- initializers.push(fn);
93
- },
94
- } as ClassFieldDecoratorContext,
95
- run(instance: unknown) {
96
- initializers.forEach((fn) => { fn.call(instance); });
97
- },
98
- };
99
- }
78
+ it("setting target to same value re-triggers start", () => {
79
+ const t = tween(0, 50);
80
+ const before = t.value();
81
+ t.target.set(50);
82
+ expect(t.value()).toBe(before);
83
+ t.stop();
84
+ });
100
85
 
101
- it("creates a numeric getter/setter on first assignment", () => {
102
- vi.useFakeTimers();
103
- const { ctx, run } = makeCtx("x");
104
- Animate()(undefined, ctx);
105
- const instance: Record<string, unknown> = {};
106
- run(instance);
107
- instance.x = 10;
108
- expect(typeof instance.x).toBe("number");
109
- vi.clearAllTimers();
110
- vi.useRealTimers();
86
+ it("changing target while playing updates target", () => {
87
+ const t = tween(0, 100);
88
+ t.target.set(200);
89
+ expect(t.target()).toBe(200);
90
+ t.stop();
91
+ });
92
+
93
+ it("animate loop runs and updates value toward target", () => {
94
+ const t = tween(0, 100, { duration: 100, easing: "linear" });
95
+ // Advance through multiple rAF frames
96
+ vi.advanceTimersByTime(50);
97
+ // Value should be moving toward 100
98
+ const mid = t.value();
99
+ expect(mid).toBeGreaterThan(0);
100
+ vi.advanceTimersByTime(100);
101
+ t.stop();
111
102
  });
112
103
 
113
- it("returns 0 before any value is set", () => {
114
- vi.useFakeTimers();
115
- const { ctx, run } = makeCtx("opacity");
116
- Animate()(undefined, ctx);
117
- const instance: Record<string, unknown> = {};
118
- run(instance);
119
- expect(instance.opacity).toBe(0);
120
- vi.clearAllTimers();
121
- vi.useRealTimers();
104
+ it("completes animation and stops playing", () => {
105
+ const t = tween(0, 100, { duration: 100 });
106
+ vi.advanceTimersByTime(500);
107
+ // After several durations, value should be at or near target
108
+ expect(t.value()).toBeGreaterThan(50);
122
109
  });
123
110
 
124
- it("updating the property updates the tween target", () => {
125
- vi.useFakeTimers();
126
- const { ctx, run } = makeCtx("scale");
127
- Animate()(undefined, ctx);
128
- const instance: Record<string, unknown> = {};
129
- run(instance);
130
- instance.scale = 1;
131
- instance.scale = 2; // second set updates tween target
132
- expect(typeof instance.scale).toBe("number");
133
- vi.clearAllTimers();
134
- vi.useRealTimers();
111
+ it("delay defers animation start", () => {
112
+ const t = tween(0, 100, { duration: 100, delay: 50 });
113
+ vi.advanceTimersByTime(10);
114
+ // Within delay, value stays at 0
115
+ expect(t.value()).toBe(0);
116
+ t.stop();
135
117
  });
136
118
  });
package/src/decorators.ts CHANGED
@@ -1,21 +1,48 @@
1
+ import { createFieldDecorator, type FieldBinding } from "@praxisjs/decorators";
2
+
3
+ import { spring, type SpringOptions } from "./spring";
1
4
  import { tween, type TweenOptions, type Tween } from "./tween";
2
5
 
3
- export function Animate(options: TweenOptions = {}) {
4
- return function (_value: undefined, context: ClassFieldDecoratorContext): void {
5
- const tweens = new WeakMap<object, Tween>();
6
+ type SpringInstance = ReturnType<typeof spring>;
7
+
8
+ export function Tween(options: TweenOptions = {}) {
9
+ const tweens = new WeakMap<object, Tween>();
6
10
 
7
- context.addInitializer(function (this: unknown) {
8
- Object.defineProperty(this, context.name, {
9
- get(this: object): number {
10
- return tweens.get(this)?.value() ?? 0;
11
+ return createFieldDecorator({
12
+ bind(_instance, _name, _initialValue): FieldBinding {
13
+ return {
14
+ descriptor: {
15
+ get(this: object): number {
16
+ return tweens.get(this)?.value() ?? 0;
17
+ },
18
+ set(this: object, value: number): void {
19
+ if (!tweens.has(this)) tweens.set(this, tween(value, value, options));
20
+ tweens.get(this)?.target.set(value);
21
+ },
11
22
  },
12
- set(this: object, value: number): void {
13
- if (!tweens.has(this)) tweens.set(this, tween(value, value, options));
14
- tweens.get(this)?.target.set(value);
23
+ };
24
+ },
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ }) as unknown as (_value: undefined, context: ClassFieldDecoratorContext<any>) => void;
27
+ }
28
+
29
+ export function Spring(options: SpringOptions = {}) {
30
+ const springs = new WeakMap<object, SpringInstance>();
31
+
32
+ return createFieldDecorator({
33
+ bind(_instance, _name, _initialValue): FieldBinding {
34
+ return {
35
+ descriptor: {
36
+ get(this: object): number {
37
+ return springs.get(this)?.value() ?? 0;
38
+ },
39
+ set(this: object, value: number): void {
40
+ if (!springs.has(this)) springs.set(this, spring(value, options));
41
+ springs.get(this)?.target.set(value);
42
+ },
15
43
  },
16
- enumerable: true,
17
- configurable: true,
18
- });
19
- });
20
- };
44
+ };
45
+ },
46
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
+ }) as unknown as (_value: undefined, context: ClassFieldDecoratorContext<any>) => void;
21
48
  }
package/src/index.ts CHANGED
@@ -1,16 +1,3 @@
1
- export { easings, resolveEasing } from "./easings";
2
- export type { Easing } from "./easings";
3
-
4
- export { tween } from "./tween";
5
- export type { Tween, TweenOptions } from "./tween";
6
-
7
- export { spring } from "./spring";
1
+ export { Tween, Spring } from "./decorators";
2
+ export type { TweenOptions } from "./tween";
8
3
  export type { SpringOptions } from "./spring";
9
-
10
- export { useMotion } from "./use-motion";
11
- export type { MotionKeyframes } from "./use-motion";
12
-
13
- export { createTransition } from "./transition";
14
- export type { TransitionOptions } from "./transition";
15
-
16
- export { Animate } from "./decorators";
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=use-motion.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-motion.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/use-motion.test.ts"],"names":[],"mappings":""}
@@ -1,139 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
3
- import { useMotion } from "../use-motion";
4
- function makeRef(el = null) {
5
- return { current: el };
6
- }
7
- describe("useMotion", () => {
8
- beforeEach(() => {
9
- vi.useFakeTimers();
10
- });
11
- afterEach(() => {
12
- vi.clearAllTimers();
13
- vi.useRealTimers();
14
- });
15
- it("returns animate, enter, and exit functions", () => {
16
- const ref = makeRef(document.createElement("div"));
17
- const m = useMotion(ref);
18
- expect(typeof m.animate).toBe("function");
19
- expect(typeof m.enter).toBe("function");
20
- expect(typeof m.exit).toBe("function");
21
- });
22
- it("returns a cancel function when ref.current is null", () => {
23
- const ref = makeRef(null);
24
- const m = useMotion(ref);
25
- const cancel = m.animate({ opacity: [0, 1] });
26
- expect(typeof cancel).toBe("function");
27
- // calling cancel on null ref should not throw
28
- expect(() => { cancel(); }).not.toThrow();
29
- });
30
- it("sets opacity style during animation", async () => {
31
- const el = document.createElement("div");
32
- const ref = makeRef(el);
33
- const m = useMotion(ref);
34
- const rafCallbacks = [];
35
- vi.spyOn(window, "requestAnimationFrame").mockImplementation((cb) => {
36
- rafCallbacks.push(cb);
37
- return 1;
38
- });
39
- m.animate({ opacity: [0, 1], duration: 100 });
40
- // Simulate first frame at t=50 (half way through)
41
- rafCallbacks[0]?.(50);
42
- expect(el.style.opacity).not.toBe("");
43
- });
44
- it("sets transform style for x, y, scale, rotate", () => {
45
- const el = document.createElement("div");
46
- const ref = makeRef(el);
47
- const m = useMotion(ref);
48
- const rafCallbacks = [];
49
- vi.spyOn(window, "requestAnimationFrame").mockImplementation((cb) => {
50
- rafCallbacks.push(cb);
51
- return 1;
52
- });
53
- m.animate({ x: [0, 100], y: [0, 50], scale: [1, 2], rotate: [0, 90], duration: 200 });
54
- rafCallbacks[0]?.(100);
55
- expect(el.style.transform).toContain("translateX");
56
- expect(el.style.transform).toContain("translateY");
57
- expect(el.style.transform).toContain("scale");
58
- expect(el.style.transform).toContain("rotate");
59
- });
60
- it("calls onComplete when animation finishes", () => {
61
- const el = document.createElement("div");
62
- const ref = makeRef(el);
63
- const m = useMotion(ref);
64
- const onComplete = vi.fn();
65
- const rafCallbacks = [];
66
- vi.spyOn(window, "requestAnimationFrame").mockImplementation((cb) => {
67
- rafCallbacks.push(cb);
68
- return rafCallbacks.length;
69
- });
70
- m.animate({ opacity: [0, 1], duration: 100, onComplete });
71
- // First frame sets startTime = 0
72
- rafCallbacks[0](0);
73
- // Second frame at ts=100: elapsed=100, t=1, onComplete fires
74
- rafCallbacks[1](100);
75
- expect(onComplete).toHaveBeenCalledTimes(1);
76
- });
77
- it("cancel() stops the animation", () => {
78
- const el = document.createElement("div");
79
- const ref = makeRef(el);
80
- const m = useMotion(ref);
81
- const cancelRaf = vi.fn();
82
- const rafCallbacks = [];
83
- vi.spyOn(window, "requestAnimationFrame").mockImplementation((cb) => {
84
- rafCallbacks.push(cb);
85
- return 42;
86
- });
87
- vi.spyOn(window, "cancelAnimationFrame").mockImplementation(cancelRaf);
88
- const cancel = m.animate({ opacity: [0, 1], duration: 300 });
89
- cancel();
90
- // After cancel, further frames should be no-ops
91
- rafCallbacks[0]?.(100);
92
- expect(cancelRaf).toHaveBeenCalledWith(42);
93
- });
94
- it("exit() reverses opacity and x/y values", () => {
95
- const el = document.createElement("div");
96
- const ref = makeRef(el);
97
- const m = useMotion(ref);
98
- const rafCallbacks = [];
99
- vi.spyOn(window, "requestAnimationFrame").mockImplementation((cb) => {
100
- rafCallbacks.push(cb);
101
- return 1;
102
- });
103
- // exit reverses opacity [0,1] → animates [1,0] and x [0,100] → [100,0]
104
- m.exit({ opacity: [0, 1], x: [0, 100], duration: 100 });
105
- rafCallbacks[0]?.(0);
106
- // At t=0 (start), opacity should be 1 (the reversed start)
107
- expect(el.style.opacity).toBe("1");
108
- });
109
- it("enter() is an alias for animate()", () => {
110
- const el = document.createElement("div");
111
- const ref = makeRef(el);
112
- const m = useMotion(ref);
113
- const onComplete = vi.fn();
114
- const rafCallbacks = [];
115
- vi.spyOn(window, "requestAnimationFrame").mockImplementation((cb) => {
116
- rafCallbacks.push(cb);
117
- return rafCallbacks.length;
118
- });
119
- m.enter({ opacity: [0, 1], duration: 50, onComplete });
120
- rafCallbacks[0](0); // sets startTime=0
121
- rafCallbacks[1](50); // elapsed=50, t=1
122
- expect(onComplete).toHaveBeenCalledTimes(1);
123
- });
124
- it("respects delay option — no progress before delay elapses", () => {
125
- const el = document.createElement("div");
126
- const ref = makeRef(el);
127
- const m = useMotion(ref);
128
- const rafCallbacks = [];
129
- vi.spyOn(window, "requestAnimationFrame").mockImplementation((cb) => {
130
- rafCallbacks.push(cb);
131
- return 1;
132
- });
133
- m.animate({ opacity: [0, 1], delay: 200, duration: 100 });
134
- // At ts=50, delay not yet passed; opacity should be at start value (0)
135
- rafCallbacks[0]?.(50);
136
- expect(el.style.opacity).toBe("0");
137
- });
138
- });
139
- //# sourceMappingURL=use-motion.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-motion.test.js","sourceRoot":"","sources":["../../src/__tests__/use-motion.test.ts"],"names":[],"mappings":"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"}
@@ -1,20 +0,0 @@
1
- import { type Easing } from "./easings";
2
- export interface MotionKeyframes {
3
- opacity?: [number, number];
4
- x?: [number, number];
5
- y?: [number, number];
6
- scale?: [number, number];
7
- rotate?: [number, number];
8
- duration?: number;
9
- easing?: Easing;
10
- delay?: number;
11
- onComplete?: () => void;
12
- }
13
- export declare function useMotion(ref: {
14
- current: HTMLElement | null;
15
- }): {
16
- animate: (keyframes: MotionKeyframes) => () => void;
17
- enter: (kf: MotionKeyframes) => () => void;
18
- exit: (kf: MotionKeyframes) => () => void;
19
- };
20
- //# sourceMappingURL=use-motion.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-motion.d.ts","sourceRoot":"","sources":["../src/use-motion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrB,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE;yBAChC,eAAe,KAAG,MAAM,IAAI;gBAgE1C,eAAe,WAhEuB,IAAI;eAiE3C,eAAe,WAjEwB,IAAI;EAyEzD"}
@@ -1,58 +0,0 @@
1
- import { resolveEasing } from "./easings";
2
- export function useMotion(ref) {
3
- function animate(keyframes) {
4
- const el = ref.current;
5
- if (!el)
6
- return () => undefined;
7
- const safeEl = el;
8
- const { opacity, x, y, scale, rotate, duration = 300, easing = "easeOut", delay = 0, onComplete, } = keyframes;
9
- const easeFn = resolveEasing(easing);
10
- let raf;
11
- let startTime;
12
- let cancelled = false;
13
- function frame(ts) {
14
- if (cancelled)
15
- return;
16
- startTime ??= ts + delay;
17
- const elapsed = Math.max(0, ts - startTime);
18
- const t = Math.min(elapsed / duration, 1);
19
- const e = easeFn(t);
20
- const transforms = [];
21
- if (x)
22
- transforms.push(`translateX(${String(x[0] + (x[1] - x[0]) * e)}px)`);
23
- if (y)
24
- transforms.push(`translateY(${String(y[0] + (y[1] - y[0]) * e)}px)`);
25
- if (scale)
26
- transforms.push(`scale(${String(scale[0] + (scale[1] - scale[0]) * e)})`);
27
- if (rotate)
28
- transforms.push(`rotate(${String(rotate[0] + (rotate[1] - rotate[0]) * e)}deg)`);
29
- if (transforms.length)
30
- safeEl.style.transform = transforms.join(" ");
31
- if (opacity)
32
- safeEl.style.opacity = String(opacity[0] + (opacity[1] - opacity[0]) * e);
33
- if (t < 1) {
34
- raf = requestAnimationFrame(frame);
35
- }
36
- else {
37
- onComplete?.();
38
- }
39
- }
40
- raf = requestAnimationFrame(frame);
41
- return () => {
42
- cancelled = true;
43
- if (raf)
44
- cancelAnimationFrame(raf);
45
- };
46
- }
47
- return {
48
- animate,
49
- enter: (kf) => animate(kf),
50
- exit: (kf) => animate({
51
- ...kf,
52
- opacity: kf.opacity ? [kf.opacity[1], kf.opacity[0]] : undefined,
53
- x: kf.x ? [kf.x[1], kf.x[0]] : undefined,
54
- y: kf.y ? [kf.y[1], kf.y[0]] : undefined,
55
- }),
56
- };
57
- }
58
- //# sourceMappingURL=use-motion.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-motion.js","sourceRoot":"","sources":["../src/use-motion.ts"],"names":[],"mappings":"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"}