motion-v 0.7.0 → 0.7.1
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/dist/cjs/index.js +280 -134
- package/dist/es/animation/hooks/animation-controls.mjs +78 -0
- package/dist/es/animation/{use-animate.mjs → hooks/use-animate.mjs} +1 -1
- package/dist/es/animation/hooks/use-animation-controls.mjs +16 -0
- package/dist/es/animation/utils.mjs +6 -0
- package/dist/es/components/animate-presence/AnimatePresence.vue.mjs +2 -2
- package/dist/es/components/motion/Motion.vue.mjs +4 -1
- package/dist/es/constants/index.mjs +0 -1
- package/dist/es/features/animation/animation.mjs +33 -0
- package/dist/es/features/feature-manager.mjs +5 -1
- package/dist/es/features/gestures/focus/index.mjs +36 -0
- package/dist/es/index.mjs +3 -1
- package/dist/es/state/animate-updates.mjs +129 -0
- package/dist/es/state/motion-state.mjs +6 -123
- package/dist/es/state/style.mjs +2 -2
- package/dist/src/animation/hooks/animation-controls.d.ts +8 -0
- package/dist/src/animation/hooks/use-animate.d.ts +8 -0
- package/dist/src/animation/hooks/use-animation-controls.d.ts +33 -0
- package/dist/src/animation/index.d.ts +2 -1
- package/dist/src/animation/types.d.ts +68 -0
- package/dist/src/animation/utils.d.ts +2 -0
- package/dist/src/components/animate-presence/utils.d.ts +0 -1
- package/dist/src/components/index.d.ts +1 -1
- package/dist/src/components/motion/NameSpace.d.ts +2 -2
- package/dist/src/features/animation/animation.d.ts +13 -0
- package/dist/src/features/gestures/focus/index.d.ts +7 -0
- package/dist/src/features/gestures/focus/types.d.ts +6 -0
- package/dist/src/features/index.d.ts +1 -0
- package/dist/src/state/animate-updates.d.ts +19 -0
- package/dist/src/state/animation/types.d.ts +0 -0
- package/dist/src/state/motion-state.d.ts +2 -4
- package/dist/src/state/utils.d.ts +1 -1
- package/dist/src/types/state.d.ts +4 -2
- package/package.json +3 -2
- package/dist/es/components/animate-presence/utils.mjs +0 -10
- /package/dist/src/{animation/use-animation.d.ts → state/animation/index.d.ts} +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isAnimationControls } from "../../animation/utils.mjs";
|
|
2
|
+
import { Feature } from "../feature.mjs";
|
|
3
|
+
class AnimationFeature extends Feature {
|
|
4
|
+
constructor(state) {
|
|
5
|
+
super(state);
|
|
6
|
+
}
|
|
7
|
+
updateAnimationControlsSubscription() {
|
|
8
|
+
const { animate } = this.state.options;
|
|
9
|
+
if (isAnimationControls(animate)) {
|
|
10
|
+
this.unmountControls = animate.subscribe(this.state);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Subscribe any provided AnimationControls to the component's VisualElement
|
|
15
|
+
*/
|
|
16
|
+
mount() {
|
|
17
|
+
this.updateAnimationControlsSubscription();
|
|
18
|
+
}
|
|
19
|
+
update() {
|
|
20
|
+
const { animate } = this.state.options;
|
|
21
|
+
const { animate: prevAnimate } = this.state.visualElement.prevProps || {};
|
|
22
|
+
if (animate !== prevAnimate) {
|
|
23
|
+
this.updateAnimationControlsSubscription();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
unmount() {
|
|
27
|
+
var _a;
|
|
28
|
+
(_a = this.unmountControls) == null ? void 0 : _a.call(this);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
AnimationFeature
|
|
33
|
+
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { SVGFeature } from "./svg.mjs";
|
|
2
2
|
import { LayoutFeature } from "./layout/layout.mjs";
|
|
3
3
|
import { PanGesture } from "./gestures/pan/index.mjs";
|
|
4
|
+
import { AnimationFeature } from "./animation/animation.mjs";
|
|
4
5
|
import { ProjectionFeature } from "./layout/projection.mjs";
|
|
6
|
+
import { FocusGesture } from "./gestures/focus/index.mjs";
|
|
5
7
|
import { HoverGesture } from "./gestures/hover/index.mjs";
|
|
6
8
|
import { PressGesture } from "./gestures/press/index.mjs";
|
|
7
9
|
import { InViewGesture } from "./gestures/in-view/index.mjs";
|
|
@@ -17,7 +19,9 @@ class FeatureManager {
|
|
|
17
19
|
new LayoutFeature(state),
|
|
18
20
|
new ProjectionFeature(state),
|
|
19
21
|
new PanGesture(state),
|
|
20
|
-
new DragGesture(state)
|
|
22
|
+
new DragGesture(state),
|
|
23
|
+
new FocusGesture(state),
|
|
24
|
+
new AnimationFeature(state)
|
|
21
25
|
];
|
|
22
26
|
}
|
|
23
27
|
mount() {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { addDomEvent } from "../../../events/add-dom-event.mjs";
|
|
2
|
+
import { Feature } from "../../feature.mjs";
|
|
3
|
+
import { pipe } from "../../../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/utils/pipe.mjs";
|
|
4
|
+
class FocusGesture extends Feature {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.isActive = false;
|
|
8
|
+
}
|
|
9
|
+
onFocus() {
|
|
10
|
+
let isFocusVisible = false;
|
|
11
|
+
try {
|
|
12
|
+
isFocusVisible = this.state.element.matches(":focus-visible");
|
|
13
|
+
} catch (e) {
|
|
14
|
+
isFocusVisible = true;
|
|
15
|
+
}
|
|
16
|
+
if (!isFocusVisible)
|
|
17
|
+
return;
|
|
18
|
+
this.state.setActive("focus", true);
|
|
19
|
+
this.isActive = true;
|
|
20
|
+
}
|
|
21
|
+
onBlur() {
|
|
22
|
+
if (!this.isActive)
|
|
23
|
+
return;
|
|
24
|
+
this.state.setActive("focus", false);
|
|
25
|
+
this.isActive = false;
|
|
26
|
+
}
|
|
27
|
+
mount() {
|
|
28
|
+
this.unmount = pipe(
|
|
29
|
+
addDomEvent(this.state.element, "focus", () => this.onFocus()),
|
|
30
|
+
addDomEvent(this.state.element, "blur", () => this.onBlur())
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
FocusGesture
|
|
36
|
+
};
|
package/dist/es/index.mjs
CHANGED
|
@@ -50,7 +50,8 @@ import { useMotionValueEvent } from "./value/use-motion-value-event.mjs";
|
|
|
50
50
|
import { useSpring } from "./value/use-spring.mjs";
|
|
51
51
|
import { useScroll } from "./value/use-scroll.mjs";
|
|
52
52
|
import { useVelocity } from "./value/use-velocity.mjs";
|
|
53
|
-
import { useAnimate } from "./animation/use-animate.mjs";
|
|
53
|
+
import { useAnimate } from "./animation/hooks/use-animate.mjs";
|
|
54
|
+
import { useAnimationControls } from "./animation/hooks/use-animation-controls.mjs";
|
|
54
55
|
import { createContext } from "./utils/createContext.mjs";
|
|
55
56
|
import { isMotionValue } from "./utils/motion-value.mjs";
|
|
56
57
|
import { useInView } from "./utils/use-in-view.mjs";
|
|
@@ -120,6 +121,7 @@ export {
|
|
|
120
121
|
time,
|
|
121
122
|
transform,
|
|
122
123
|
useAnimate,
|
|
124
|
+
useAnimationControls,
|
|
123
125
|
useAnimationFrame,
|
|
124
126
|
useCombineMotionValues,
|
|
125
127
|
useComputed,
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { resolveVariant, getOptions, hasChanged } from "./utils.mjs";
|
|
2
|
+
import { style } from "./style.mjs";
|
|
3
|
+
import { transformResetValue } from "./transform.mjs";
|
|
4
|
+
import { motionEvent } from "./event.mjs";
|
|
5
|
+
import { isDef } from "@vueuse/core";
|
|
6
|
+
import { isAnimationControls } from "../animation/utils.mjs";
|
|
7
|
+
import { animate } from "../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/animation/animate/index.mjs";
|
|
8
|
+
import { noop } from "../external/.pnpm/motion-utils@11.16.0/external/motion-utils/dist/es/noop.mjs";
|
|
9
|
+
import "../external/.pnpm/motion-utils@11.16.0/external/motion-utils/dist/es/errors.mjs";
|
|
10
|
+
const STATE_TYPES = ["initial", "animate", "inView", "hover", "press", "whileDrag", "focus", "exit"];
|
|
11
|
+
function animateUpdates({
|
|
12
|
+
controlActiveState = void 0,
|
|
13
|
+
controlDelay = 0,
|
|
14
|
+
directAnimate,
|
|
15
|
+
directTransition,
|
|
16
|
+
isFallback = false
|
|
17
|
+
} = {}) {
|
|
18
|
+
const prevTarget = this.target;
|
|
19
|
+
this.target = { ...this.baseTarget };
|
|
20
|
+
const animationOptions = {};
|
|
21
|
+
const transition = { ...this.options.transition };
|
|
22
|
+
if (directAnimate)
|
|
23
|
+
resolveDirectAnimation.call(this, directAnimate, directTransition, animationOptions);
|
|
24
|
+
else
|
|
25
|
+
resolveStateAnimation.call(this, controlActiveState, animationOptions);
|
|
26
|
+
const factories = createAnimationFactories.call(this, prevTarget, animationOptions, controlDelay);
|
|
27
|
+
const { getChildAnimations, childAnimations } = setupChildAnimations.call(this, transition, controlActiveState, isFallback);
|
|
28
|
+
return executeAnimations.call(this, factories, getChildAnimations, childAnimations, transition, controlActiveState);
|
|
29
|
+
}
|
|
30
|
+
function resolveDirectAnimation(directAnimate, directTransition, animationOptions) {
|
|
31
|
+
const variant = resolveVariant(directAnimate, this.options.variants, this.options.custom);
|
|
32
|
+
if (!variant)
|
|
33
|
+
return;
|
|
34
|
+
const transition = { ...this.options.transition, ...directTransition || variant.transition };
|
|
35
|
+
Object.entries(variant).forEach(([key, value]) => {
|
|
36
|
+
if (key === "transition")
|
|
37
|
+
return;
|
|
38
|
+
this.target[key] = value;
|
|
39
|
+
animationOptions[key] = getOptions(transition, key);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function resolveStateAnimation(controlActiveState, animationOptions) {
|
|
43
|
+
if (controlActiveState)
|
|
44
|
+
this.activeStates = { ...this.activeStates, ...controlActiveState };
|
|
45
|
+
STATE_TYPES.forEach((name) => {
|
|
46
|
+
if (!this.activeStates[name] || isAnimationControls(this.options[name]))
|
|
47
|
+
return;
|
|
48
|
+
const definition = isDef(this.options[name]) ? this.options[name] : this.context[name];
|
|
49
|
+
const variant = resolveVariant(definition, this.options.variants, this.options.custom);
|
|
50
|
+
if (!variant)
|
|
51
|
+
return;
|
|
52
|
+
const transition = { ...this.options.transition, ...variant.transition };
|
|
53
|
+
Object.entries(variant).forEach(([key, value]) => {
|
|
54
|
+
if (key === "transition")
|
|
55
|
+
return;
|
|
56
|
+
this.target[key] = value;
|
|
57
|
+
animationOptions[key] = getOptions(transition, key);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function createAnimationFactories(prevTarget, animationOptions, controlDelay) {
|
|
62
|
+
const factories = [];
|
|
63
|
+
new Set(Object.keys(this.target)).forEach((key) => {
|
|
64
|
+
var _a;
|
|
65
|
+
if (!hasChanged(this.visualElement.getValue(key), this.target[key]))
|
|
66
|
+
return;
|
|
67
|
+
(_a = this.baseTarget)[key] ?? (_a[key] = style.get(this.element, key));
|
|
68
|
+
const keyValue = this.target[key] === "none" ? transformResetValue[key] : this.target[key];
|
|
69
|
+
const targetTransition = animationOptions[key];
|
|
70
|
+
factories.push(() => animate(
|
|
71
|
+
this.element,
|
|
72
|
+
{ [key]: keyValue },
|
|
73
|
+
{
|
|
74
|
+
...targetTransition,
|
|
75
|
+
delay: ((targetTransition == null ? void 0 : targetTransition.delay) || 0) + controlDelay
|
|
76
|
+
}
|
|
77
|
+
));
|
|
78
|
+
});
|
|
79
|
+
return factories;
|
|
80
|
+
}
|
|
81
|
+
function setupChildAnimations(transition, controlActiveState, isFallback) {
|
|
82
|
+
var _a;
|
|
83
|
+
if (!((_a = this.visualElement.variantChildren) == null ? void 0 : _a.size) || controlActiveState)
|
|
84
|
+
return { getChildAnimations: () => Promise.resolve(), childAnimations: [] };
|
|
85
|
+
const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition || {};
|
|
86
|
+
const maxStaggerDuration = (this.visualElement.variantChildren.size - 1) * staggerChildren;
|
|
87
|
+
const generateStaggerDuration = staggerDirection === 1 ? (i = 0) => i * staggerChildren : (i = 0) => maxStaggerDuration - i * staggerChildren;
|
|
88
|
+
const childAnimations = Array.from(this.visualElement.variantChildren).map((child, index) => {
|
|
89
|
+
const childDelay = delayChildren + generateStaggerDuration(index);
|
|
90
|
+
return child.state.animateUpdates({
|
|
91
|
+
controlActiveState: this.activeStates,
|
|
92
|
+
controlDelay: isFallback ? 0 : childDelay
|
|
93
|
+
});
|
|
94
|
+
}).filter(Boolean);
|
|
95
|
+
return {
|
|
96
|
+
getChildAnimations: () => Promise.all(childAnimations.map((animation) => animation())),
|
|
97
|
+
childAnimations
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function executeAnimations(factories, getChildAnimations, childAnimations, transition, controlActiveState) {
|
|
101
|
+
let animations;
|
|
102
|
+
const getAnimation = () => {
|
|
103
|
+
animations = factories.map((factory) => factory()).filter(Boolean);
|
|
104
|
+
return Promise.all(animations);
|
|
105
|
+
};
|
|
106
|
+
const isExit = this.activeStates.exit;
|
|
107
|
+
const animationTarget = { ...this.target };
|
|
108
|
+
const element = this.element;
|
|
109
|
+
const finishAnimation = (animationPromise) => {
|
|
110
|
+
if (!(animations == null ? void 0 : animations.length) && !childAnimations.length) {
|
|
111
|
+
if (isExit) {
|
|
112
|
+
element.dispatchEvent(motionEvent("motionstart", animationTarget));
|
|
113
|
+
element.dispatchEvent(motionEvent("motioncomplete", animationTarget, isExit));
|
|
114
|
+
}
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
element.dispatchEvent(motionEvent("motionstart", animationTarget));
|
|
118
|
+
animationPromise.then(() => element.dispatchEvent(motionEvent("motioncomplete", animationTarget, isExit))).catch(noop);
|
|
119
|
+
};
|
|
120
|
+
const getAnimationPromise = () => {
|
|
121
|
+
const animationPromise = (transition == null ? void 0 : transition.when) ? (transition.when === "beforeChildren" ? getAnimation() : getChildAnimations()).then(() => transition.when === "beforeChildren" ? getChildAnimations() : getAnimation()) : Promise.all([getAnimation(), getChildAnimations()]);
|
|
122
|
+
finishAnimation(animationPromise);
|
|
123
|
+
return animationPromise;
|
|
124
|
+
};
|
|
125
|
+
return controlActiveState ? getAnimationPromise : getAnimationPromise();
|
|
126
|
+
}
|
|
127
|
+
export {
|
|
128
|
+
animateUpdates
|
|
129
|
+
};
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { invariant } from "hey-listen";
|
|
2
2
|
import { visualElementStore } from "../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/render/store.mjs";
|
|
3
3
|
import { isDef } from "@vueuse/core";
|
|
4
|
-
import { resolveVariant
|
|
4
|
+
import { resolveVariant } from "./utils.mjs";
|
|
5
5
|
import { FeatureManager } from "../features/feature-manager.mjs";
|
|
6
|
-
import { style } from "./style.mjs";
|
|
7
|
-
import { transformResetValue } from "./transform.mjs";
|
|
8
|
-
import { motionEvent } from "./event.mjs";
|
|
9
6
|
import { createVisualElement } from "./create-visual-element.mjs";
|
|
10
7
|
import { doneCallbacks } from "../components/presence.mjs";
|
|
8
|
+
import { animateUpdates } from "./animate-updates.mjs";
|
|
11
9
|
import { frame } from "../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/frameloop/frame.mjs";
|
|
12
|
-
import { noop } from "../external/.pnpm/motion-utils@11.16.0/external/motion-utils/dist/es/noop.mjs";
|
|
13
|
-
import "../external/.pnpm/motion-utils@11.16.0/external/motion-utils/dist/es/errors.mjs";
|
|
14
|
-
import { animate } from "../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/animation/animate/index.mjs";
|
|
15
|
-
const STATE_TYPES = ["initial", "animate", "inView", "hover", "press", "whileDrag", "exit"];
|
|
16
10
|
const mountedStates = /* @__PURE__ */ new WeakMap();
|
|
17
11
|
let id = 0;
|
|
18
12
|
class MotionState {
|
|
@@ -27,6 +21,7 @@ class MotionState {
|
|
|
27
21
|
animate: true
|
|
28
22
|
};
|
|
29
23
|
this._context = null;
|
|
24
|
+
this.animateUpdates = animateUpdates;
|
|
30
25
|
this.id = `motion-state-${id++}`;
|
|
31
26
|
this.options = options;
|
|
32
27
|
this.parent = parent;
|
|
@@ -176,122 +171,10 @@ class MotionState {
|
|
|
176
171
|
child.state.setActive(name, isActive, false);
|
|
177
172
|
});
|
|
178
173
|
if (isAnimate) {
|
|
179
|
-
this.animateUpdates(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
// Core animation update logic
|
|
183
|
-
animateUpdates(controlActiveState = void 0, controlDelay = 0) {
|
|
184
|
-
var _a;
|
|
185
|
-
const prevTarget = this.target;
|
|
186
|
-
this.target = {
|
|
187
|
-
...this.baseTarget
|
|
188
|
-
};
|
|
189
|
-
const animationOptions = {};
|
|
190
|
-
let transition;
|
|
191
|
-
if (controlActiveState) {
|
|
192
|
-
this.activeStates = { ...this.activeStates, ...controlActiveState };
|
|
193
|
-
}
|
|
194
|
-
for (const name of STATE_TYPES) {
|
|
195
|
-
if (!this.activeStates[name]) {
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
const definition = isDef(this.options[name]) ? this.options[name] : this.context[name];
|
|
199
|
-
const variant = resolveVariant(
|
|
200
|
-
definition,
|
|
201
|
-
this.options.variants,
|
|
202
|
-
this.options.custom
|
|
203
|
-
);
|
|
204
|
-
transition = Object.assign({}, this.options.transition, variant == null ? void 0 : variant.transition);
|
|
205
|
-
if (!variant)
|
|
206
|
-
continue;
|
|
207
|
-
const allTarget = { ...variant };
|
|
208
|
-
for (const key in allTarget) {
|
|
209
|
-
if (key === "transition")
|
|
210
|
-
continue;
|
|
211
|
-
this.target[key] = variant[key];
|
|
212
|
-
animationOptions[key] = getOptions(
|
|
213
|
-
transition,
|
|
214
|
-
key
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
const allTargetKeys = /* @__PURE__ */ new Set([
|
|
219
|
-
...Object.keys(this.target)
|
|
220
|
-
]);
|
|
221
|
-
const animationFactories = [];
|
|
222
|
-
allTargetKeys.forEach((key) => {
|
|
223
|
-
var _a2;
|
|
224
|
-
if (hasChanged(prevTarget[key], this.target[key])) {
|
|
225
|
-
(_a2 = this.baseTarget)[key] ?? (_a2[key] = style.get(this.element, key));
|
|
226
|
-
const keyValue = this.target[key] === "none" ? transformResetValue[key] : this.target[key];
|
|
227
|
-
const targetTransition = animationOptions[key];
|
|
228
|
-
animationFactories.push(
|
|
229
|
-
() => {
|
|
230
|
-
return animate(
|
|
231
|
-
this.element,
|
|
232
|
-
{
|
|
233
|
-
[key]: keyValue
|
|
234
|
-
},
|
|
235
|
-
{
|
|
236
|
-
...targetTransition,
|
|
237
|
-
delay: ((targetTransition == null ? void 0 : targetTransition.delay) || 0) + controlDelay
|
|
238
|
-
}
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
let getChildAnimations = () => Promise.resolve();
|
|
245
|
-
let childAnimations = [];
|
|
246
|
-
if (((_a = this.visualElement.variantChildren) == null ? void 0 : _a.size) && !controlActiveState) {
|
|
247
|
-
const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition || {};
|
|
248
|
-
const maxStaggerDuration = (this.visualElement.variantChildren.size - 1) * staggerChildren;
|
|
249
|
-
const generateStaggerDuration = staggerDirection === 1 ? (i = 0) => i * staggerChildren : (i = 0) => maxStaggerDuration - i * staggerChildren;
|
|
250
|
-
childAnimations = Array.from(this.visualElement.variantChildren).map((child, index) => {
|
|
251
|
-
const childDelay = delayChildren + generateStaggerDuration(index);
|
|
252
|
-
return child.state.animateUpdates(this.activeStates, childDelay);
|
|
253
|
-
}).filter(Boolean);
|
|
254
|
-
getChildAnimations = () => Promise.all(childAnimations.map((animation) => animation()));
|
|
255
|
-
}
|
|
256
|
-
let animations;
|
|
257
|
-
const getAnimation = () => {
|
|
258
|
-
animations = animationFactories.map((factory) => factory()).filter(Boolean);
|
|
259
|
-
return Promise.all(animations);
|
|
260
|
-
};
|
|
261
|
-
const { when } = transition;
|
|
262
|
-
let animationPromise;
|
|
263
|
-
const isExit = this.activeStates.exit;
|
|
264
|
-
const animationTarget = { ...this.target };
|
|
265
|
-
const element = this.element;
|
|
266
|
-
function finishAnimation() {
|
|
267
|
-
if (!(animations == null ? void 0 : animations.length) && !childAnimations.length) {
|
|
268
|
-
if (isExit) {
|
|
269
|
-
element.dispatchEvent(motionEvent("motionstart", animationTarget));
|
|
270
|
-
element.dispatchEvent(motionEvent("motioncomplete", animationTarget, isExit));
|
|
271
|
-
}
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
element.dispatchEvent(motionEvent("motionstart", animationTarget));
|
|
275
|
-
animationPromise.then(() => {
|
|
276
|
-
element.dispatchEvent(motionEvent("motioncomplete", animationTarget, isExit));
|
|
277
|
-
}).catch(noop);
|
|
278
|
-
}
|
|
279
|
-
function getAnimationPromise() {
|
|
280
|
-
if (when) {
|
|
281
|
-
const [first, last] = when === "beforeChildren" ? [getAnimation, getChildAnimations] : [getChildAnimations, getAnimation];
|
|
282
|
-
animationPromise = first().then(() => last());
|
|
283
|
-
finishAnimation();
|
|
284
|
-
return animationPromise;
|
|
285
|
-
} else {
|
|
286
|
-
animationPromise = Promise.all([getAnimation(), getChildAnimations()]);
|
|
287
|
-
finishAnimation();
|
|
288
|
-
return animationPromise;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
if (controlActiveState) {
|
|
292
|
-
return getAnimationPromise;
|
|
174
|
+
this.animateUpdates({
|
|
175
|
+
isFallback: !isActive
|
|
176
|
+
});
|
|
293
177
|
}
|
|
294
|
-
getAnimationPromise();
|
|
295
178
|
}
|
|
296
179
|
isMounted() {
|
|
297
180
|
return Boolean(this.element);
|
package/dist/es/state/style.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isNumber, isCssVar } from "./utils.mjs";
|
|
2
|
+
import { isTransform, transformAlias, transformDefinitions, buildTransformTemplate } from "./transform.mjs";
|
|
3
3
|
import { isMotionValue } from "../utils/motion-value.mjs";
|
|
4
4
|
const style = {
|
|
5
5
|
get: (element, name) => {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AnimationControls } from '../types';
|
|
2
|
+
import { MotionState } from '../../state';
|
|
3
|
+
import { Options } from '../../types';
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare function animationControls(): AnimationControls;
|
|
8
|
+
export declare function setValues(state: MotionState, definition: Options['animate']): void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AnimationPlaybackControls } from 'framer-motion';
|
|
2
|
+
import { Ref, UnwrapRef } from 'vue';
|
|
3
|
+
import { createScopedAnimate } from 'framer-motion/dom';
|
|
4
|
+
type Scope = Ref<UnwrapRef<Element>> & {
|
|
5
|
+
animations: AnimationPlaybackControls[];
|
|
6
|
+
};
|
|
7
|
+
export declare function useAnimate<T extends Element = any>(): [Scope, ReturnType<typeof createScopedAnimate>];
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates `AnimationControls`, which can be used to manually start, stop
|
|
3
|
+
* and sequence animations on one or more components.
|
|
4
|
+
*
|
|
5
|
+
* The returned `AnimationControls` should be passed to the `animate` property
|
|
6
|
+
* of the components you want to animate.
|
|
7
|
+
*
|
|
8
|
+
* These components can then be animated with the `start` method.
|
|
9
|
+
*
|
|
10
|
+
* ```jsx
|
|
11
|
+
* import { motion, useAnimationControls } from 'motion-v'
|
|
12
|
+
*
|
|
13
|
+
* export default defineComponent({
|
|
14
|
+
* setup() {
|
|
15
|
+
* const controls = useAnimationControls()
|
|
16
|
+
*
|
|
17
|
+
* controls.start({
|
|
18
|
+
* x: 100,
|
|
19
|
+
* transition: { duration: 0.5 },
|
|
20
|
+
* })
|
|
21
|
+
*
|
|
22
|
+
* return () => (
|
|
23
|
+
* <motion.div animate={controls} />
|
|
24
|
+
* )
|
|
25
|
+
* }
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @returns Animation controller with `start`, `stop`, `set` and `mount` methods
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export declare function useAnimationControls(): import('../types').AnimationControls;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from './use-animate';
|
|
1
|
+
export * from './hooks/use-animate';
|
|
2
|
+
export * from './hooks/use-animation-controls';
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { MotionState } from '../state';
|
|
2
|
+
import { $Transition, Options } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface AnimationControls {
|
|
7
|
+
/**
|
|
8
|
+
* Subscribes a component's animation controls to this.
|
|
9
|
+
*
|
|
10
|
+
* @param controls - The controls to subscribe
|
|
11
|
+
* @returns An unsubscribe function.
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
subscribe: (state: MotionState) => () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Starts an animation on all linked components.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
*
|
|
21
|
+
* ```jsx
|
|
22
|
+
* controls.start("variantLabel")
|
|
23
|
+
* controls.start({
|
|
24
|
+
* x: 0,
|
|
25
|
+
* transition: { duration: 1 }
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @param definition - Properties or variant label to animate to
|
|
30
|
+
* @param transition - Optional `transtion` to apply to a variant
|
|
31
|
+
* @returns - A `Promise` that resolves when all animations have completed.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
start: (definition: Options['animate'], transitionOverride?: $Transition) => Promise<any>;
|
|
36
|
+
/**
|
|
37
|
+
* Instantly set to a set of properties or a variant.
|
|
38
|
+
*
|
|
39
|
+
* ```jsx
|
|
40
|
+
* // With properties
|
|
41
|
+
* controls.set({ opacity: 0 })
|
|
42
|
+
*
|
|
43
|
+
* // With variants
|
|
44
|
+
* controls.set("hidden")
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @privateRemarks
|
|
48
|
+
* We could perform a similar trick to `.start` where this can be called before mount
|
|
49
|
+
* and we maintain a list of of pending actions that get applied on mount. But the
|
|
50
|
+
* expectation of `set` is that it happens synchronously and this would be difficult
|
|
51
|
+
* to do before any children have even attached themselves. It's also poor practise
|
|
52
|
+
* and we should discourage render-synchronous `.start` calls rather than lean into this.
|
|
53
|
+
*
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
set: (definition: Options['animate']) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Stops animations on all linked components.
|
|
59
|
+
*
|
|
60
|
+
* ```jsx
|
|
61
|
+
* controls.stop()
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
stop: () => void;
|
|
67
|
+
mount: () => () => void;
|
|
68
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function requestIdleCallback(callback: () => void): void;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { DefineComponent, ExtractPropTypes, ExtractPublicPropTypes, IntrinsicElementAttributes } from 'vue';
|
|
2
2
|
import { MotionProps } from './Motion';
|
|
3
3
|
type ComponentProps<T> = T extends DefineComponent<ExtractPropTypes<infer Props>, any, any> ? ExtractPublicPropTypes<Props> : never;
|
|
4
|
-
type MotionComponentProps =
|
|
4
|
+
type MotionComponentProps = {
|
|
5
5
|
create: <T extends DefineComponent>(T: any) => DefineComponent<MotionProps<any, unknown> & ComponentProps<T>>;
|
|
6
6
|
};
|
|
7
|
-
interface MotionNameSpace extends Record<keyof IntrinsicElementAttributes, DefineComponent<MotionProps<keyof IntrinsicElementAttributes, unknown
|
|
7
|
+
interface MotionNameSpace extends Record<keyof IntrinsicElementAttributes, DefineComponent<MotionProps<keyof IntrinsicElementAttributes, unknown>>> {
|
|
8
8
|
create: MotionComponentProps['create'];
|
|
9
9
|
}
|
|
10
10
|
export declare const motion: MotionNameSpace;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Feature } from '../feature';
|
|
2
|
+
import { MotionState } from '../../state';
|
|
3
|
+
export declare class AnimationFeature extends Feature {
|
|
4
|
+
unmountControls?: () => void;
|
|
5
|
+
constructor(state: MotionState);
|
|
6
|
+
updateAnimationControlsSubscription(): void;
|
|
7
|
+
/**
|
|
8
|
+
* Subscribe any provided AnimationControls to the component's VisualElement
|
|
9
|
+
*/
|
|
10
|
+
mount(): void;
|
|
11
|
+
update(): void;
|
|
12
|
+
unmount(): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { $Transition, Options } from '../types';
|
|
2
|
+
import { MotionState } from './motion-state';
|
|
3
|
+
declare const STATE_TYPES: readonly ["initial", "animate", "inView", "hover", "press", "whileDrag", "focus", "exit"];
|
|
4
|
+
export type StateType = typeof STATE_TYPES[number];
|
|
5
|
+
/**
|
|
6
|
+
* 核心动画更新函数,处理所有动画状态变化和执行
|
|
7
|
+
* @param controlActiveState - 需要更新的动画状态
|
|
8
|
+
* @param controlDelay - 动画延迟时间
|
|
9
|
+
* @param directAnimate - 直接动画目标值
|
|
10
|
+
* @param directTransition - 直接动画过渡配置
|
|
11
|
+
*/
|
|
12
|
+
export declare function animateUpdates(this: MotionState, { controlActiveState, controlDelay, directAnimate, directTransition, isFallback, }?: {
|
|
13
|
+
controlActiveState?: Partial<Record<string, boolean>>;
|
|
14
|
+
controlDelay?: number;
|
|
15
|
+
directAnimate?: Options['animate'];
|
|
16
|
+
directTransition?: $Transition;
|
|
17
|
+
isFallback?: boolean;
|
|
18
|
+
}): any;
|
|
19
|
+
export {};
|
|
File without changes
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { MotionStateContext, Options } from '../types';
|
|
2
2
|
import { DOMKeyframesDefinition, VisualElement } from 'framer-motion';
|
|
3
|
-
|
|
4
|
-
type StateType = typeof STATE_TYPES[number];
|
|
3
|
+
import { StateType, animateUpdates } from './animate-updates';
|
|
5
4
|
export declare const mountedStates: WeakMap<Element, MotionState>;
|
|
6
5
|
/**
|
|
7
6
|
* Core class that manages animation state and orchestrates animations
|
|
@@ -33,9 +32,8 @@ export declare class MotionState {
|
|
|
33
32
|
beforeUpdate(): void;
|
|
34
33
|
update(options: Options, notAnimate?: boolean): void;
|
|
35
34
|
setActive(name: StateType, isActive: boolean, isAnimate?: boolean): void;
|
|
36
|
-
animateUpdates
|
|
35
|
+
animateUpdates: typeof animateUpdates;
|
|
37
36
|
isMounted(): boolean;
|
|
38
37
|
getOptions(): Options<any>;
|
|
39
38
|
willUpdate(label: string): void;
|
|
40
39
|
}
|
|
41
|
-
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { $Transition, Options } from '../types';
|
|
2
2
|
import { Variant } from 'framer-motion';
|
|
3
3
|
import { IntrinsicElementAttributes } from 'vue';
|
|
4
|
-
export declare function resolveVariant(definition?: Options['
|
|
4
|
+
export declare function resolveVariant(definition?: Options['animate'], variants?: Options['variants'], custom?: Options['custom']): Variant | undefined;
|
|
5
5
|
export declare function hasChanged(a: any, b: any): boolean;
|
|
6
6
|
export declare function shallowCompare(next: any[], prev: any[]): boolean;
|
|
7
7
|
export declare function addUniqueItem<T>(array: T[], item: T): void;
|