framer-motion 7.6.4 → 7.6.6
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 +789 -850
- package/dist/es/animation/use-animated-state.mjs +29 -17
- package/dist/es/gestures/drag/VisualElementDragControls.mjs +14 -10
- package/dist/es/gestures/use-focus-gesture.mjs +1 -1
- package/dist/es/gestures/use-tap-gesture.mjs +1 -1
- package/dist/es/index.mjs +1 -1
- package/dist/es/motion/features/viewport/use-viewport.mjs +2 -2
- package/dist/es/motion/utils/use-visual-element.mjs +3 -3
- package/dist/es/projection/node/create-projection-node.mjs +74 -60
- package/dist/es/render/VisualElement.mjs +480 -0
- package/dist/es/render/dom/DOMVisualElement.mjs +49 -0
- package/dist/es/render/dom/create-visual-element.mjs +4 -4
- package/dist/es/render/dom/utils/css-variables-conversion.mjs +2 -2
- package/dist/es/render/dom/utils/unit-conversion.mjs +4 -4
- package/dist/es/render/html/HTMLVisualElement.mjs +41 -0
- package/dist/es/render/svg/{visual-element.mjs → SVGVisualElement.mjs} +21 -15
- package/dist/es/render/utils/animation.mjs +4 -4
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/render/utils/resolve-dynamic-variants.mjs +2 -2
- package/dist/es/render/utils/setters.mjs +2 -1
- package/dist/es/value/index.mjs +1 -1
- package/dist/framer-motion.dev.js +789 -850
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +2101 -1931
- package/dist/projection.dev.js +1053 -1136
- package/dist/size-rollup-dom-animation-m.js +1 -1
- package/dist/size-rollup-dom-animation.js +1 -1
- package/dist/size-rollup-dom-max-assets.js +1 -1
- package/dist/size-rollup-dom-max.js +1 -1
- package/dist/size-rollup-m.js +1 -1
- package/dist/size-rollup-motion.js +1 -1
- package/dist/size-webpack-dom-animation.js +1 -1
- package/dist/size-webpack-dom-max.js +1 -1
- package/dist/size-webpack-m.js +1 -1
- package/dist/three-entry.d.ts +1956 -1745
- package/package.json +8 -8
- package/dist/es/render/html/visual-element.mjs +0 -109
- package/dist/es/render/index.mjs +0 -515
- package/dist/es/render/utils/lifecycles.mjs +0 -43
package/dist/cjs/index.js
CHANGED
|
@@ -63,7 +63,7 @@ function useVisualElement(Component, visualState, props, createVisualElement) {
|
|
|
63
63
|
const lazyContext = React.useContext(LazyContext);
|
|
64
64
|
const presenceContext = React.useContext(PresenceContext);
|
|
65
65
|
const reducedMotionConfig = React.useContext(MotionConfigContext).reducedMotion;
|
|
66
|
-
const visualElementRef = React.useRef(
|
|
66
|
+
const visualElementRef = React.useRef();
|
|
67
67
|
/**
|
|
68
68
|
* If we haven't preloaded a renderer, check to see if we have one lazy-loaded
|
|
69
69
|
*/
|
|
@@ -82,14 +82,14 @@ function useVisualElement(Component, visualState, props, createVisualElement) {
|
|
|
82
82
|
}
|
|
83
83
|
const visualElement = visualElementRef.current;
|
|
84
84
|
useIsomorphicLayoutEffect(() => {
|
|
85
|
-
visualElement && visualElement.
|
|
85
|
+
visualElement && visualElement.render();
|
|
86
86
|
});
|
|
87
87
|
React.useEffect(() => {
|
|
88
88
|
if (visualElement && visualElement.animationState) {
|
|
89
89
|
visualElement.animationState.animateChanges();
|
|
90
90
|
}
|
|
91
91
|
});
|
|
92
|
-
useIsomorphicLayoutEffect(() => () => visualElement && visualElement.
|
|
92
|
+
useIsomorphicLayoutEffect(() => () => visualElement && visualElement.notify("Unmount"), []);
|
|
93
93
|
return visualElement;
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -1294,7 +1294,7 @@ function useDomEvent(ref, eventName, handler, options) {
|
|
|
1294
1294
|
* @param ref
|
|
1295
1295
|
* @internal
|
|
1296
1296
|
*/
|
|
1297
|
-
function useFocusGesture({ whileFocus, visualElement }) {
|
|
1297
|
+
function useFocusGesture({ whileFocus, visualElement, }) {
|
|
1298
1298
|
const { animationState } = visualElement;
|
|
1299
1299
|
const onFocus = () => {
|
|
1300
1300
|
animationState && animationState.setActive(exports.AnimationType.Focus, true);
|
|
@@ -1530,7 +1530,7 @@ function useTapGesture({ onTap, onTapStart, onTapCancel, whileTap, visualElement
|
|
|
1530
1530
|
* We only count this as a tap gesture if the event.target is the same
|
|
1531
1531
|
* as, or a child of, this component's element
|
|
1532
1532
|
*/
|
|
1533
|
-
!isNodeOrChild(visualElement.
|
|
1533
|
+
!isNodeOrChild(visualElement.current, event.target)
|
|
1534
1534
|
? onTapCancel && onTapCancel(event, info)
|
|
1535
1535
|
: onTap && onTap(event, info);
|
|
1536
1536
|
}
|
|
@@ -1641,7 +1641,7 @@ const thresholdNames = {
|
|
|
1641
1641
|
};
|
|
1642
1642
|
function useIntersectionObserver(shouldObserve, state, visualElement, { root, margin: rootMargin, amount = "some", once }) {
|
|
1643
1643
|
React.useEffect(() => {
|
|
1644
|
-
if (!shouldObserve)
|
|
1644
|
+
if (!shouldObserve || !visualElement.current)
|
|
1645
1645
|
return;
|
|
1646
1646
|
const options = {
|
|
1647
1647
|
root: root === null || root === void 0 ? void 0 : root.current,
|
|
@@ -1679,7 +1679,7 @@ function useIntersectionObserver(shouldObserve, state, visualElement, { root, ma
|
|
|
1679
1679
|
: props.onViewportLeave;
|
|
1680
1680
|
callback && callback(entry);
|
|
1681
1681
|
};
|
|
1682
|
-
return observeIntersection(visualElement.
|
|
1682
|
+
return observeIntersection(visualElement.current, options, intersectionCallback);
|
|
1683
1683
|
}, [shouldObserve, root, rootMargin, amount]);
|
|
1684
1684
|
}
|
|
1685
1685
|
/**
|
|
@@ -2258,7 +2258,7 @@ class MotionValue {
|
|
|
2258
2258
|
* This will be replaced by the build step with the latest version number.
|
|
2259
2259
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
2260
2260
|
*/
|
|
2261
|
-
this.version = "7.6.
|
|
2261
|
+
this.version = "7.6.6";
|
|
2262
2262
|
/**
|
|
2263
2263
|
* Duration, in milliseconds, since last updating frame.
|
|
2264
2264
|
*
|
|
@@ -2572,7 +2572,7 @@ const findValueType = (v) => valueTypes.find(testValueType(v));
|
|
|
2572
2572
|
*/
|
|
2573
2573
|
function getCurrent(visualElement) {
|
|
2574
2574
|
const current = {};
|
|
2575
|
-
visualElement.
|
|
2575
|
+
visualElement.values.forEach((value, key) => (current[key] = value.get()));
|
|
2576
2576
|
return current;
|
|
2577
2577
|
}
|
|
2578
2578
|
/**
|
|
@@ -2580,7 +2580,7 @@ function getCurrent(visualElement) {
|
|
|
2580
2580
|
*/
|
|
2581
2581
|
function getVelocity$1(visualElement) {
|
|
2582
2582
|
const velocity = {};
|
|
2583
|
-
visualElement.
|
|
2583
|
+
visualElement.values.forEach((value, key) => (velocity[key] = value.getVelocity()));
|
|
2584
2584
|
return velocity;
|
|
2585
2585
|
}
|
|
2586
2586
|
function resolveVariant(visualElement, definition, custom) {
|
|
@@ -2674,7 +2674,8 @@ function checkTargetForNewValues(visualElement, target, origin) {
|
|
|
2674
2674
|
if (origin[key] === undefined) {
|
|
2675
2675
|
origin[key] = value;
|
|
2676
2676
|
}
|
|
2677
|
-
|
|
2677
|
+
if (value !== null)
|
|
2678
|
+
visualElement.setBaseTarget(key, value);
|
|
2678
2679
|
}
|
|
2679
2680
|
}
|
|
2680
2681
|
function getOriginFromTransition(key, transition) {
|
|
@@ -2701,7 +2702,7 @@ function isWillChangeMotionValue(value) {
|
|
|
2701
2702
|
}
|
|
2702
2703
|
|
|
2703
2704
|
function animateVisualElement(visualElement, definition, options = {}) {
|
|
2704
|
-
visualElement.
|
|
2705
|
+
visualElement.notify("AnimationStart", definition);
|
|
2705
2706
|
let animation;
|
|
2706
2707
|
if (Array.isArray(definition)) {
|
|
2707
2708
|
const animations = definition.map((variant) => animateVariant(visualElement, variant, options));
|
|
@@ -2716,7 +2717,7 @@ function animateVisualElement(visualElement, definition, options = {}) {
|
|
|
2716
2717
|
: definition;
|
|
2717
2718
|
animation = animateTarget(visualElement, resolvedDefinition, options);
|
|
2718
2719
|
}
|
|
2719
|
-
return animation.then(() => visualElement.
|
|
2720
|
+
return animation.then(() => visualElement.notify("AnimationComplete", definition));
|
|
2720
2721
|
}
|
|
2721
2722
|
function animateVariant(visualElement, variant, options = {}) {
|
|
2722
2723
|
var _a;
|
|
@@ -2811,12 +2812,12 @@ function animateChildren(visualElement, variant, delayChildren = 0, staggerChild
|
|
|
2811
2812
|
animations.push(animateVariant(child, variant, {
|
|
2812
2813
|
...options,
|
|
2813
2814
|
delay: delayChildren + generateStaggerDuration(i),
|
|
2814
|
-
}).then(() => child.
|
|
2815
|
+
}).then(() => child.notify("AnimationComplete", variant)));
|
|
2815
2816
|
});
|
|
2816
2817
|
return Promise.all(animations);
|
|
2817
2818
|
}
|
|
2818
2819
|
function stopAnimation(visualElement) {
|
|
2819
|
-
visualElement.
|
|
2820
|
+
visualElement.values.forEach((value) => value.stop());
|
|
2820
2821
|
}
|
|
2821
2822
|
function sortByTreeOrder(a, b) {
|
|
2822
2823
|
return a.sortNodePosition(b);
|
|
@@ -3737,7 +3738,7 @@ class VisualElementDragControls {
|
|
|
3737
3738
|
* If the MotionValue is a percentage value convert to px
|
|
3738
3739
|
*/
|
|
3739
3740
|
if (styleValueTypes.percent.test(current)) {
|
|
3740
|
-
const measuredAxis = (_b = (_a = this.visualElement.projection) === null || _a === void 0 ? void 0 : _a.layout) === null || _b === void 0 ? void 0 : _b.
|
|
3741
|
+
const measuredAxis = (_b = (_a = this.visualElement.projection) === null || _a === void 0 ? void 0 : _a.layout) === null || _b === void 0 ? void 0 : _b.layoutBox[axis];
|
|
3741
3742
|
if (measuredAxis) {
|
|
3742
3743
|
const length = calcLength(measuredAxis);
|
|
3743
3744
|
current = length * (parseFloat(current) / 100);
|
|
@@ -3774,9 +3775,9 @@ class VisualElementDragControls {
|
|
|
3774
3775
|
* of a re-render we want to ensure the browser can read the latest
|
|
3775
3776
|
* bounding box to ensure the pointer and element don't fall out of sync.
|
|
3776
3777
|
*/
|
|
3777
|
-
this.visualElement.
|
|
3778
|
+
this.visualElement.render();
|
|
3778
3779
|
/**
|
|
3779
|
-
* This must fire after the
|
|
3780
|
+
* This must fire after the render call as it might trigger a state
|
|
3780
3781
|
* change which itself might trigger a layout update.
|
|
3781
3782
|
*/
|
|
3782
3783
|
onDrag === null || onDrag === void 0 ? void 0 : onDrag(event, info);
|
|
@@ -3838,7 +3839,7 @@ class VisualElementDragControls {
|
|
|
3838
3839
|
}
|
|
3839
3840
|
else {
|
|
3840
3841
|
if (dragConstraints && layout) {
|
|
3841
|
-
this.constraints = calcRelativeConstraints(layout.
|
|
3842
|
+
this.constraints = calcRelativeConstraints(layout.layoutBox, dragConstraints);
|
|
3842
3843
|
}
|
|
3843
3844
|
else {
|
|
3844
3845
|
this.constraints = false;
|
|
@@ -3855,7 +3856,7 @@ class VisualElementDragControls {
|
|
|
3855
3856
|
!this.hasMutatedConstraints) {
|
|
3856
3857
|
eachAxis((axis) => {
|
|
3857
3858
|
if (this.getAxisMotionValue(axis)) {
|
|
3858
|
-
this.constraints[axis] = rebaseAxisConstraints(layout.
|
|
3859
|
+
this.constraints[axis] = rebaseAxisConstraints(layout.layoutBox[axis], this.constraints[axis]);
|
|
3859
3860
|
}
|
|
3860
3861
|
});
|
|
3861
3862
|
}
|
|
@@ -3871,7 +3872,7 @@ class VisualElementDragControls {
|
|
|
3871
3872
|
if (!projection || !projection.layout)
|
|
3872
3873
|
return false;
|
|
3873
3874
|
const constraintsBox = measurePageBox(constraintsElement, projection.root, this.visualElement.getTransformPagePoint());
|
|
3874
|
-
let measuredConstraints = calcViewportConstraints(projection.layout.
|
|
3875
|
+
let measuredConstraints = calcViewportConstraints(projection.layout.layoutBox, constraintsBox);
|
|
3875
3876
|
/**
|
|
3876
3877
|
* If there's an onMeasureDragConstraints listener we call it and
|
|
3877
3878
|
* if different constraints are returned, set constraints to that
|
|
@@ -3953,7 +3954,7 @@ class VisualElementDragControls {
|
|
|
3953
3954
|
const { projection } = this.visualElement;
|
|
3954
3955
|
const axisValue = this.getAxisMotionValue(axis);
|
|
3955
3956
|
if (projection && projection.layout) {
|
|
3956
|
-
const { min, max } = projection.layout.
|
|
3957
|
+
const { min, max } = projection.layout.layoutBox[axis];
|
|
3957
3958
|
axisValue.set(point[axis] - popmotion.mix(min, max, 0.5));
|
|
3958
3959
|
}
|
|
3959
3960
|
});
|
|
@@ -3965,6 +3966,8 @@ class VisualElementDragControls {
|
|
|
3965
3966
|
*/
|
|
3966
3967
|
scalePositionWithinConstraints() {
|
|
3967
3968
|
var _a;
|
|
3969
|
+
if (!this.visualElement.current)
|
|
3970
|
+
return;
|
|
3968
3971
|
const { drag, dragConstraints } = this.getProps();
|
|
3969
3972
|
const { projection } = this.visualElement;
|
|
3970
3973
|
if (!isRefObject(dragConstraints) || !projection || !this.constraints)
|
|
@@ -3990,7 +3993,7 @@ class VisualElementDragControls {
|
|
|
3990
3993
|
* Update the layout of this element and resolve the latest drag constraints
|
|
3991
3994
|
*/
|
|
3992
3995
|
const { transformTemplate } = this.visualElement.getProps();
|
|
3993
|
-
this.visualElement.
|
|
3996
|
+
this.visualElement.current.style.transform = transformTemplate
|
|
3994
3997
|
? transformTemplate({}, "")
|
|
3995
3998
|
: "none";
|
|
3996
3999
|
(_a = projection.root) === null || _a === void 0 ? void 0 : _a.updateScroll();
|
|
@@ -4013,8 +4016,10 @@ class VisualElementDragControls {
|
|
|
4013
4016
|
}
|
|
4014
4017
|
addListeners() {
|
|
4015
4018
|
var _a;
|
|
4019
|
+
if (!this.visualElement.current)
|
|
4020
|
+
return;
|
|
4016
4021
|
elementDragControls.set(this.visualElement, this);
|
|
4017
|
-
const element = this.visualElement.
|
|
4022
|
+
const element = this.visualElement.current;
|
|
4018
4023
|
/**
|
|
4019
4024
|
* Attach a pointerdown event listener on this DOM element to initiate drag tracking.
|
|
4020
4025
|
*/
|
|
@@ -4053,7 +4058,7 @@ class VisualElementDragControls {
|
|
|
4053
4058
|
this.originPoint[axis] += delta[axis].translate;
|
|
4054
4059
|
motionValue.set(motionValue.get() + delta[axis].translate);
|
|
4055
4060
|
});
|
|
4056
|
-
this.visualElement.
|
|
4061
|
+
this.visualElement.render();
|
|
4057
4062
|
}
|
|
4058
4063
|
}));
|
|
4059
4064
|
return () => {
|
|
@@ -4158,618 +4163,6 @@ const drag = {
|
|
|
4158
4163
|
drag: makeRenderlessComponent(useDrag),
|
|
4159
4164
|
};
|
|
4160
4165
|
|
|
4161
|
-
// Does this device prefer reduced motion? Returns `null` server-side.
|
|
4162
|
-
const prefersReducedMotion = { current: null };
|
|
4163
|
-
const hasReducedMotionListener = { current: false };
|
|
4164
|
-
|
|
4165
|
-
function initPrefersReducedMotion() {
|
|
4166
|
-
hasReducedMotionListener.current = true;
|
|
4167
|
-
if (!isBrowser)
|
|
4168
|
-
return;
|
|
4169
|
-
if (window.matchMedia) {
|
|
4170
|
-
const motionMediaQuery = window.matchMedia("(prefers-reduced-motion)");
|
|
4171
|
-
const setReducedMotionPreferences = () => (prefersReducedMotion.current = motionMediaQuery.matches);
|
|
4172
|
-
motionMediaQuery.addListener(setReducedMotionPreferences);
|
|
4173
|
-
setReducedMotionPreferences();
|
|
4174
|
-
}
|
|
4175
|
-
else {
|
|
4176
|
-
prefersReducedMotion.current = false;
|
|
4177
|
-
}
|
|
4178
|
-
}
|
|
4179
|
-
|
|
4180
|
-
const names = [
|
|
4181
|
-
"LayoutMeasure",
|
|
4182
|
-
"BeforeLayoutMeasure",
|
|
4183
|
-
"LayoutUpdate",
|
|
4184
|
-
"ViewportBoxUpdate",
|
|
4185
|
-
"Update",
|
|
4186
|
-
"Render",
|
|
4187
|
-
"AnimationComplete",
|
|
4188
|
-
"LayoutAnimationComplete",
|
|
4189
|
-
"AnimationStart",
|
|
4190
|
-
"LayoutAnimationStart",
|
|
4191
|
-
"SetAxisTarget",
|
|
4192
|
-
"Unmount",
|
|
4193
|
-
];
|
|
4194
|
-
function createLifecycles() {
|
|
4195
|
-
const managers = names.map(() => new SubscriptionManager());
|
|
4196
|
-
const propSubscriptions = {};
|
|
4197
|
-
const lifecycles = {
|
|
4198
|
-
clearAllListeners: () => managers.forEach((manager) => manager.clear()),
|
|
4199
|
-
updatePropListeners: (props) => {
|
|
4200
|
-
names.forEach((name) => {
|
|
4201
|
-
var _a;
|
|
4202
|
-
const on = "on" + name;
|
|
4203
|
-
const propListener = props[on];
|
|
4204
|
-
// Unsubscribe existing subscription
|
|
4205
|
-
(_a = propSubscriptions[name]) === null || _a === void 0 ? void 0 : _a.call(propSubscriptions);
|
|
4206
|
-
// Add new subscription
|
|
4207
|
-
if (propListener) {
|
|
4208
|
-
propSubscriptions[name] = lifecycles[on](propListener);
|
|
4209
|
-
}
|
|
4210
|
-
});
|
|
4211
|
-
},
|
|
4212
|
-
};
|
|
4213
|
-
managers.forEach((manager, i) => {
|
|
4214
|
-
lifecycles["on" + names[i]] = (handler) => manager.add(handler);
|
|
4215
|
-
lifecycles["notify" + names[i]] = (...args) => manager.notify(...args);
|
|
4216
|
-
});
|
|
4217
|
-
return lifecycles;
|
|
4218
|
-
}
|
|
4219
|
-
|
|
4220
|
-
function updateMotionValuesFromProps(element, next, prev) {
|
|
4221
|
-
const { willChange } = next;
|
|
4222
|
-
for (const key in next) {
|
|
4223
|
-
const nextValue = next[key];
|
|
4224
|
-
const prevValue = prev[key];
|
|
4225
|
-
if (isMotionValue(nextValue)) {
|
|
4226
|
-
/**
|
|
4227
|
-
* If this is a motion value found in props or style, we want to add it
|
|
4228
|
-
* to our visual element's motion value map.
|
|
4229
|
-
*/
|
|
4230
|
-
element.addValue(key, nextValue);
|
|
4231
|
-
if (isWillChangeMotionValue(willChange)) {
|
|
4232
|
-
willChange.add(key);
|
|
4233
|
-
}
|
|
4234
|
-
/**
|
|
4235
|
-
* Check the version of the incoming motion value with this version
|
|
4236
|
-
* and warn against mismatches.
|
|
4237
|
-
*/
|
|
4238
|
-
if (process.env.NODE_ENV === "development") {
|
|
4239
|
-
warnOnce(nextValue.version === "7.6.4", `Attempting to mix Framer Motion versions ${nextValue.version} with 7.6.4 may not work as expected.`);
|
|
4240
|
-
}
|
|
4241
|
-
}
|
|
4242
|
-
else if (isMotionValue(prevValue)) {
|
|
4243
|
-
/**
|
|
4244
|
-
* If we're swapping from a motion value to a static value,
|
|
4245
|
-
* create a new motion value from that
|
|
4246
|
-
*/
|
|
4247
|
-
element.addValue(key, motionValue(nextValue));
|
|
4248
|
-
if (isWillChangeMotionValue(willChange)) {
|
|
4249
|
-
willChange.remove(key);
|
|
4250
|
-
}
|
|
4251
|
-
}
|
|
4252
|
-
else if (prevValue !== nextValue) {
|
|
4253
|
-
/**
|
|
4254
|
-
* If this is a flat value that has changed, update the motion value
|
|
4255
|
-
* or create one if it doesn't exist. We only want to do this if we're
|
|
4256
|
-
* not handling the value with our animation state.
|
|
4257
|
-
*/
|
|
4258
|
-
if (element.hasValue(key)) {
|
|
4259
|
-
const existingValue = element.getValue(key);
|
|
4260
|
-
// TODO: Only update values that aren't being animated or even looked at
|
|
4261
|
-
!existingValue.hasAnimated && existingValue.set(nextValue);
|
|
4262
|
-
}
|
|
4263
|
-
else {
|
|
4264
|
-
const latestValue = element.getStaticValue(key);
|
|
4265
|
-
element.addValue(key, motionValue(latestValue !== undefined ? latestValue : nextValue));
|
|
4266
|
-
}
|
|
4267
|
-
}
|
|
4268
|
-
}
|
|
4269
|
-
// Handle removed values
|
|
4270
|
-
for (const key in prev) {
|
|
4271
|
-
if (next[key] === undefined)
|
|
4272
|
-
element.removeValue(key);
|
|
4273
|
-
}
|
|
4274
|
-
return next;
|
|
4275
|
-
}
|
|
4276
|
-
|
|
4277
|
-
const featureNames = Object.keys(featureDefinitions);
|
|
4278
|
-
const numFeatures = featureNames.length;
|
|
4279
|
-
const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatable, measureViewportBox, render: renderInstance, readValueFromInstance, removeValueFromRenderState, sortNodePosition, scrapeMotionValuesFromProps, }) => ({ parent, props, presenceId, blockInitialAnimation, visualState, reducedMotionConfig, }, options = {}) => {
|
|
4280
|
-
let isMounted = false;
|
|
4281
|
-
const { latestValues, renderState } = visualState;
|
|
4282
|
-
/**
|
|
4283
|
-
* The instance of the render-specific node that will be hydrated by the
|
|
4284
|
-
* exposed React ref. So for example, this visual element can host a
|
|
4285
|
-
* HTMLElement, plain object, or Three.js object. The functions provided
|
|
4286
|
-
* in VisualElementConfig allow us to interface with this instance.
|
|
4287
|
-
*/
|
|
4288
|
-
let instance;
|
|
4289
|
-
/**
|
|
4290
|
-
* Manages the subscriptions for a visual element's lifecycle, for instance
|
|
4291
|
-
* onRender
|
|
4292
|
-
*/
|
|
4293
|
-
const lifecycles = createLifecycles();
|
|
4294
|
-
/**
|
|
4295
|
-
* A map of all motion values attached to this visual element. Motion
|
|
4296
|
-
* values are source of truth for any given animated value. A motion
|
|
4297
|
-
* value might be provided externally by the component via props.
|
|
4298
|
-
*/
|
|
4299
|
-
const values = new Map();
|
|
4300
|
-
/**
|
|
4301
|
-
* A map of every subscription that binds the provided or generated
|
|
4302
|
-
* motion values onChange listeners to this visual element.
|
|
4303
|
-
*/
|
|
4304
|
-
const valueSubscriptions = new Map();
|
|
4305
|
-
/**
|
|
4306
|
-
* A reference to the previously-provided motion values as returned
|
|
4307
|
-
* from scrapeMotionValuesFromProps. We use the keys in here to determine
|
|
4308
|
-
* if any motion values need to be removed after props are updated.
|
|
4309
|
-
*/
|
|
4310
|
-
let prevMotionValues = {};
|
|
4311
|
-
/**
|
|
4312
|
-
* When values are removed from all animation props we need to search
|
|
4313
|
-
* for a fallback value to animate to. These values are tracked in baseTarget.
|
|
4314
|
-
*/
|
|
4315
|
-
const baseTarget = {
|
|
4316
|
-
...latestValues,
|
|
4317
|
-
};
|
|
4318
|
-
/**
|
|
4319
|
-
* Create an object of the values we initially animated from (if initial prop present).
|
|
4320
|
-
*/
|
|
4321
|
-
const initialValues = props.initial ? { ...latestValues } : {};
|
|
4322
|
-
// Internal methods ========================
|
|
4323
|
-
/**
|
|
4324
|
-
* On mount, this will be hydrated with a callback to disconnect
|
|
4325
|
-
* this visual element from its parent on unmount.
|
|
4326
|
-
*/
|
|
4327
|
-
let removeFromVariantTree;
|
|
4328
|
-
/**
|
|
4329
|
-
* Render the element with the latest styles outside of the React
|
|
4330
|
-
* render lifecycle
|
|
4331
|
-
*/
|
|
4332
|
-
function render() {
|
|
4333
|
-
if (!instance || !isMounted)
|
|
4334
|
-
return;
|
|
4335
|
-
triggerBuild();
|
|
4336
|
-
renderInstance(instance, renderState, props.style, element.projection);
|
|
4337
|
-
}
|
|
4338
|
-
function triggerBuild() {
|
|
4339
|
-
build(element, renderState, latestValues, options, props);
|
|
4340
|
-
}
|
|
4341
|
-
function update() {
|
|
4342
|
-
lifecycles.notifyUpdate(latestValues);
|
|
4343
|
-
}
|
|
4344
|
-
/**
|
|
4345
|
-
*
|
|
4346
|
-
*/
|
|
4347
|
-
function bindToMotionValue(key, value) {
|
|
4348
|
-
const removeOnChange = value.onChange((latestValue) => {
|
|
4349
|
-
latestValues[key] = latestValue;
|
|
4350
|
-
props.onUpdate && sync__default["default"].update(update, false, true);
|
|
4351
|
-
});
|
|
4352
|
-
const removeOnRenderRequest = value.onRenderRequest(element.scheduleRender);
|
|
4353
|
-
valueSubscriptions.set(key, () => {
|
|
4354
|
-
removeOnChange();
|
|
4355
|
-
removeOnRenderRequest();
|
|
4356
|
-
});
|
|
4357
|
-
}
|
|
4358
|
-
/**
|
|
4359
|
-
* Any motion values that are provided to the element when created
|
|
4360
|
-
* aren't yet bound to the element, as this would technically be impure.
|
|
4361
|
-
* However, we iterate through the motion values and set them to the
|
|
4362
|
-
* initial values for this component.
|
|
4363
|
-
*
|
|
4364
|
-
* TODO: This is impure and we should look at changing this to run on mount.
|
|
4365
|
-
* Doing so will break some tests but this isn't neccessarily a breaking change,
|
|
4366
|
-
* more a reflection of the test.
|
|
4367
|
-
*/
|
|
4368
|
-
const { willChange, ...initialMotionValues } = scrapeMotionValuesFromProps(props);
|
|
4369
|
-
for (const key in initialMotionValues) {
|
|
4370
|
-
const value = initialMotionValues[key];
|
|
4371
|
-
if (latestValues[key] !== undefined && isMotionValue(value)) {
|
|
4372
|
-
value.set(latestValues[key], false);
|
|
4373
|
-
if (isWillChangeMotionValue(willChange)) {
|
|
4374
|
-
willChange.add(key);
|
|
4375
|
-
}
|
|
4376
|
-
}
|
|
4377
|
-
}
|
|
4378
|
-
/**
|
|
4379
|
-
* Update external values with initial values
|
|
4380
|
-
*/
|
|
4381
|
-
if (props.values) {
|
|
4382
|
-
for (const key in props.values) {
|
|
4383
|
-
const value = props.values[key];
|
|
4384
|
-
if (latestValues[key] !== undefined && isMotionValue(value)) {
|
|
4385
|
-
value.set(latestValues[key]);
|
|
4386
|
-
}
|
|
4387
|
-
}
|
|
4388
|
-
}
|
|
4389
|
-
/**
|
|
4390
|
-
* Determine what role this visual element should take in the variant tree.
|
|
4391
|
-
*/
|
|
4392
|
-
const isControllingVariants$1 = isControllingVariants(props);
|
|
4393
|
-
const isVariantNode$1 = isVariantNode(props);
|
|
4394
|
-
const element = {
|
|
4395
|
-
treeType,
|
|
4396
|
-
/**
|
|
4397
|
-
* This is a mirror of the internal instance prop, which keeps
|
|
4398
|
-
* VisualElement type-compatible with React's RefObject.
|
|
4399
|
-
*/
|
|
4400
|
-
current: null,
|
|
4401
|
-
/**
|
|
4402
|
-
* The depth of this visual element within the visual element tree.
|
|
4403
|
-
*/
|
|
4404
|
-
depth: parent ? parent.depth + 1 : 0,
|
|
4405
|
-
parent,
|
|
4406
|
-
children: new Set(),
|
|
4407
|
-
/**
|
|
4408
|
-
*
|
|
4409
|
-
*/
|
|
4410
|
-
presenceId,
|
|
4411
|
-
shouldReduceMotion: null,
|
|
4412
|
-
/**
|
|
4413
|
-
* If this component is part of the variant tree, it should track
|
|
4414
|
-
* any children that are also part of the tree. This is essentially
|
|
4415
|
-
* a shadow tree to simplify logic around how to stagger over children.
|
|
4416
|
-
*/
|
|
4417
|
-
variantChildren: isVariantNode$1 ? new Set() : undefined,
|
|
4418
|
-
/**
|
|
4419
|
-
* Whether this instance is visible. This can be changed imperatively
|
|
4420
|
-
* by the projection tree, is analogous to CSS's visibility in that
|
|
4421
|
-
* hidden elements should take up layout, and needs enacting by the configured
|
|
4422
|
-
* render function.
|
|
4423
|
-
*/
|
|
4424
|
-
isVisible: undefined,
|
|
4425
|
-
/**
|
|
4426
|
-
* Normally, if a component is controlled by a parent's variants, it can
|
|
4427
|
-
* rely on that ancestor to trigger animations further down the tree.
|
|
4428
|
-
* However, if a component is created after its parent is mounted, the parent
|
|
4429
|
-
* won't trigger that mount animation so the child needs to.
|
|
4430
|
-
*
|
|
4431
|
-
* TODO: This might be better replaced with a method isParentMounted
|
|
4432
|
-
*/
|
|
4433
|
-
manuallyAnimateOnMount: Boolean(parent === null || parent === void 0 ? void 0 : parent.isMounted()),
|
|
4434
|
-
/**
|
|
4435
|
-
* This can be set by AnimatePresence to force components that mount
|
|
4436
|
-
* at the same time as it to mount as if they have initial={false} set.
|
|
4437
|
-
*/
|
|
4438
|
-
blockInitialAnimation,
|
|
4439
|
-
/**
|
|
4440
|
-
* Determine whether this component has mounted yet. This is mostly used
|
|
4441
|
-
* by variant children to determine whether they need to trigger their
|
|
4442
|
-
* own animations on mount.
|
|
4443
|
-
*/
|
|
4444
|
-
isMounted: () => Boolean(instance),
|
|
4445
|
-
mount(newInstance) {
|
|
4446
|
-
isMounted = true;
|
|
4447
|
-
instance = element.current = newInstance;
|
|
4448
|
-
if (element.projection) {
|
|
4449
|
-
element.projection.mount(newInstance);
|
|
4450
|
-
}
|
|
4451
|
-
if (isVariantNode$1 && parent && !isControllingVariants$1) {
|
|
4452
|
-
removeFromVariantTree = parent === null || parent === void 0 ? void 0 : parent.addVariantChild(element);
|
|
4453
|
-
}
|
|
4454
|
-
values.forEach((value, key) => bindToMotionValue(key, value));
|
|
4455
|
-
if (!hasReducedMotionListener.current) {
|
|
4456
|
-
initPrefersReducedMotion();
|
|
4457
|
-
}
|
|
4458
|
-
element.shouldReduceMotion =
|
|
4459
|
-
reducedMotionConfig === "never"
|
|
4460
|
-
? false
|
|
4461
|
-
: reducedMotionConfig === "always"
|
|
4462
|
-
? true
|
|
4463
|
-
: prefersReducedMotion.current;
|
|
4464
|
-
parent === null || parent === void 0 ? void 0 : parent.children.add(element);
|
|
4465
|
-
element.setProps(props);
|
|
4466
|
-
},
|
|
4467
|
-
/**
|
|
4468
|
-
*
|
|
4469
|
-
*/
|
|
4470
|
-
unmount() {
|
|
4471
|
-
var _a;
|
|
4472
|
-
(_a = element.projection) === null || _a === void 0 ? void 0 : _a.unmount();
|
|
4473
|
-
sync.cancelSync.update(update);
|
|
4474
|
-
sync.cancelSync.render(render);
|
|
4475
|
-
valueSubscriptions.forEach((remove) => remove());
|
|
4476
|
-
removeFromVariantTree === null || removeFromVariantTree === void 0 ? void 0 : removeFromVariantTree();
|
|
4477
|
-
parent === null || parent === void 0 ? void 0 : parent.children.delete(element);
|
|
4478
|
-
lifecycles.clearAllListeners();
|
|
4479
|
-
instance = undefined;
|
|
4480
|
-
isMounted = false;
|
|
4481
|
-
},
|
|
4482
|
-
loadFeatures(renderedProps, isStrict, preloadedFeatures, projectionId, ProjectionNodeConstructor, initialLayoutGroupConfig) {
|
|
4483
|
-
const features = [];
|
|
4484
|
-
/**
|
|
4485
|
-
* If we're in development mode, check to make sure we're not rendering a motion component
|
|
4486
|
-
* as a child of LazyMotion, as this will break the file-size benefits of using it.
|
|
4487
|
-
*/
|
|
4488
|
-
if (env !== "production" && preloadedFeatures && isStrict) {
|
|
4489
|
-
heyListen.invariant(false, "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.");
|
|
4490
|
-
}
|
|
4491
|
-
for (let i = 0; i < numFeatures; i++) {
|
|
4492
|
-
const name = featureNames[i];
|
|
4493
|
-
const { isEnabled, Component } = featureDefinitions[name];
|
|
4494
|
-
/**
|
|
4495
|
-
* It might be possible in the future to use this moment to
|
|
4496
|
-
* dynamically request functionality. In initial tests this
|
|
4497
|
-
* was producing a lot of duplication amongst bundles.
|
|
4498
|
-
*/
|
|
4499
|
-
if (isEnabled(renderedProps) && Component) {
|
|
4500
|
-
features.push(React.createElement(Component, {
|
|
4501
|
-
key: name,
|
|
4502
|
-
...renderedProps,
|
|
4503
|
-
visualElement: element,
|
|
4504
|
-
}));
|
|
4505
|
-
}
|
|
4506
|
-
}
|
|
4507
|
-
if (!element.projection && ProjectionNodeConstructor) {
|
|
4508
|
-
element.projection = new ProjectionNodeConstructor(projectionId, element.getLatestValues(), parent && parent.projection);
|
|
4509
|
-
const { layoutId, layout, drag, dragConstraints, layoutScroll, } = renderedProps;
|
|
4510
|
-
element.projection.setOptions({
|
|
4511
|
-
layoutId,
|
|
4512
|
-
layout,
|
|
4513
|
-
alwaysMeasureLayout: Boolean(drag) ||
|
|
4514
|
-
(dragConstraints && isRefObject(dragConstraints)),
|
|
4515
|
-
visualElement: element,
|
|
4516
|
-
scheduleRender: () => element.scheduleRender(),
|
|
4517
|
-
/**
|
|
4518
|
-
* TODO: Update options in an effect. This could be tricky as it'll be too late
|
|
4519
|
-
* to update by the time layout animations run.
|
|
4520
|
-
* We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
|
|
4521
|
-
* ensuring it gets called if there's no potential layout animations.
|
|
4522
|
-
*
|
|
4523
|
-
*/
|
|
4524
|
-
animationType: typeof layout === "string" ? layout : "both",
|
|
4525
|
-
initialPromotionConfig: initialLayoutGroupConfig,
|
|
4526
|
-
layoutScroll,
|
|
4527
|
-
});
|
|
4528
|
-
}
|
|
4529
|
-
return features;
|
|
4530
|
-
},
|
|
4531
|
-
/**
|
|
4532
|
-
* Add a child visual element to our set of children.
|
|
4533
|
-
*/
|
|
4534
|
-
addVariantChild(child) {
|
|
4535
|
-
var _a;
|
|
4536
|
-
const closestVariantNode = element.getClosestVariantNode();
|
|
4537
|
-
if (closestVariantNode) {
|
|
4538
|
-
(_a = closestVariantNode.variantChildren) === null || _a === void 0 ? void 0 : _a.add(child);
|
|
4539
|
-
return () => closestVariantNode.variantChildren.delete(child);
|
|
4540
|
-
}
|
|
4541
|
-
},
|
|
4542
|
-
sortNodePosition(other) {
|
|
4543
|
-
/**
|
|
4544
|
-
* If these nodes aren't even of the same type we can't compare their depth.
|
|
4545
|
-
*/
|
|
4546
|
-
if (!sortNodePosition || treeType !== other.treeType)
|
|
4547
|
-
return 0;
|
|
4548
|
-
return sortNodePosition(element.getInstance(), other.getInstance());
|
|
4549
|
-
},
|
|
4550
|
-
/**
|
|
4551
|
-
* Returns the closest variant node in the tree starting from
|
|
4552
|
-
* this visual element.
|
|
4553
|
-
*/
|
|
4554
|
-
getClosestVariantNode: () => isVariantNode$1 ? element : parent === null || parent === void 0 ? void 0 : parent.getClosestVariantNode(),
|
|
4555
|
-
/**
|
|
4556
|
-
* Expose the latest layoutId prop.
|
|
4557
|
-
*/
|
|
4558
|
-
getLayoutId: () => props.layoutId,
|
|
4559
|
-
/**
|
|
4560
|
-
* Returns the current instance.
|
|
4561
|
-
*/
|
|
4562
|
-
getInstance: () => instance,
|
|
4563
|
-
/**
|
|
4564
|
-
* Get/set the latest static values.
|
|
4565
|
-
*/
|
|
4566
|
-
getStaticValue: (key) => latestValues[key],
|
|
4567
|
-
setStaticValue: (key, value) => (latestValues[key] = value),
|
|
4568
|
-
/**
|
|
4569
|
-
* Returns the latest motion value state. Currently only used to take
|
|
4570
|
-
* a snapshot of the visual element - perhaps this can return the whole
|
|
4571
|
-
* visual state
|
|
4572
|
-
*/
|
|
4573
|
-
getLatestValues: () => latestValues,
|
|
4574
|
-
/**
|
|
4575
|
-
* Set the visiblity of the visual element. If it's changed, schedule
|
|
4576
|
-
* a render to reflect these changes.
|
|
4577
|
-
*/
|
|
4578
|
-
setVisibility(visibility) {
|
|
4579
|
-
if (element.isVisible === visibility)
|
|
4580
|
-
return;
|
|
4581
|
-
element.isVisible = visibility;
|
|
4582
|
-
element.scheduleRender();
|
|
4583
|
-
},
|
|
4584
|
-
/**
|
|
4585
|
-
* Make a target animatable by Popmotion. For instance, if we're
|
|
4586
|
-
* trying to animate width from 100px to 100vw we need to measure 100vw
|
|
4587
|
-
* in pixels to determine what we really need to animate to. This is also
|
|
4588
|
-
* pluggable to support Framer's custom value types like Color,
|
|
4589
|
-
* and CSS variables.
|
|
4590
|
-
*/
|
|
4591
|
-
makeTargetAnimatable(target, canMutate = true) {
|
|
4592
|
-
return makeTargetAnimatable(element, target, props, canMutate);
|
|
4593
|
-
},
|
|
4594
|
-
/**
|
|
4595
|
-
* Measure the current viewport box with or without transforms.
|
|
4596
|
-
* Only measures axis-aligned boxes, rotate and skew must be manually
|
|
4597
|
-
* removed with a re-render to work.
|
|
4598
|
-
*/
|
|
4599
|
-
measureViewportBox() {
|
|
4600
|
-
return measureViewportBox(instance, props);
|
|
4601
|
-
},
|
|
4602
|
-
// Motion values ========================
|
|
4603
|
-
/**
|
|
4604
|
-
* Add a motion value and bind it to this visual element.
|
|
4605
|
-
*/
|
|
4606
|
-
addValue(key, value) {
|
|
4607
|
-
// Remove existing value if it exists
|
|
4608
|
-
if (element.hasValue(key))
|
|
4609
|
-
element.removeValue(key);
|
|
4610
|
-
values.set(key, value);
|
|
4611
|
-
latestValues[key] = value.get();
|
|
4612
|
-
bindToMotionValue(key, value);
|
|
4613
|
-
},
|
|
4614
|
-
/**
|
|
4615
|
-
* Remove a motion value and unbind any active subscriptions.
|
|
4616
|
-
*/
|
|
4617
|
-
removeValue(key) {
|
|
4618
|
-
var _a;
|
|
4619
|
-
values.delete(key);
|
|
4620
|
-
(_a = valueSubscriptions.get(key)) === null || _a === void 0 ? void 0 : _a();
|
|
4621
|
-
valueSubscriptions.delete(key);
|
|
4622
|
-
delete latestValues[key];
|
|
4623
|
-
removeValueFromRenderState(key, renderState);
|
|
4624
|
-
},
|
|
4625
|
-
/**
|
|
4626
|
-
* Check whether we have a motion value for this key
|
|
4627
|
-
*/
|
|
4628
|
-
hasValue: (key) => values.has(key),
|
|
4629
|
-
/**
|
|
4630
|
-
* Get a motion value for this key. If called with a default
|
|
4631
|
-
* value, we'll create one if none exists.
|
|
4632
|
-
*/
|
|
4633
|
-
getValue(key, defaultValue) {
|
|
4634
|
-
if (props.values && props.values[key]) {
|
|
4635
|
-
return props.values[key];
|
|
4636
|
-
}
|
|
4637
|
-
let value = values.get(key);
|
|
4638
|
-
if (value === undefined && defaultValue !== undefined) {
|
|
4639
|
-
value = motionValue(defaultValue);
|
|
4640
|
-
element.addValue(key, value);
|
|
4641
|
-
}
|
|
4642
|
-
return value;
|
|
4643
|
-
},
|
|
4644
|
-
/**
|
|
4645
|
-
* Iterate over our motion values.
|
|
4646
|
-
*/
|
|
4647
|
-
forEachValue: (callback) => values.forEach(callback),
|
|
4648
|
-
/**
|
|
4649
|
-
* If we're trying to animate to a previously unencountered value,
|
|
4650
|
-
* we need to check for it in our state and as a last resort read it
|
|
4651
|
-
* directly from the instance (which might have performance implications).
|
|
4652
|
-
*/
|
|
4653
|
-
readValue: (key) => latestValues[key] !== undefined
|
|
4654
|
-
? latestValues[key]
|
|
4655
|
-
: readValueFromInstance(instance, key, options),
|
|
4656
|
-
/**
|
|
4657
|
-
* Set the base target to later animate back to. This is currently
|
|
4658
|
-
* only hydrated on creation and when we first read a value.
|
|
4659
|
-
*/
|
|
4660
|
-
setBaseTarget(key, value) {
|
|
4661
|
-
baseTarget[key] = value;
|
|
4662
|
-
},
|
|
4663
|
-
/**
|
|
4664
|
-
* Find the base target for a value thats been removed from all animation
|
|
4665
|
-
* props.
|
|
4666
|
-
*/
|
|
4667
|
-
getBaseTarget(key) {
|
|
4668
|
-
var _a;
|
|
4669
|
-
const { initial } = props;
|
|
4670
|
-
const valueFromInitial = typeof initial === "string" || typeof initial === "object"
|
|
4671
|
-
? (_a = resolveVariantFromProps(props, initial)) === null || _a === void 0 ? void 0 : _a[key]
|
|
4672
|
-
: undefined;
|
|
4673
|
-
/**
|
|
4674
|
-
* If this value still exists in the current initial variant, read that.
|
|
4675
|
-
*/
|
|
4676
|
-
if (initial && valueFromInitial !== undefined) {
|
|
4677
|
-
return valueFromInitial;
|
|
4678
|
-
}
|
|
4679
|
-
/**
|
|
4680
|
-
* Alternatively, if this VisualElement config has defined a getBaseTarget
|
|
4681
|
-
* so we can read the value from an alternative source, try that.
|
|
4682
|
-
*/
|
|
4683
|
-
if (getBaseTarget) {
|
|
4684
|
-
const target = getBaseTarget(props, key);
|
|
4685
|
-
if (target !== undefined && !isMotionValue(target))
|
|
4686
|
-
return target;
|
|
4687
|
-
}
|
|
4688
|
-
/**
|
|
4689
|
-
* If the value was initially defined on initial, but it doesn't any more,
|
|
4690
|
-
* return undefined. Otherwise return the value as initially read from the DOM.
|
|
4691
|
-
*/
|
|
4692
|
-
return initialValues[key] !== undefined &&
|
|
4693
|
-
valueFromInitial === undefined
|
|
4694
|
-
? undefined
|
|
4695
|
-
: baseTarget[key];
|
|
4696
|
-
},
|
|
4697
|
-
// Lifecyles ========================
|
|
4698
|
-
...lifecycles,
|
|
4699
|
-
/**
|
|
4700
|
-
* Build the renderer state based on the latest visual state.
|
|
4701
|
-
*/
|
|
4702
|
-
build() {
|
|
4703
|
-
triggerBuild();
|
|
4704
|
-
return renderState;
|
|
4705
|
-
},
|
|
4706
|
-
/**
|
|
4707
|
-
* Schedule a render on the next animation frame.
|
|
4708
|
-
*/
|
|
4709
|
-
scheduleRender() {
|
|
4710
|
-
sync__default["default"].render(render, false, true);
|
|
4711
|
-
},
|
|
4712
|
-
/**
|
|
4713
|
-
* Synchronously fire render. It's prefered that we batch renders but
|
|
4714
|
-
* in many circumstances, like layout measurement, we need to run this
|
|
4715
|
-
* synchronously. However in those instances other measures should be taken
|
|
4716
|
-
* to batch reads/writes.
|
|
4717
|
-
*/
|
|
4718
|
-
syncRender: render,
|
|
4719
|
-
/**
|
|
4720
|
-
* Update the provided props. Ensure any newly-added motion values are
|
|
4721
|
-
* added to our map, old ones removed, and listeners updated.
|
|
4722
|
-
*/
|
|
4723
|
-
setProps(newProps) {
|
|
4724
|
-
if (newProps.transformTemplate || props.transformTemplate) {
|
|
4725
|
-
element.scheduleRender();
|
|
4726
|
-
}
|
|
4727
|
-
props = newProps;
|
|
4728
|
-
lifecycles.updatePropListeners(newProps);
|
|
4729
|
-
prevMotionValues = updateMotionValuesFromProps(element, scrapeMotionValuesFromProps(props), prevMotionValues);
|
|
4730
|
-
},
|
|
4731
|
-
getProps: () => props,
|
|
4732
|
-
// Variants ==============================
|
|
4733
|
-
/**
|
|
4734
|
-
* Returns the variant definition with a given name.
|
|
4735
|
-
*/
|
|
4736
|
-
getVariant: (name) => { var _a; return (_a = props.variants) === null || _a === void 0 ? void 0 : _a[name]; },
|
|
4737
|
-
/**
|
|
4738
|
-
* Returns the defined default transition on this component.
|
|
4739
|
-
*/
|
|
4740
|
-
getDefaultTransition: () => props.transition,
|
|
4741
|
-
getTransformPagePoint: () => {
|
|
4742
|
-
return props.transformPagePoint;
|
|
4743
|
-
},
|
|
4744
|
-
/**
|
|
4745
|
-
* Used by child variant nodes to get the closest ancestor variant props.
|
|
4746
|
-
*/
|
|
4747
|
-
getVariantContext(startAtParent = false) {
|
|
4748
|
-
if (startAtParent)
|
|
4749
|
-
return parent === null || parent === void 0 ? void 0 : parent.getVariantContext();
|
|
4750
|
-
if (!isControllingVariants$1) {
|
|
4751
|
-
const context = (parent === null || parent === void 0 ? void 0 : parent.getVariantContext()) || {};
|
|
4752
|
-
if (props.initial !== undefined) {
|
|
4753
|
-
context.initial = props.initial;
|
|
4754
|
-
}
|
|
4755
|
-
return context;
|
|
4756
|
-
}
|
|
4757
|
-
const context = {};
|
|
4758
|
-
for (let i = 0; i < numVariantProps; i++) {
|
|
4759
|
-
const name = variantProps[i];
|
|
4760
|
-
const prop = props[name];
|
|
4761
|
-
if (isVariantLabel(prop) || prop === false) {
|
|
4762
|
-
context[name] = prop;
|
|
4763
|
-
}
|
|
4764
|
-
}
|
|
4765
|
-
return context;
|
|
4766
|
-
},
|
|
4767
|
-
};
|
|
4768
|
-
return element;
|
|
4769
|
-
};
|
|
4770
|
-
const variantProps = ["initial", ...variantPriorityOrder];
|
|
4771
|
-
const numVariantProps = variantProps.length;
|
|
4772
|
-
|
|
4773
4166
|
function isCSSVariable(value) {
|
|
4774
4167
|
return typeof value === "string" && value.startsWith("var(--");
|
|
4775
4168
|
}
|
|
@@ -4816,7 +4209,7 @@ function getVariableValue(current, element, depth = 1) {
|
|
|
4816
4209
|
* @internal
|
|
4817
4210
|
*/
|
|
4818
4211
|
function resolveCSSVariables(visualElement, { ...target }, transitionEnd) {
|
|
4819
|
-
const element = visualElement.
|
|
4212
|
+
const element = visualElement.current;
|
|
4820
4213
|
if (!(element instanceof Element))
|
|
4821
4214
|
return { target, transitionEnd };
|
|
4822
4215
|
// If `transitionEnd` isn't `undefined`, clone it. We could clone `target` and `transitionEnd`
|
|
@@ -4825,7 +4218,7 @@ function resolveCSSVariables(visualElement, { ...target }, transitionEnd) {
|
|
|
4825
4218
|
transitionEnd = { ...transitionEnd };
|
|
4826
4219
|
}
|
|
4827
4220
|
// Go through existing `MotionValue`s and ensure any existing CSS variables are resolved
|
|
4828
|
-
visualElement.
|
|
4221
|
+
visualElement.values.forEach((value) => {
|
|
4829
4222
|
const current = value.get();
|
|
4830
4223
|
if (!isCSSVariable(current))
|
|
4831
4224
|
return;
|
|
@@ -4915,7 +4308,7 @@ function removeNonTranslationalTransform(visualElement) {
|
|
|
4915
4308
|
});
|
|
4916
4309
|
// Apply changes to element before measurement
|
|
4917
4310
|
if (removedTransforms.length)
|
|
4918
|
-
visualElement.
|
|
4311
|
+
visualElement.render();
|
|
4919
4312
|
return removedTransforms;
|
|
4920
4313
|
}
|
|
4921
4314
|
const positionalValues = {
|
|
@@ -4932,7 +4325,7 @@ const positionalValues = {
|
|
|
4932
4325
|
};
|
|
4933
4326
|
const convertChangedValueTypes = (target, visualElement, changedKeys) => {
|
|
4934
4327
|
const originBbox = visualElement.measureViewportBox();
|
|
4935
|
-
const element = visualElement.
|
|
4328
|
+
const element = visualElement.current;
|
|
4936
4329
|
const elementComputedStyle = getComputedStyle(element);
|
|
4937
4330
|
const { display } = elementComputedStyle;
|
|
4938
4331
|
const origin = {};
|
|
@@ -4948,7 +4341,7 @@ const convertChangedValueTypes = (target, visualElement, changedKeys) => {
|
|
|
4948
4341
|
origin[key] = positionalValues[key](originBbox, elementComputedStyle);
|
|
4949
4342
|
});
|
|
4950
4343
|
// Apply the latest values (as set in checkAndConvertChangedValueTypes)
|
|
4951
|
-
visualElement.
|
|
4344
|
+
visualElement.render();
|
|
4952
4345
|
const targetBbox = visualElement.measureViewportBox();
|
|
4953
4346
|
changedKeys.forEach((key) => {
|
|
4954
4347
|
// Restore styles to their **calculated computed style**, not their actual
|
|
@@ -5026,131 +4419,625 @@ const checkAndConvertChangedValueTypes = (visualElement, target, origin = {}, tr
|
|
|
5026
4419
|
target[key] = fromType.transform(to);
|
|
5027
4420
|
}
|
|
5028
4421
|
}
|
|
5029
|
-
else {
|
|
5030
|
-
// If we're going to do value conversion via DOM measurements, we first
|
|
5031
|
-
// need to remove non-positional transform values that could affect the bbox measurements.
|
|
5032
|
-
if (!hasAttemptedToRemoveTransformValues) {
|
|
5033
|
-
removedTransformValues =
|
|
5034
|
-
removeNonTranslationalTransform(visualElement);
|
|
5035
|
-
hasAttemptedToRemoveTransformValues = true;
|
|
4422
|
+
else {
|
|
4423
|
+
// If we're going to do value conversion via DOM measurements, we first
|
|
4424
|
+
// need to remove non-positional transform values that could affect the bbox measurements.
|
|
4425
|
+
if (!hasAttemptedToRemoveTransformValues) {
|
|
4426
|
+
removedTransformValues =
|
|
4427
|
+
removeNonTranslationalTransform(visualElement);
|
|
4428
|
+
hasAttemptedToRemoveTransformValues = true;
|
|
4429
|
+
}
|
|
4430
|
+
changedValueTypeKeys.push(key);
|
|
4431
|
+
transitionEnd[key] =
|
|
4432
|
+
transitionEnd[key] !== undefined
|
|
4433
|
+
? transitionEnd[key]
|
|
4434
|
+
: target[key];
|
|
4435
|
+
setAndResetVelocity(value, to);
|
|
4436
|
+
}
|
|
4437
|
+
}
|
|
4438
|
+
});
|
|
4439
|
+
if (changedValueTypeKeys.length) {
|
|
4440
|
+
const scrollY = changedValueTypeKeys.indexOf("height") >= 0
|
|
4441
|
+
? window.pageYOffset
|
|
4442
|
+
: null;
|
|
4443
|
+
const convertedTarget = convertChangedValueTypes(target, visualElement, changedValueTypeKeys);
|
|
4444
|
+
// If we removed transform values, reapply them before the next render
|
|
4445
|
+
if (removedTransformValues.length) {
|
|
4446
|
+
removedTransformValues.forEach(([key, value]) => {
|
|
4447
|
+
visualElement.getValue(key).set(value);
|
|
4448
|
+
});
|
|
4449
|
+
}
|
|
4450
|
+
// Reapply original values
|
|
4451
|
+
visualElement.render();
|
|
4452
|
+
// Restore scroll position
|
|
4453
|
+
if (isBrowser && scrollY !== null) {
|
|
4454
|
+
window.scrollTo({ top: scrollY });
|
|
4455
|
+
}
|
|
4456
|
+
return { target: convertedTarget, transitionEnd };
|
|
4457
|
+
}
|
|
4458
|
+
else {
|
|
4459
|
+
return { target, transitionEnd };
|
|
4460
|
+
}
|
|
4461
|
+
};
|
|
4462
|
+
/**
|
|
4463
|
+
* Convert value types for x/y/width/height/top/left/bottom/right
|
|
4464
|
+
*
|
|
4465
|
+
* Allows animation between `'auto'` -> `'100%'` or `0` -> `'calc(50% - 10vw)'`
|
|
4466
|
+
*
|
|
4467
|
+
* @internal
|
|
4468
|
+
*/
|
|
4469
|
+
function unitConversion(visualElement, target, origin, transitionEnd) {
|
|
4470
|
+
return hasPositionalKey(target)
|
|
4471
|
+
? checkAndConvertChangedValueTypes(visualElement, target, origin, transitionEnd)
|
|
4472
|
+
: { target, transitionEnd };
|
|
4473
|
+
}
|
|
4474
|
+
|
|
4475
|
+
/**
|
|
4476
|
+
* Parse a DOM variant to make it animatable. This involves resolving CSS variables
|
|
4477
|
+
* and ensuring animations like "20%" => "calc(50vw)" are performed in pixels.
|
|
4478
|
+
*/
|
|
4479
|
+
const parseDomVariant = (visualElement, target, origin, transitionEnd) => {
|
|
4480
|
+
const resolved = resolveCSSVariables(visualElement, target, transitionEnd);
|
|
4481
|
+
target = resolved.target;
|
|
4482
|
+
transitionEnd = resolved.transitionEnd;
|
|
4483
|
+
return unitConversion(visualElement, target, origin, transitionEnd);
|
|
4484
|
+
};
|
|
4485
|
+
|
|
4486
|
+
// Does this device prefer reduced motion? Returns `null` server-side.
|
|
4487
|
+
const prefersReducedMotion = { current: null };
|
|
4488
|
+
const hasReducedMotionListener = { current: false };
|
|
4489
|
+
|
|
4490
|
+
function initPrefersReducedMotion() {
|
|
4491
|
+
hasReducedMotionListener.current = true;
|
|
4492
|
+
if (!isBrowser)
|
|
4493
|
+
return;
|
|
4494
|
+
if (window.matchMedia) {
|
|
4495
|
+
const motionMediaQuery = window.matchMedia("(prefers-reduced-motion)");
|
|
4496
|
+
const setReducedMotionPreferences = () => (prefersReducedMotion.current = motionMediaQuery.matches);
|
|
4497
|
+
motionMediaQuery.addListener(setReducedMotionPreferences);
|
|
4498
|
+
setReducedMotionPreferences();
|
|
4499
|
+
}
|
|
4500
|
+
else {
|
|
4501
|
+
prefersReducedMotion.current = false;
|
|
4502
|
+
}
|
|
4503
|
+
}
|
|
4504
|
+
|
|
4505
|
+
function updateMotionValuesFromProps(element, next, prev) {
|
|
4506
|
+
const { willChange } = next;
|
|
4507
|
+
for (const key in next) {
|
|
4508
|
+
const nextValue = next[key];
|
|
4509
|
+
const prevValue = prev[key];
|
|
4510
|
+
if (isMotionValue(nextValue)) {
|
|
4511
|
+
/**
|
|
4512
|
+
* If this is a motion value found in props or style, we want to add it
|
|
4513
|
+
* to our visual element's motion value map.
|
|
4514
|
+
*/
|
|
4515
|
+
element.addValue(key, nextValue);
|
|
4516
|
+
if (isWillChangeMotionValue(willChange)) {
|
|
4517
|
+
willChange.add(key);
|
|
4518
|
+
}
|
|
4519
|
+
/**
|
|
4520
|
+
* Check the version of the incoming motion value with this version
|
|
4521
|
+
* and warn against mismatches.
|
|
4522
|
+
*/
|
|
4523
|
+
if (process.env.NODE_ENV === "development") {
|
|
4524
|
+
warnOnce(nextValue.version === "7.6.6", `Attempting to mix Framer Motion versions ${nextValue.version} with 7.6.6 may not work as expected.`);
|
|
4525
|
+
}
|
|
4526
|
+
}
|
|
4527
|
+
else if (isMotionValue(prevValue)) {
|
|
4528
|
+
/**
|
|
4529
|
+
* If we're swapping from a motion value to a static value,
|
|
4530
|
+
* create a new motion value from that
|
|
4531
|
+
*/
|
|
4532
|
+
element.addValue(key, motionValue(nextValue));
|
|
4533
|
+
if (isWillChangeMotionValue(willChange)) {
|
|
4534
|
+
willChange.remove(key);
|
|
4535
|
+
}
|
|
4536
|
+
}
|
|
4537
|
+
else if (prevValue !== nextValue) {
|
|
4538
|
+
/**
|
|
4539
|
+
* If this is a flat value that has changed, update the motion value
|
|
4540
|
+
* or create one if it doesn't exist. We only want to do this if we're
|
|
4541
|
+
* not handling the value with our animation state.
|
|
4542
|
+
*/
|
|
4543
|
+
if (element.hasValue(key)) {
|
|
4544
|
+
const existingValue = element.getValue(key);
|
|
4545
|
+
// TODO: Only update values that aren't being animated or even looked at
|
|
4546
|
+
!existingValue.hasAnimated && existingValue.set(nextValue);
|
|
4547
|
+
}
|
|
4548
|
+
else {
|
|
4549
|
+
const latestValue = element.getStaticValue(key);
|
|
4550
|
+
element.addValue(key, motionValue(latestValue !== undefined ? latestValue : nextValue));
|
|
4551
|
+
}
|
|
4552
|
+
}
|
|
4553
|
+
}
|
|
4554
|
+
// Handle removed values
|
|
4555
|
+
for (const key in prev) {
|
|
4556
|
+
if (next[key] === undefined)
|
|
4557
|
+
element.removeValue(key);
|
|
4558
|
+
}
|
|
4559
|
+
return next;
|
|
4560
|
+
}
|
|
4561
|
+
|
|
4562
|
+
const featureNames = Object.keys(featureDefinitions);
|
|
4563
|
+
const numFeatures = featureNames.length;
|
|
4564
|
+
const propEventHandlers = [
|
|
4565
|
+
"AnimationStart",
|
|
4566
|
+
"AnimationComplete",
|
|
4567
|
+
"Update",
|
|
4568
|
+
"Unmount",
|
|
4569
|
+
"BeforeLayoutMeasure",
|
|
4570
|
+
"LayoutMeasure",
|
|
4571
|
+
"LayoutAnimationStart",
|
|
4572
|
+
"LayoutAnimationComplete",
|
|
4573
|
+
];
|
|
4574
|
+
/**
|
|
4575
|
+
* A VisualElement is an imperative abstraction around UI elements such as
|
|
4576
|
+
* HTMLElement, SVGElement, Three.Object3D etc.
|
|
4577
|
+
*/
|
|
4578
|
+
class VisualElement {
|
|
4579
|
+
constructor({ parent, props, reducedMotionConfig, visualState, }, options = {}) {
|
|
4580
|
+
/**
|
|
4581
|
+
* A reference to the current underlying Instance, e.g. a HTMLElement
|
|
4582
|
+
* or Three.Mesh etc.
|
|
4583
|
+
*/
|
|
4584
|
+
this.current = null;
|
|
4585
|
+
/**
|
|
4586
|
+
* A set containing references to this VisualElement's children.
|
|
4587
|
+
*/
|
|
4588
|
+
this.children = new Set();
|
|
4589
|
+
/**
|
|
4590
|
+
* Determine what role this visual element should take in the variant tree.
|
|
4591
|
+
*/
|
|
4592
|
+
this.isVariantNode = false;
|
|
4593
|
+
this.isControllingVariants = false;
|
|
4594
|
+
/**
|
|
4595
|
+
* Decides whether this VisualElement should animate in reduced motion
|
|
4596
|
+
* mode.
|
|
4597
|
+
*
|
|
4598
|
+
* TODO: This is currently set on every individual VisualElement but feels
|
|
4599
|
+
* like it could be set globally.
|
|
4600
|
+
*/
|
|
4601
|
+
this.shouldReduceMotion = null;
|
|
4602
|
+
/**
|
|
4603
|
+
* A map of all motion values attached to this visual element. Motion
|
|
4604
|
+
* values are source of truth for any given animated value. A motion
|
|
4605
|
+
* value might be provided externally by the component via props.
|
|
4606
|
+
*/
|
|
4607
|
+
this.values = new Map();
|
|
4608
|
+
/**
|
|
4609
|
+
* Tracks whether this VisualElement's React component is currently present
|
|
4610
|
+
* within the defined React tree.
|
|
4611
|
+
*/
|
|
4612
|
+
this.isPresent = true;
|
|
4613
|
+
/**
|
|
4614
|
+
* A map of every subscription that binds the provided or generated
|
|
4615
|
+
* motion values onChange listeners to this visual element.
|
|
4616
|
+
*/
|
|
4617
|
+
this.valueSubscriptions = new Map();
|
|
4618
|
+
/**
|
|
4619
|
+
* A reference to the previously-provided motion values as returned
|
|
4620
|
+
* from scrapeMotionValuesFromProps. We use the keys in here to determine
|
|
4621
|
+
* if any motion values need to be removed after props are updated.
|
|
4622
|
+
*/
|
|
4623
|
+
this.prevMotionValues = {};
|
|
4624
|
+
/**
|
|
4625
|
+
* An object containing a SubscriptionManager for each active event.
|
|
4626
|
+
*/
|
|
4627
|
+
this.events = {};
|
|
4628
|
+
/**
|
|
4629
|
+
* An object containing an unsubscribe function for each prop event subscription.
|
|
4630
|
+
* For example, every "Update" event can have multiple subscribers via
|
|
4631
|
+
* VisualElement.on(), but only one of those can be defined via the onUpdate prop.
|
|
4632
|
+
*/
|
|
4633
|
+
this.propEventSubscriptions = {};
|
|
4634
|
+
this.notifyUpdate = () => this.notify("Update", this.latestValues);
|
|
4635
|
+
this.render = () => {
|
|
4636
|
+
if (!this.current)
|
|
4637
|
+
return;
|
|
4638
|
+
this.triggerBuild();
|
|
4639
|
+
this.renderInstance(this.current, this.renderState, this.props.style, this.projection);
|
|
4640
|
+
};
|
|
4641
|
+
this.scheduleRender = () => sync__default["default"].render(this.render, false, true);
|
|
4642
|
+
const { latestValues, renderState } = visualState;
|
|
4643
|
+
this.latestValues = latestValues;
|
|
4644
|
+
this.baseTarget = { ...latestValues };
|
|
4645
|
+
this.initialValues = props.initial ? { ...latestValues } : {};
|
|
4646
|
+
this.renderState = renderState;
|
|
4647
|
+
this.parent = parent;
|
|
4648
|
+
this.props = props;
|
|
4649
|
+
this.depth = parent ? parent.depth + 1 : 0;
|
|
4650
|
+
this.reducedMotionConfig = reducedMotionConfig;
|
|
4651
|
+
this.options = options;
|
|
4652
|
+
this.isControllingVariants = isControllingVariants(props);
|
|
4653
|
+
this.isVariantNode = isVariantNode(props);
|
|
4654
|
+
if (this.isVariantNode) {
|
|
4655
|
+
this.variantChildren = new Set();
|
|
4656
|
+
}
|
|
4657
|
+
this.manuallyAnimateOnMount = Boolean(parent && parent.current);
|
|
4658
|
+
/**
|
|
4659
|
+
* Any motion values that are provided to the element when created
|
|
4660
|
+
* aren't yet bound to the element, as this would technically be impure.
|
|
4661
|
+
* However, we iterate through the motion values and set them to the
|
|
4662
|
+
* initial values for this component.
|
|
4663
|
+
*
|
|
4664
|
+
* TODO: This is impure and we should look at changing this to run on mount.
|
|
4665
|
+
* Doing so will break some tests but this isn't neccessarily a breaking change,
|
|
4666
|
+
* more a reflection of the test.
|
|
4667
|
+
*/
|
|
4668
|
+
const { willChange, ...initialMotionValues } = this.scrapeMotionValuesFromProps(props);
|
|
4669
|
+
for (const key in initialMotionValues) {
|
|
4670
|
+
const value = initialMotionValues[key];
|
|
4671
|
+
if (latestValues[key] !== undefined && isMotionValue(value)) {
|
|
4672
|
+
value.set(latestValues[key], false);
|
|
4673
|
+
if (isWillChangeMotionValue(willChange)) {
|
|
4674
|
+
willChange.add(key);
|
|
4675
|
+
}
|
|
4676
|
+
}
|
|
4677
|
+
}
|
|
4678
|
+
/**
|
|
4679
|
+
* Update external values with initial values
|
|
4680
|
+
*/
|
|
4681
|
+
if (props.values) {
|
|
4682
|
+
for (const key in props.values) {
|
|
4683
|
+
const value = props.values[key];
|
|
4684
|
+
if (latestValues[key] !== undefined && isMotionValue(value)) {
|
|
4685
|
+
value.set(latestValues[key]);
|
|
5036
4686
|
}
|
|
5037
|
-
changedValueTypeKeys.push(key);
|
|
5038
|
-
transitionEnd[key] =
|
|
5039
|
-
transitionEnd[key] !== undefined
|
|
5040
|
-
? transitionEnd[key]
|
|
5041
|
-
: target[key];
|
|
5042
|
-
setAndResetVelocity(value, to);
|
|
5043
4687
|
}
|
|
5044
4688
|
}
|
|
5045
|
-
}
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
4689
|
+
}
|
|
4690
|
+
/**
|
|
4691
|
+
* This method takes React props and returns found MotionValues. For example, HTML
|
|
4692
|
+
* MotionValues will be found within the style prop, whereas for Three.js within attribute arrays.
|
|
4693
|
+
*
|
|
4694
|
+
* This isn't an abstract method as it needs calling in the constructor, but it is
|
|
4695
|
+
* intended to be one.
|
|
4696
|
+
*/
|
|
4697
|
+
scrapeMotionValuesFromProps(_props) {
|
|
4698
|
+
return {};
|
|
4699
|
+
}
|
|
4700
|
+
mount(instance) {
|
|
4701
|
+
var _a;
|
|
4702
|
+
this.current = instance;
|
|
4703
|
+
if (this.projection) {
|
|
4704
|
+
this.projection.mount(instance);
|
|
4705
|
+
}
|
|
4706
|
+
if (this.parent && this.isVariantNode && !this.isControllingVariants) {
|
|
4707
|
+
this.removeFromVariantTree = (_a = this.parent) === null || _a === void 0 ? void 0 : _a.addVariantChild(this);
|
|
4708
|
+
}
|
|
4709
|
+
this.values.forEach((value, key) => this.bindToMotionValue(key, value));
|
|
4710
|
+
if (!hasReducedMotionListener.current) {
|
|
4711
|
+
initPrefersReducedMotion();
|
|
4712
|
+
}
|
|
4713
|
+
this.shouldReduceMotion =
|
|
4714
|
+
this.reducedMotionConfig === "never"
|
|
4715
|
+
? false
|
|
4716
|
+
: this.reducedMotionConfig === "always"
|
|
4717
|
+
? true
|
|
4718
|
+
: prefersReducedMotion.current;
|
|
4719
|
+
if (this.parent)
|
|
4720
|
+
this.parent.children.add(this);
|
|
4721
|
+
this.setProps(this.props);
|
|
4722
|
+
}
|
|
4723
|
+
unmount() {
|
|
4724
|
+
var _a, _b, _c;
|
|
4725
|
+
(_a = this.projection) === null || _a === void 0 ? void 0 : _a.unmount();
|
|
4726
|
+
sync.cancelSync.update(this.notifyUpdate);
|
|
4727
|
+
sync.cancelSync.render(this.render);
|
|
4728
|
+
this.valueSubscriptions.forEach((remove) => remove());
|
|
4729
|
+
(_b = this.removeFromVariantTree) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
4730
|
+
(_c = this.parent) === null || _c === void 0 ? void 0 : _c.children.delete(this);
|
|
4731
|
+
for (const key in this.events) {
|
|
4732
|
+
this.events[key].clear();
|
|
4733
|
+
}
|
|
4734
|
+
this.current = null;
|
|
4735
|
+
}
|
|
4736
|
+
bindToMotionValue(key, value) {
|
|
4737
|
+
const removeOnChange = value.onChange((latestValue) => {
|
|
4738
|
+
this.latestValues[key] = latestValue;
|
|
4739
|
+
this.props.onUpdate &&
|
|
4740
|
+
sync__default["default"].update(this.notifyUpdate, false, true);
|
|
4741
|
+
});
|
|
4742
|
+
const removeOnRenderRequest = value.onRenderRequest(this.scheduleRender);
|
|
4743
|
+
this.valueSubscriptions.set(key, () => {
|
|
4744
|
+
removeOnChange();
|
|
4745
|
+
removeOnRenderRequest();
|
|
4746
|
+
});
|
|
4747
|
+
}
|
|
4748
|
+
sortNodePosition(other) {
|
|
4749
|
+
/**
|
|
4750
|
+
* If these nodes aren't even of the same type we can't compare their depth.
|
|
4751
|
+
*/
|
|
4752
|
+
if (!this.current ||
|
|
4753
|
+
!this.sortInstanceNodePosition ||
|
|
4754
|
+
this.type !== other.type)
|
|
4755
|
+
return 0;
|
|
4756
|
+
return this.sortInstanceNodePosition(this.current, other.current);
|
|
4757
|
+
}
|
|
4758
|
+
loadFeatures(renderedProps, isStrict, preloadedFeatures, projectionId, ProjectionNodeConstructor, initialLayoutGroupConfig) {
|
|
4759
|
+
const features = [];
|
|
4760
|
+
/**
|
|
4761
|
+
* If we're in development mode, check to make sure we're not rendering a motion component
|
|
4762
|
+
* as a child of LazyMotion, as this will break the file-size benefits of using it.
|
|
4763
|
+
*/
|
|
4764
|
+
if (env !== "production" && preloadedFeatures && isStrict) {
|
|
4765
|
+
heyListen.invariant(false, "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.");
|
|
4766
|
+
}
|
|
4767
|
+
for (let i = 0; i < numFeatures; i++) {
|
|
4768
|
+
const name = featureNames[i];
|
|
4769
|
+
const { isEnabled, Component } = featureDefinitions[name];
|
|
4770
|
+
/**
|
|
4771
|
+
* It might be possible in the future to use this moment to
|
|
4772
|
+
* dynamically request functionality. In initial tests this
|
|
4773
|
+
* was producing a lot of duplication amongst bundles.
|
|
4774
|
+
*/
|
|
4775
|
+
if (isEnabled(renderedProps) && Component) {
|
|
4776
|
+
features.push(React.createElement(Component, {
|
|
4777
|
+
key: name,
|
|
4778
|
+
...renderedProps,
|
|
4779
|
+
visualElement: this,
|
|
4780
|
+
}));
|
|
4781
|
+
}
|
|
4782
|
+
}
|
|
4783
|
+
if (!this.projection && ProjectionNodeConstructor) {
|
|
4784
|
+
this.projection = new ProjectionNodeConstructor(projectionId, this.latestValues, this.parent && this.parent.projection);
|
|
4785
|
+
const { layoutId, layout, drag, dragConstraints, layoutScroll } = renderedProps;
|
|
4786
|
+
this.projection.setOptions({
|
|
4787
|
+
layoutId,
|
|
4788
|
+
layout,
|
|
4789
|
+
alwaysMeasureLayout: Boolean(drag) ||
|
|
4790
|
+
(dragConstraints && isRefObject(dragConstraints)),
|
|
4791
|
+
visualElement: this,
|
|
4792
|
+
scheduleRender: () => this.scheduleRender(),
|
|
4793
|
+
/**
|
|
4794
|
+
* TODO: Update options in an effect. This could be tricky as it'll be too late
|
|
4795
|
+
* to update by the time layout animations run.
|
|
4796
|
+
* We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
|
|
4797
|
+
* ensuring it gets called if there's no potential layout animations.
|
|
4798
|
+
*
|
|
4799
|
+
*/
|
|
4800
|
+
animationType: typeof layout === "string" ? layout : "both",
|
|
4801
|
+
initialPromotionConfig: initialLayoutGroupConfig,
|
|
4802
|
+
layoutScroll,
|
|
5055
4803
|
});
|
|
5056
4804
|
}
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
4805
|
+
return features;
|
|
4806
|
+
}
|
|
4807
|
+
triggerBuild() {
|
|
4808
|
+
this.build(this.renderState, this.latestValues, this.options, this.props);
|
|
4809
|
+
}
|
|
4810
|
+
/**
|
|
4811
|
+
* Measure the current viewport box with or without transforms.
|
|
4812
|
+
* Only measures axis-aligned boxes, rotate and skew must be manually
|
|
4813
|
+
* removed with a re-render to work.
|
|
4814
|
+
*/
|
|
4815
|
+
measureViewportBox() {
|
|
4816
|
+
return this.current
|
|
4817
|
+
? this.measureInstanceViewportBox(this.current, this.props)
|
|
4818
|
+
: createBox();
|
|
4819
|
+
}
|
|
4820
|
+
getStaticValue(key) {
|
|
4821
|
+
return this.latestValues[key];
|
|
4822
|
+
}
|
|
4823
|
+
setStaticValue(key, value) {
|
|
4824
|
+
this.latestValues[key] = value;
|
|
4825
|
+
}
|
|
4826
|
+
/**
|
|
4827
|
+
* Make a target animatable by Popmotion. For instance, if we're
|
|
4828
|
+
* trying to animate width from 100px to 100vw we need to measure 100vw
|
|
4829
|
+
* in pixels to determine what we really need to animate to. This is also
|
|
4830
|
+
* pluggable to support Framer's custom value types like Color,
|
|
4831
|
+
* and CSS variables.
|
|
4832
|
+
*/
|
|
4833
|
+
makeTargetAnimatable(target, canMutate = true) {
|
|
4834
|
+
return this.makeTargetAnimatableFromInstance(target, this.props, canMutate);
|
|
4835
|
+
}
|
|
4836
|
+
/**
|
|
4837
|
+
* Update the provided props. Ensure any newly-added motion values are
|
|
4838
|
+
* added to our map, old ones removed, and listeners updated.
|
|
4839
|
+
*/
|
|
4840
|
+
setProps(props) {
|
|
4841
|
+
if (props.transformTemplate || this.props.transformTemplate) {
|
|
4842
|
+
this.scheduleRender();
|
|
5062
4843
|
}
|
|
5063
|
-
|
|
4844
|
+
this.props = props;
|
|
4845
|
+
/**
|
|
4846
|
+
* Update prop event handlers ie onAnimationStart, onAnimationComplete
|
|
4847
|
+
*/
|
|
4848
|
+
for (let i = 0; i < propEventHandlers.length; i++) {
|
|
4849
|
+
const key = propEventHandlers[i];
|
|
4850
|
+
if (this.propEventSubscriptions[key]) {
|
|
4851
|
+
this.propEventSubscriptions[key]();
|
|
4852
|
+
delete this.propEventSubscriptions[key];
|
|
4853
|
+
}
|
|
4854
|
+
const listener = props["on" + key];
|
|
4855
|
+
if (listener) {
|
|
4856
|
+
this.propEventSubscriptions[key] = this.on(key, listener);
|
|
4857
|
+
}
|
|
4858
|
+
}
|
|
4859
|
+
this.prevMotionValues = updateMotionValuesFromProps(this, this.scrapeMotionValuesFromProps(props), this.prevMotionValues);
|
|
5064
4860
|
}
|
|
5065
|
-
|
|
5066
|
-
return
|
|
4861
|
+
getProps() {
|
|
4862
|
+
return this.props;
|
|
5067
4863
|
}
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
}
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
readValueFromInstance(domElement, key) {
|
|
5099
|
-
if (transformProps.has(key)) {
|
|
5100
|
-
const defaultType = getDefaultValueType(key);
|
|
5101
|
-
return defaultType ? defaultType.default || 0 : 0;
|
|
4864
|
+
/**
|
|
4865
|
+
* Returns the variant definition with a given name.
|
|
4866
|
+
*/
|
|
4867
|
+
getVariant(name) {
|
|
4868
|
+
var _a;
|
|
4869
|
+
return (_a = this.props.variants) === null || _a === void 0 ? void 0 : _a[name];
|
|
4870
|
+
}
|
|
4871
|
+
/**
|
|
4872
|
+
* Returns the defined default transition on this component.
|
|
4873
|
+
*/
|
|
4874
|
+
getDefaultTransition() {
|
|
4875
|
+
return this.props.transition;
|
|
4876
|
+
}
|
|
4877
|
+
getTransformPagePoint() {
|
|
4878
|
+
return this.props.transformPagePoint;
|
|
4879
|
+
}
|
|
4880
|
+
getClosestVariantNode() {
|
|
4881
|
+
var _a;
|
|
4882
|
+
return this.isVariantNode ? this : (_a = this.parent) === null || _a === void 0 ? void 0 : _a.getClosestVariantNode();
|
|
4883
|
+
}
|
|
4884
|
+
getVariantContext(startAtParent = false) {
|
|
4885
|
+
var _a, _b;
|
|
4886
|
+
if (startAtParent)
|
|
4887
|
+
return (_a = this.parent) === null || _a === void 0 ? void 0 : _a.getVariantContext();
|
|
4888
|
+
if (!this.isControllingVariants) {
|
|
4889
|
+
const context = ((_b = this.parent) === null || _b === void 0 ? void 0 : _b.getVariantContext()) || {};
|
|
4890
|
+
if (this.props.initial !== undefined) {
|
|
4891
|
+
context.initial = this.props.initial;
|
|
4892
|
+
}
|
|
4893
|
+
return context;
|
|
5102
4894
|
}
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
const
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
4895
|
+
const context = {};
|
|
4896
|
+
for (let i = 0; i < numVariantProps; i++) {
|
|
4897
|
+
const name = variantProps[i];
|
|
4898
|
+
const prop = this.props[name];
|
|
4899
|
+
if (isVariantLabel(prop) || prop === false) {
|
|
4900
|
+
context[name] = prop;
|
|
4901
|
+
}
|
|
5109
4902
|
}
|
|
5110
|
-
|
|
5111
|
-
|
|
4903
|
+
return context;
|
|
4904
|
+
}
|
|
4905
|
+
/**
|
|
4906
|
+
* Add a child visual element to our set of children.
|
|
4907
|
+
*/
|
|
4908
|
+
addVariantChild(child) {
|
|
4909
|
+
var _a;
|
|
4910
|
+
const closestVariantNode = this.getClosestVariantNode();
|
|
4911
|
+
if (closestVariantNode) {
|
|
4912
|
+
(_a = closestVariantNode.variantChildren) === null || _a === void 0 ? void 0 : _a.add(child);
|
|
4913
|
+
return () => closestVariantNode.variantChildren.delete(child);
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
/**
|
|
4917
|
+
* Add a motion value and bind it to this visual element.
|
|
4918
|
+
*/
|
|
4919
|
+
addValue(key, value) {
|
|
4920
|
+
// Remove existing value if it exists
|
|
4921
|
+
if (this.hasValue(key))
|
|
4922
|
+
this.removeValue(key);
|
|
4923
|
+
this.values.set(key, value);
|
|
4924
|
+
this.latestValues[key] = value.get();
|
|
4925
|
+
this.bindToMotionValue(key, value);
|
|
4926
|
+
}
|
|
4927
|
+
/**
|
|
4928
|
+
* Remove a motion value and unbind any active subscriptions.
|
|
4929
|
+
*/
|
|
4930
|
+
removeValue(key) {
|
|
4931
|
+
var _a;
|
|
4932
|
+
this.values.delete(key);
|
|
4933
|
+
(_a = this.valueSubscriptions.get(key)) === null || _a === void 0 ? void 0 : _a();
|
|
4934
|
+
this.valueSubscriptions.delete(key);
|
|
4935
|
+
delete this.latestValues[key];
|
|
4936
|
+
this.removeValueFromRenderState(key, this.renderState);
|
|
4937
|
+
}
|
|
4938
|
+
/**
|
|
4939
|
+
* Check whether we have a motion value for this key
|
|
4940
|
+
*/
|
|
4941
|
+
hasValue(key) {
|
|
4942
|
+
return this.values.has(key);
|
|
4943
|
+
}
|
|
4944
|
+
/**
|
|
4945
|
+
* Get a motion value for this key. If called with a default
|
|
4946
|
+
* value, we'll create one if none exists.
|
|
4947
|
+
*/
|
|
4948
|
+
getValue(key, defaultValue) {
|
|
4949
|
+
if (this.props.values && this.props.values[key]) {
|
|
4950
|
+
return this.props.values[key];
|
|
4951
|
+
}
|
|
4952
|
+
let value = this.values.get(key);
|
|
4953
|
+
if (value === undefined && defaultValue !== undefined) {
|
|
4954
|
+
value = motionValue(defaultValue);
|
|
4955
|
+
this.addValue(key, value);
|
|
4956
|
+
}
|
|
4957
|
+
return value;
|
|
4958
|
+
}
|
|
4959
|
+
/**
|
|
4960
|
+
* If we're trying to animate to a previously unencountered value,
|
|
4961
|
+
* we need to check for it in our state and as a last resort read it
|
|
4962
|
+
* directly from the instance (which might have performance implications).
|
|
4963
|
+
*/
|
|
4964
|
+
readValue(key) {
|
|
4965
|
+
return this.latestValues[key] !== undefined || !this.current
|
|
4966
|
+
? this.latestValues[key]
|
|
4967
|
+
: this.readValueFromInstance(this.current, key, this.options);
|
|
4968
|
+
}
|
|
4969
|
+
/**
|
|
4970
|
+
* Set the base target to later animate back to. This is currently
|
|
4971
|
+
* only hydrated on creation and when we first read a value.
|
|
4972
|
+
*/
|
|
4973
|
+
setBaseTarget(key, value) {
|
|
4974
|
+
this.baseTarget[key] = value;
|
|
4975
|
+
}
|
|
4976
|
+
/**
|
|
4977
|
+
* Find the base target for a value thats been removed from all animation
|
|
4978
|
+
* props.
|
|
4979
|
+
*/
|
|
4980
|
+
getBaseTarget(key) {
|
|
4981
|
+
var _a;
|
|
4982
|
+
const { initial } = this.props;
|
|
4983
|
+
const valueFromInitial = typeof initial === "string" || typeof initial === "object"
|
|
4984
|
+
? (_a = resolveVariantFromProps(this.props, initial)) === null || _a === void 0 ? void 0 : _a[key]
|
|
4985
|
+
: undefined;
|
|
4986
|
+
/**
|
|
4987
|
+
* If this value still exists in the current initial variant, read that.
|
|
4988
|
+
*/
|
|
4989
|
+
if (initial && valueFromInitial !== undefined) {
|
|
4990
|
+
return valueFromInitial;
|
|
4991
|
+
}
|
|
4992
|
+
/**
|
|
4993
|
+
* Alternatively, if this VisualElement config has defined a getBaseTarget
|
|
4994
|
+
* so we can read the value from an alternative source, try that.
|
|
4995
|
+
*/
|
|
4996
|
+
const target = this.getBaseTargetFromProps(this.props, key);
|
|
4997
|
+
if (target !== undefined && !isMotionValue(target))
|
|
4998
|
+
return target;
|
|
4999
|
+
/**
|
|
5000
|
+
* If the value was initially defined on initial, but it doesn't any more,
|
|
5001
|
+
* return undefined. Otherwise return the value as initially read from the DOM.
|
|
5002
|
+
*/
|
|
5003
|
+
return this.initialValues[key] !== undefined &&
|
|
5004
|
+
valueFromInitial === undefined
|
|
5005
|
+
? undefined
|
|
5006
|
+
: this.baseTarget[key];
|
|
5007
|
+
}
|
|
5008
|
+
on(eventName, callback) {
|
|
5009
|
+
if (!this.events[eventName]) {
|
|
5010
|
+
this.events[eventName] = new SubscriptionManager();
|
|
5011
|
+
}
|
|
5012
|
+
return this.events[eventName].add(callback);
|
|
5013
|
+
}
|
|
5014
|
+
notify(eventName, ...args) {
|
|
5015
|
+
var _a;
|
|
5016
|
+
(_a = this.events[eventName]) === null || _a === void 0 ? void 0 : _a.notify(...args);
|
|
5017
|
+
}
|
|
5018
|
+
}
|
|
5019
|
+
const variantProps = ["initial", ...variantPriorityOrder];
|
|
5020
|
+
const numVariantProps = variantProps.length;
|
|
5021
|
+
|
|
5022
|
+
class DOMVisualElement extends VisualElement {
|
|
5023
|
+
sortInstanceNodePosition(a, b) {
|
|
5112
5024
|
/**
|
|
5113
5025
|
* compareDocumentPosition returns a bitmask, by using the bitwise &
|
|
5114
5026
|
* we're returning true if 2 in that bitmask is set to true. 2 is set
|
|
5115
5027
|
* to true if b preceeds a.
|
|
5116
5028
|
*/
|
|
5117
5029
|
return a.compareDocumentPosition(b) & 2 ? 1 : -1;
|
|
5118
|
-
}
|
|
5119
|
-
|
|
5030
|
+
}
|
|
5031
|
+
getBaseTargetFromProps(props, key) {
|
|
5120
5032
|
var _a;
|
|
5121
5033
|
return (_a = props.style) === null || _a === void 0 ? void 0 : _a[key];
|
|
5122
|
-
}
|
|
5123
|
-
measureViewportBox(element, { transformPagePoint }) {
|
|
5124
|
-
return measureViewportBox(element, transformPagePoint);
|
|
5125
|
-
},
|
|
5126
|
-
/**
|
|
5127
|
-
* Reset the transform on the current Element. This is called as part
|
|
5128
|
-
* of a batched process across the entire layout tree. To remove this write
|
|
5129
|
-
* cycle it'd be interesting to see if it's possible to "undo" all the current
|
|
5130
|
-
* layout transforms up the tree in the same way this.getBoundingBoxWithoutTransforms
|
|
5131
|
-
* works
|
|
5132
|
-
*/
|
|
5133
|
-
resetTransform(element, domElement, props) {
|
|
5134
|
-
const { transformTemplate } = props;
|
|
5135
|
-
domElement.style.transform = transformTemplate
|
|
5136
|
-
? transformTemplate({}, "")
|
|
5137
|
-
: "none";
|
|
5138
|
-
// Ensure that whatever happens next, we restore our transform on the next frame
|
|
5139
|
-
element.scheduleRender();
|
|
5140
|
-
},
|
|
5141
|
-
restoreTransform(instance, mutableState) {
|
|
5142
|
-
instance.style.transform = mutableState.style.transform;
|
|
5143
|
-
},
|
|
5034
|
+
}
|
|
5144
5035
|
removeValueFromRenderState(key, { vars, style }) {
|
|
5145
5036
|
delete vars[key];
|
|
5146
5037
|
delete style[key];
|
|
5147
|
-
}
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
* can be animated by Motion.
|
|
5151
|
-
*/
|
|
5152
|
-
makeTargetAnimatable(element, { transition, transitionEnd, ...target }, { transformValues }, isMounted = true) {
|
|
5153
|
-
let origin = getOrigin(target, transition || {}, element);
|
|
5038
|
+
}
|
|
5039
|
+
makeTargetAnimatableFromInstance({ transition, transitionEnd, ...target }, { transformValues }, isMounted) {
|
|
5040
|
+
let origin = getOrigin(target, transition || {}, this);
|
|
5154
5041
|
/**
|
|
5155
5042
|
* If Framer has provided a function to convert `Color` etc value types, convert them
|
|
5156
5043
|
*/
|
|
@@ -5163,8 +5050,8 @@ const htmlConfig = {
|
|
|
5163
5050
|
origin = transformValues(origin);
|
|
5164
5051
|
}
|
|
5165
5052
|
if (isMounted) {
|
|
5166
|
-
checkTargetForNewValues(
|
|
5167
|
-
const parsed = parseDomVariant(
|
|
5053
|
+
checkTargetForNewValues(this, target, origin);
|
|
5054
|
+
const parsed = parseDomVariant(this, target, origin, transitionEnd);
|
|
5168
5055
|
transitionEnd = parsed.transitionEnd;
|
|
5169
5056
|
target = parsed.target;
|
|
5170
5057
|
}
|
|
@@ -5173,44 +5060,70 @@ const htmlConfig = {
|
|
|
5173
5060
|
transitionEnd,
|
|
5174
5061
|
...target,
|
|
5175
5062
|
};
|
|
5176
|
-
}
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5063
|
+
}
|
|
5064
|
+
}
|
|
5065
|
+
|
|
5066
|
+
function getComputedStyle$1(element) {
|
|
5067
|
+
return window.getComputedStyle(element);
|
|
5068
|
+
}
|
|
5069
|
+
class HTMLVisualElement extends DOMVisualElement {
|
|
5070
|
+
readValueFromInstance(instance, key) {
|
|
5071
|
+
if (transformProps.has(key)) {
|
|
5072
|
+
const defaultType = getDefaultValueType(key);
|
|
5073
|
+
return defaultType ? defaultType.default || 0 : 0;
|
|
5074
|
+
}
|
|
5075
|
+
else {
|
|
5076
|
+
const computedStyle = getComputedStyle$1(instance);
|
|
5077
|
+
const value = (isCSSVariable$1(key)
|
|
5078
|
+
? computedStyle.getPropertyValue(key)
|
|
5079
|
+
: computedStyle[key]) || 0;
|
|
5080
|
+
return typeof value === "string" ? value.trim() : value;
|
|
5183
5081
|
}
|
|
5082
|
+
}
|
|
5083
|
+
measureInstanceViewportBox(instance, { transformPagePoint }) {
|
|
5084
|
+
return measureViewportBox(instance, transformPagePoint);
|
|
5085
|
+
}
|
|
5086
|
+
build(renderState, latestValues, options, props) {
|
|
5184
5087
|
buildHTMLStyles(renderState, latestValues, options, props.transformTemplate);
|
|
5185
|
-
}
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5088
|
+
}
|
|
5089
|
+
scrapeMotionValuesFromProps(props) {
|
|
5090
|
+
return scrapeMotionValuesFromProps$1(props);
|
|
5091
|
+
}
|
|
5092
|
+
renderInstance(instance, renderState, styleProp, projection) {
|
|
5093
|
+
renderHTML(instance, renderState, styleProp, projection);
|
|
5094
|
+
}
|
|
5095
|
+
}
|
|
5189
5096
|
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
getBaseTarget(props, key) {
|
|
5097
|
+
class SVGVisualElement extends DOMVisualElement {
|
|
5098
|
+
getBaseTargetFromProps(props, key) {
|
|
5193
5099
|
return props[key];
|
|
5194
|
-
}
|
|
5195
|
-
readValueFromInstance(
|
|
5100
|
+
}
|
|
5101
|
+
readValueFromInstance(instance, key) {
|
|
5196
5102
|
var _a;
|
|
5197
5103
|
if (transformProps.has(key)) {
|
|
5198
5104
|
return ((_a = getDefaultValueType(key)) === null || _a === void 0 ? void 0 : _a.default) || 0;
|
|
5199
5105
|
}
|
|
5200
5106
|
key = !camelCaseAttributes.has(key) ? camelToDash(key) : key;
|
|
5201
|
-
return
|
|
5202
|
-
}
|
|
5203
|
-
|
|
5204
|
-
|
|
5107
|
+
return instance.getAttribute(key);
|
|
5108
|
+
}
|
|
5109
|
+
measureInstanceViewportBox() {
|
|
5110
|
+
return createBox();
|
|
5111
|
+
}
|
|
5112
|
+
scrapeMotionValuesFromProps(props) {
|
|
5113
|
+
return scrapeMotionValuesFromProps(props);
|
|
5114
|
+
}
|
|
5115
|
+
build(renderState, latestValues, options, props) {
|
|
5205
5116
|
buildSVGAttrs(renderState, latestValues, options, props.transformTemplate);
|
|
5206
|
-
}
|
|
5207
|
-
|
|
5208
|
-
|
|
5117
|
+
}
|
|
5118
|
+
renderInstance(instance, renderState, styleProp, projection) {
|
|
5119
|
+
renderSVG(instance, renderState, styleProp, projection);
|
|
5120
|
+
}
|
|
5121
|
+
}
|
|
5209
5122
|
|
|
5210
5123
|
const createDomVisualElement = (Component, options) => {
|
|
5211
5124
|
return isSVGComponent(Component)
|
|
5212
|
-
?
|
|
5213
|
-
:
|
|
5125
|
+
? new SVGVisualElement(options, { enableHardwareAcceleration: false })
|
|
5126
|
+
: new HTMLVisualElement(options, { enableHardwareAcceleration: true });
|
|
5214
5127
|
};
|
|
5215
5128
|
|
|
5216
5129
|
function pixelsToPercent(pixels, axis) {
|
|
@@ -5808,7 +5721,7 @@ const transformAxes = ["", "X", "Y", "Z"];
|
|
|
5808
5721
|
const animationTarget = 1000;
|
|
5809
5722
|
function createProjectionNode({ attachResizeListener, defaultParent, measureScroll, checkIsScrollRoot, resetTransform, }) {
|
|
5810
5723
|
return class ProjectionNode {
|
|
5811
|
-
constructor(
|
|
5724
|
+
constructor(elementId, latestValues = {}, parent = defaultParent === null || defaultParent === void 0 ? void 0 : defaultParent()) {
|
|
5812
5725
|
/**
|
|
5813
5726
|
* A Set containing all this component's children. This is used to iterate
|
|
5814
5727
|
* through the children.
|
|
@@ -5861,7 +5774,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
5861
5774
|
/**
|
|
5862
5775
|
* An object representing the calculated contextual/accumulated/tree scale.
|
|
5863
5776
|
* This will be used to scale calculcated projection transforms, as these are
|
|
5864
|
-
* calculated in screen-space but need to be scaled for elements to
|
|
5777
|
+
* calculated in screen-space but need to be scaled for elements to layoutly
|
|
5865
5778
|
* make it to their calculated destinations.
|
|
5866
5779
|
*
|
|
5867
5780
|
* TODO: Lazy-init
|
|
@@ -5891,13 +5804,13 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
5891
5804
|
*/
|
|
5892
5805
|
// TODO Only running on root node
|
|
5893
5806
|
this.sharedNodes = new Map();
|
|
5894
|
-
this.
|
|
5807
|
+
this.elementId = elementId;
|
|
5895
5808
|
this.latestValues = latestValues;
|
|
5896
5809
|
this.root = parent ? parent.root || parent : this;
|
|
5897
5810
|
this.path = parent ? [...parent.path, parent] : [];
|
|
5898
5811
|
this.parent = parent;
|
|
5899
5812
|
this.depth = parent ? parent.depth + 1 : 0;
|
|
5900
|
-
|
|
5813
|
+
elementId && this.root.registerPotentialNode(elementId, this);
|
|
5901
5814
|
for (let i = 0; i < this.path.length; i++) {
|
|
5902
5815
|
this.path[i].shouldResetTransform = true;
|
|
5903
5816
|
}
|
|
@@ -5931,12 +5844,12 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
5931
5844
|
instance instanceof SVGElement && instance.tagName !== "svg";
|
|
5932
5845
|
this.instance = instance;
|
|
5933
5846
|
const { layoutId, layout, visualElement } = this.options;
|
|
5934
|
-
if (visualElement && !visualElement.
|
|
5847
|
+
if (visualElement && !visualElement.current) {
|
|
5935
5848
|
visualElement.mount(instance);
|
|
5936
5849
|
}
|
|
5937
5850
|
this.root.nodes.add(this);
|
|
5938
5851
|
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.children.add(this);
|
|
5939
|
-
this.
|
|
5852
|
+
this.elementId && this.root.potentialNodes.delete(this.elementId);
|
|
5940
5853
|
if (isLayoutDirty && (layout || layoutId)) {
|
|
5941
5854
|
this.isLayoutDirty = true;
|
|
5942
5855
|
}
|
|
@@ -6152,14 +6065,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6152
6065
|
updateSnapshot() {
|
|
6153
6066
|
if (this.snapshot || !this.instance)
|
|
6154
6067
|
return;
|
|
6155
|
-
|
|
6156
|
-
const layout = this.removeTransform(this.removeElementScroll(measured));
|
|
6157
|
-
roundBox(layout);
|
|
6158
|
-
this.snapshot = {
|
|
6159
|
-
measured,
|
|
6160
|
-
layout,
|
|
6161
|
-
latestValues: {},
|
|
6162
|
-
};
|
|
6068
|
+
this.snapshot = this.measure();
|
|
6163
6069
|
}
|
|
6164
6070
|
updateLayout() {
|
|
6165
6071
|
var _a;
|
|
@@ -6184,18 +6090,13 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6184
6090
|
node.updateScroll();
|
|
6185
6091
|
}
|
|
6186
6092
|
}
|
|
6187
|
-
const measured = this.measure();
|
|
6188
|
-
roundBox(measured);
|
|
6189
6093
|
const prevLayout = this.layout;
|
|
6190
|
-
this.layout =
|
|
6191
|
-
measured,
|
|
6192
|
-
actual: this.removeElementScroll(measured),
|
|
6193
|
-
};
|
|
6094
|
+
this.layout = this.measure(false);
|
|
6194
6095
|
this.layoutCorrected = createBox();
|
|
6195
6096
|
this.isLayoutDirty = false;
|
|
6196
6097
|
this.projectionDelta = undefined;
|
|
6197
|
-
this.notifyListeners("measure", this.layout.
|
|
6198
|
-
(_a = this.options.visualElement) === null || _a === void 0 ? void 0 : _a.
|
|
6098
|
+
this.notifyListeners("measure", this.layout.layoutBox);
|
|
6099
|
+
(_a = this.options.visualElement) === null || _a === void 0 ? void 0 : _a.notify("LayoutMeasure", this.layout.layoutBox, prevLayout === null || prevLayout === void 0 ? void 0 : prevLayout.layoutBox);
|
|
6199
6100
|
}
|
|
6200
6101
|
updateScroll() {
|
|
6201
6102
|
if (this.options.layoutScroll && this.instance) {
|
|
@@ -6221,7 +6122,25 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6221
6122
|
this.scheduleRender();
|
|
6222
6123
|
}
|
|
6223
6124
|
}
|
|
6224
|
-
measure() {
|
|
6125
|
+
measure(removeTransform = true) {
|
|
6126
|
+
const pageBox = this.measurePageBox();
|
|
6127
|
+
let layoutBox = this.removeElementScroll(pageBox);
|
|
6128
|
+
/**
|
|
6129
|
+
* Measurements taken during the pre-render stage
|
|
6130
|
+
* still have transforms applied so we remove them
|
|
6131
|
+
* via calculation.
|
|
6132
|
+
*/
|
|
6133
|
+
if (removeTransform) {
|
|
6134
|
+
layoutBox = this.removeTransform(layoutBox);
|
|
6135
|
+
}
|
|
6136
|
+
roundBox(layoutBox);
|
|
6137
|
+
return {
|
|
6138
|
+
measuredBox: pageBox,
|
|
6139
|
+
layoutBox,
|
|
6140
|
+
latestValues: {},
|
|
6141
|
+
};
|
|
6142
|
+
}
|
|
6143
|
+
measurePageBox() {
|
|
6225
6144
|
const { visualElement } = this.options;
|
|
6226
6145
|
if (!visualElement)
|
|
6227
6146
|
return createBox();
|
|
@@ -6302,9 +6221,9 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6302
6221
|
continue;
|
|
6303
6222
|
hasScale(node.latestValues) && node.updateSnapshot();
|
|
6304
6223
|
const sourceBox = createBox();
|
|
6305
|
-
const nodeBox = node.
|
|
6224
|
+
const nodeBox = node.measurePageBox();
|
|
6306
6225
|
copyBoxInto(sourceBox, nodeBox);
|
|
6307
|
-
removeBoxTransforms(boxWithoutTransform, node.latestValues, (_a = node.snapshot) === null || _a === void 0 ? void 0 : _a.
|
|
6226
|
+
removeBoxTransforms(boxWithoutTransform, node.latestValues, (_a = node.snapshot) === null || _a === void 0 ? void 0 : _a.layoutBox, sourceBox);
|
|
6308
6227
|
}
|
|
6309
6228
|
if (hasTransform(this.latestValues)) {
|
|
6310
6229
|
removeBoxTransforms(boxWithoutTransform, this.latestValues);
|
|
@@ -6353,13 +6272,17 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6353
6272
|
// TODO If this is unsuccessful this currently happens every frame
|
|
6354
6273
|
if (!this.targetDelta && !this.relativeTarget) {
|
|
6355
6274
|
// TODO: This is a semi-repetition of further down this function, make DRY
|
|
6356
|
-
|
|
6357
|
-
if (
|
|
6275
|
+
const relativeParent = this.getClosestProjectingParent();
|
|
6276
|
+
if (relativeParent && relativeParent.layout) {
|
|
6277
|
+
this.relativeParent = relativeParent;
|
|
6358
6278
|
this.relativeTarget = createBox();
|
|
6359
6279
|
this.relativeTargetOrigin = createBox();
|
|
6360
|
-
calcRelativePosition(this.relativeTargetOrigin, this.layout.
|
|
6280
|
+
calcRelativePosition(this.relativeTargetOrigin, this.layout.layoutBox, relativeParent.layout.layoutBox);
|
|
6361
6281
|
copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
|
|
6362
6282
|
}
|
|
6283
|
+
else {
|
|
6284
|
+
this.relativeParent = this.relativeTarget = undefined;
|
|
6285
|
+
}
|
|
6363
6286
|
}
|
|
6364
6287
|
/**
|
|
6365
6288
|
* If we have no relative target or no target delta our target isn't valid
|
|
@@ -6388,10 +6311,10 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6388
6311
|
else if (this.targetDelta) {
|
|
6389
6312
|
if (Boolean(this.resumingFrom)) {
|
|
6390
6313
|
// TODO: This is creating a new object every frame
|
|
6391
|
-
this.target = this.applyTransform(this.layout.
|
|
6314
|
+
this.target = this.applyTransform(this.layout.layoutBox);
|
|
6392
6315
|
}
|
|
6393
6316
|
else {
|
|
6394
|
-
copyBoxInto(this.target, this.layout.
|
|
6317
|
+
copyBoxInto(this.target, this.layout.layoutBox);
|
|
6395
6318
|
}
|
|
6396
6319
|
applyBoxDelta(this.target, this.targetDelta);
|
|
6397
6320
|
}
|
|
@@ -6399,24 +6322,28 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6399
6322
|
/**
|
|
6400
6323
|
* If no target, use own layout as target
|
|
6401
6324
|
*/
|
|
6402
|
-
copyBoxInto(this.target, this.layout.
|
|
6325
|
+
copyBoxInto(this.target, this.layout.layoutBox);
|
|
6403
6326
|
}
|
|
6404
6327
|
/**
|
|
6405
6328
|
* If we've been told to attempt to resolve a relative target, do so.
|
|
6406
6329
|
*/
|
|
6407
6330
|
if (this.attemptToResolveRelativeTarget) {
|
|
6408
6331
|
this.attemptToResolveRelativeTarget = false;
|
|
6409
|
-
|
|
6410
|
-
if (
|
|
6411
|
-
Boolean(
|
|
6332
|
+
const relativeParent = this.getClosestProjectingParent();
|
|
6333
|
+
if (relativeParent &&
|
|
6334
|
+
Boolean(relativeParent.resumingFrom) ===
|
|
6412
6335
|
Boolean(this.resumingFrom) &&
|
|
6413
|
-
!
|
|
6414
|
-
|
|
6336
|
+
!relativeParent.options.layoutScroll &&
|
|
6337
|
+
relativeParent.target) {
|
|
6338
|
+
this.relativeParent = relativeParent;
|
|
6415
6339
|
this.relativeTarget = createBox();
|
|
6416
6340
|
this.relativeTargetOrigin = createBox();
|
|
6417
|
-
calcRelativePosition(this.relativeTargetOrigin, this.target,
|
|
6341
|
+
calcRelativePosition(this.relativeTargetOrigin, this.target, relativeParent.target);
|
|
6418
6342
|
copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
|
|
6419
6343
|
}
|
|
6344
|
+
else {
|
|
6345
|
+
this.relativeParent = this.relativeTarget = undefined;
|
|
6346
|
+
}
|
|
6420
6347
|
}
|
|
6421
6348
|
}
|
|
6422
6349
|
getClosestProjectingParent() {
|
|
@@ -6452,7 +6379,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6452
6379
|
* Reset the corrected box with the latest values from box, as we're then going
|
|
6453
6380
|
* to perform mutative operations on it.
|
|
6454
6381
|
*/
|
|
6455
|
-
copyBoxInto(this.layoutCorrected, this.layout.
|
|
6382
|
+
copyBoxInto(this.layoutCorrected, this.layout.layoutBox);
|
|
6456
6383
|
/**
|
|
6457
6384
|
* Apply all the parent deltas to this box to produce the corrected box. This
|
|
6458
6385
|
* is the layout box, as it will appear on screen as a result of the transforms of its parents.
|
|
@@ -6529,7 +6456,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6529
6456
|
this.relativeTargetOrigin &&
|
|
6530
6457
|
this.layout &&
|
|
6531
6458
|
((_a = this.relativeParent) === null || _a === void 0 ? void 0 : _a.layout)) {
|
|
6532
|
-
calcRelativePosition(relativeLayout, this.layout.
|
|
6459
|
+
calcRelativePosition(relativeLayout, this.layout.layoutBox, this.relativeParent.layout.layoutBox);
|
|
6533
6460
|
mixBox(this.relativeTarget, this.relativeTargetOrigin, relativeLayout, progress);
|
|
6534
6461
|
}
|
|
6535
6462
|
if (isSharedLayoutAnimation) {
|
|
@@ -6613,12 +6540,12 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6613
6540
|
if (this !== lead &&
|
|
6614
6541
|
this.layout &&
|
|
6615
6542
|
layout &&
|
|
6616
|
-
shouldAnimatePositionOnly(this.options.animationType, this.layout.
|
|
6543
|
+
shouldAnimatePositionOnly(this.options.animationType, this.layout.layoutBox, layout.layoutBox)) {
|
|
6617
6544
|
target = this.target || createBox();
|
|
6618
|
-
const xLength = calcLength(this.layout.
|
|
6545
|
+
const xLength = calcLength(this.layout.layoutBox.x);
|
|
6619
6546
|
target.x.min = lead.target.x.min;
|
|
6620
6547
|
target.x.max = target.x.min + xLength;
|
|
6621
|
-
const yLength = calcLength(this.layout.
|
|
6548
|
+
const yLength = calcLength(this.layout.layoutBox.y);
|
|
6622
6549
|
target.y.min = lead.target.y.min;
|
|
6623
6550
|
target.y.max = target.y.min + yLength;
|
|
6624
6551
|
}
|
|
@@ -6632,7 +6559,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6632
6559
|
/**
|
|
6633
6560
|
* Update the delta between the corrected box and the final target box, after
|
|
6634
6561
|
* user-set transforms are applied to it. This will be used by the renderer to
|
|
6635
|
-
* create a transform style that will reproject the element from its
|
|
6562
|
+
* create a transform style that will reproject the element from its layout layout
|
|
6636
6563
|
* into the desired bounding box.
|
|
6637
6564
|
*/
|
|
6638
6565
|
calcBoxDelta(this.projectionDeltaWithTransform, this.layoutCorrected, targetWithTransforms, latestValues);
|
|
@@ -6715,7 +6642,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6715
6642
|
return;
|
|
6716
6643
|
// Force a render of this element to apply the transform with all rotations
|
|
6717
6644
|
// set to 0.
|
|
6718
|
-
visualElement === null || visualElement === void 0 ? void 0 : visualElement.
|
|
6645
|
+
visualElement === null || visualElement === void 0 ? void 0 : visualElement.render();
|
|
6719
6646
|
// Put back all the values we reset
|
|
6720
6647
|
for (const key in resetValues) {
|
|
6721
6648
|
visualElement.setStaticValue(key, resetValues[key]);
|
|
@@ -6788,7 +6715,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6788
6715
|
}
|
|
6789
6716
|
else {
|
|
6790
6717
|
/**
|
|
6791
|
-
* Or we're not animating at all, set the lead component to its
|
|
6718
|
+
* Or we're not animating at all, set the lead component to its layout
|
|
6792
6719
|
* opacity and other components to hidden.
|
|
6793
6720
|
*/
|
|
6794
6721
|
styles.opacity =
|
|
@@ -6852,53 +6779,53 @@ function notifyLayoutUpdate(node) {
|
|
|
6852
6779
|
node.layout &&
|
|
6853
6780
|
snapshot &&
|
|
6854
6781
|
node.hasListeners("didUpdate")) {
|
|
6855
|
-
const {
|
|
6782
|
+
const { layoutBox: layout, measuredBox: measuredLayout } = node.layout;
|
|
6856
6783
|
const { animationType } = node.options;
|
|
6857
6784
|
// TODO Maybe we want to also resize the layout snapshot so we don't trigger
|
|
6858
6785
|
// animations for instance if layout="size" and an element has only changed position
|
|
6859
6786
|
if (animationType === "size") {
|
|
6860
6787
|
eachAxis((axis) => {
|
|
6861
6788
|
const axisSnapshot = snapshot.isShared
|
|
6862
|
-
? snapshot.
|
|
6863
|
-
: snapshot.
|
|
6789
|
+
? snapshot.measuredBox[axis]
|
|
6790
|
+
: snapshot.layoutBox[axis];
|
|
6864
6791
|
const length = calcLength(axisSnapshot);
|
|
6865
6792
|
axisSnapshot.min = layout[axis].min;
|
|
6866
6793
|
axisSnapshot.max = axisSnapshot.min + length;
|
|
6867
6794
|
});
|
|
6868
6795
|
}
|
|
6869
|
-
else if (shouldAnimatePositionOnly(animationType, snapshot.
|
|
6796
|
+
else if (shouldAnimatePositionOnly(animationType, snapshot.layoutBox, layout)) {
|
|
6870
6797
|
eachAxis((axis) => {
|
|
6871
6798
|
const axisSnapshot = snapshot.isShared
|
|
6872
|
-
? snapshot.
|
|
6873
|
-
: snapshot.
|
|
6799
|
+
? snapshot.measuredBox[axis]
|
|
6800
|
+
: snapshot.layoutBox[axis];
|
|
6874
6801
|
const length = calcLength(layout[axis]);
|
|
6875
6802
|
axisSnapshot.max = axisSnapshot.min + length;
|
|
6876
6803
|
});
|
|
6877
6804
|
}
|
|
6878
6805
|
const layoutDelta = createDelta();
|
|
6879
|
-
calcBoxDelta(layoutDelta, layout, snapshot.
|
|
6806
|
+
calcBoxDelta(layoutDelta, layout, snapshot.layoutBox);
|
|
6880
6807
|
const visualDelta = createDelta();
|
|
6881
6808
|
if (snapshot.isShared) {
|
|
6882
|
-
calcBoxDelta(visualDelta, node.applyTransform(measuredLayout, true), snapshot.
|
|
6809
|
+
calcBoxDelta(visualDelta, node.applyTransform(measuredLayout, true), snapshot.measuredBox);
|
|
6883
6810
|
}
|
|
6884
6811
|
else {
|
|
6885
|
-
calcBoxDelta(visualDelta, layout, snapshot.
|
|
6812
|
+
calcBoxDelta(visualDelta, layout, snapshot.layoutBox);
|
|
6886
6813
|
}
|
|
6887
6814
|
const hasLayoutChanged = !isDeltaZero(layoutDelta);
|
|
6888
6815
|
let hasRelativeTargetChanged = false;
|
|
6889
6816
|
if (!node.resumeFrom) {
|
|
6890
|
-
|
|
6817
|
+
const relativeParent = node.getClosestProjectingParent();
|
|
6891
6818
|
/**
|
|
6892
6819
|
* If the relativeParent is itself resuming from a different element then
|
|
6893
6820
|
* the relative snapshot is not relavent
|
|
6894
6821
|
*/
|
|
6895
|
-
if (
|
|
6896
|
-
const { snapshot: parentSnapshot, layout: parentLayout } =
|
|
6822
|
+
if (relativeParent && !relativeParent.resumeFrom) {
|
|
6823
|
+
const { snapshot: parentSnapshot, layout: parentLayout } = relativeParent;
|
|
6897
6824
|
if (parentSnapshot && parentLayout) {
|
|
6898
6825
|
const relativeSnapshot = createBox();
|
|
6899
|
-
calcRelativePosition(relativeSnapshot, snapshot.
|
|
6826
|
+
calcRelativePosition(relativeSnapshot, snapshot.layoutBox, parentSnapshot.layoutBox);
|
|
6900
6827
|
const relativeLayout = createBox();
|
|
6901
|
-
calcRelativePosition(relativeLayout, layout, parentLayout.
|
|
6828
|
+
calcRelativePosition(relativeLayout, layout, parentLayout.layoutBox);
|
|
6902
6829
|
if (!boxEquals(relativeSnapshot, relativeLayout)) {
|
|
6903
6830
|
hasRelativeTargetChanged = true;
|
|
6904
6831
|
}
|
|
@@ -6933,7 +6860,7 @@ function clearMeasurements(node) {
|
|
|
6933
6860
|
function resetTransformStyle(node) {
|
|
6934
6861
|
const { visualElement } = node.options;
|
|
6935
6862
|
if (visualElement === null || visualElement === void 0 ? void 0 : visualElement.getProps().onBeforeLayoutMeasure) {
|
|
6936
|
-
visualElement.
|
|
6863
|
+
visualElement.notify("BeforeLayoutMeasure");
|
|
6937
6864
|
}
|
|
6938
6865
|
node.resetTransform();
|
|
6939
6866
|
}
|
|
@@ -8333,23 +8260,33 @@ function useResetProjection() {
|
|
|
8333
8260
|
}
|
|
8334
8261
|
|
|
8335
8262
|
const createObject = () => ({});
|
|
8336
|
-
|
|
8337
|
-
build() { }
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
|
|
8342
|
-
|
|
8343
|
-
|
|
8263
|
+
class StateVisualElement extends VisualElement {
|
|
8264
|
+
build() { }
|
|
8265
|
+
measureInstanceViewportBox() {
|
|
8266
|
+
return createBox();
|
|
8267
|
+
}
|
|
8268
|
+
resetTransform() { }
|
|
8269
|
+
restoreTransform() { }
|
|
8270
|
+
removeValueFromRenderState() { }
|
|
8271
|
+
renderInstance() { }
|
|
8272
|
+
scrapeMotionValuesFromProps() {
|
|
8273
|
+
return createObject();
|
|
8274
|
+
}
|
|
8275
|
+
getBaseTargetFromProps() {
|
|
8276
|
+
return undefined;
|
|
8277
|
+
}
|
|
8344
8278
|
readValueFromInstance(_state, key, options) {
|
|
8345
8279
|
return options.initialState[key] || 0;
|
|
8346
|
-
}
|
|
8347
|
-
|
|
8348
|
-
|
|
8349
|
-
|
|
8280
|
+
}
|
|
8281
|
+
sortInstanceNodePosition() {
|
|
8282
|
+
return 0;
|
|
8283
|
+
}
|
|
8284
|
+
makeTargetAnimatableFromInstance({ transition, transitionEnd, ...target }) {
|
|
8285
|
+
const origin = getOrigin(target, transition || {}, this);
|
|
8286
|
+
checkTargetForNewValues(this, target, origin);
|
|
8350
8287
|
return { transition, transitionEnd, ...target };
|
|
8351
|
-
}
|
|
8352
|
-
}
|
|
8288
|
+
}
|
|
8289
|
+
}
|
|
8353
8290
|
const useVisualState = makeUseVisualState({
|
|
8354
8291
|
scrapeMotionValuesFromProps: createObject,
|
|
8355
8292
|
createRenderState: createObject,
|
|
@@ -8361,10 +8298,12 @@ const useVisualState = makeUseVisualState({
|
|
|
8361
8298
|
function useAnimatedState(initialState) {
|
|
8362
8299
|
const [animationState, setAnimationState] = React.useState(initialState);
|
|
8363
8300
|
const visualState = useVisualState({}, false);
|
|
8364
|
-
const element = useConstant(() =>
|
|
8301
|
+
const element = useConstant(() => {
|
|
8302
|
+
return new StateVisualElement({ props: {}, visualState }, { initialState });
|
|
8303
|
+
});
|
|
8365
8304
|
React.useEffect(() => {
|
|
8366
8305
|
element.mount({});
|
|
8367
|
-
return element.unmount;
|
|
8306
|
+
return () => element.unmount();
|
|
8368
8307
|
}, [element]);
|
|
8369
8308
|
React.useEffect(() => {
|
|
8370
8309
|
element.setProps({
|
|
@@ -8439,6 +8378,7 @@ exports.MotionValue = MotionValue;
|
|
|
8439
8378
|
exports.PresenceContext = PresenceContext;
|
|
8440
8379
|
exports.Reorder = Reorder;
|
|
8441
8380
|
exports.SwitchLayoutGroupContext = SwitchLayoutGroupContext;
|
|
8381
|
+
exports.VisualElement = VisualElement;
|
|
8442
8382
|
exports.addPointerEvent = addPointerEvent;
|
|
8443
8383
|
exports.addScaleCorrector = addScaleCorrector;
|
|
8444
8384
|
exports.animate = animate;
|
|
@@ -8497,5 +8437,4 @@ exports.useVelocity = useVelocity;
|
|
|
8497
8437
|
exports.useViewportScroll = useViewportScroll;
|
|
8498
8438
|
exports.useVisualElementContext = useVisualElementContext;
|
|
8499
8439
|
exports.useWillChange = useWillChange;
|
|
8500
|
-
exports.visualElement = visualElement;
|
|
8501
8440
|
exports.wrapHandler = wrapHandler;
|