framer-motion 12.35.2 → 12.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -15
- package/dist/cjs/client.js +1 -1
- package/dist/cjs/dom.js +38 -6
- package/dist/cjs/dom.js.map +1 -1
- package/dist/cjs/{feature-bundle-DqHxNjy5.js → feature-bundle-CBfLWgGA.js} +47 -6
- package/dist/cjs/feature-bundle-CBfLWgGA.js.map +1 -0
- package/dist/cjs/index.js +41 -8
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/m.js +7 -1
- package/dist/cjs/m.js.map +1 -1
- package/dist/dom-mini.js +1 -1
- package/dist/dom.js +1 -1
- package/dist/es/components/AnimatePresence/PopChild.mjs +1 -0
- package/dist/es/components/AnimatePresence/PopChild.mjs.map +1 -1
- package/dist/es/components/AnimatePresence/index.mjs +1 -1
- package/dist/es/components/AnimatePresence/index.mjs.map +1 -1
- package/dist/es/gestures/drag/VisualElementDragControls.mjs +2 -1
- package/dist/es/gestures/drag/VisualElementDragControls.mjs.map +1 -1
- package/dist/es/gestures/pan/PanSession.mjs.map +1 -1
- package/dist/es/motion/features/animation/exit.mjs +31 -1
- package/dist/es/motion/features/animation/exit.mjs.map +1 -1
- package/dist/es/motion/features/viewport/index.mjs +7 -3
- package/dist/es/motion/features/viewport/index.mjs.map +1 -1
- package/dist/es/render/dom/scroll/utils/offset-to-range.mjs +38 -6
- package/dist/es/render/dom/scroll/utils/offset-to-range.mjs.map +1 -1
- package/dist/es/render/dom/utils/filter-props.mjs +8 -1
- package/dist/es/render/dom/utils/filter-props.mjs.map +1 -1
- package/dist/es/value/use-spring.mjs.map +1 -1
- package/dist/framer-motion.dev.js +272 -88
- package/dist/framer-motion.js +1 -1
- package/dist/mini.js +1 -1
- package/dist/size-rollup-animate.js +1 -1
- package/dist/size-rollup-animate.js.map +1 -1
- package/dist/size-rollup-dom-animation-assets.js +1 -1
- 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-m.js.map +1 -1
- package/dist/size-rollup-motion.js +1 -1
- package/dist/size-rollup-motion.js.map +1 -1
- package/dist/size-rollup-scroll.js +1 -1
- package/dist/size-rollup-scroll.js.map +1 -1
- package/dist/size-rollup-waapi-animate.js +1 -1
- package/dist/size-rollup-waapi-animate.js.map +1 -1
- package/dist/types/index.d.ts +5 -4
- package/package.json +4 -4
- package/dist/cjs/feature-bundle-DqHxNjy5.js.map +0 -1
|
@@ -324,7 +324,11 @@
|
|
|
324
324
|
const backIn = /*@__PURE__*/ reverseEasing(backOut);
|
|
325
325
|
const backInOut = /*@__PURE__*/ mirrorEasing(backIn);
|
|
326
326
|
|
|
327
|
-
const anticipate = (p) =>
|
|
327
|
+
const anticipate = (p) => p >= 1
|
|
328
|
+
? 1
|
|
329
|
+
: (p *= 2) < 1
|
|
330
|
+
? 0.5 * backIn(p)
|
|
331
|
+
: 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
|
|
328
332
|
|
|
329
333
|
const circIn = (p) => 1 - Math.sin(Math.acos(p));
|
|
330
334
|
const circOut = reverseEasing(circIn);
|
|
@@ -443,8 +447,7 @@
|
|
|
443
447
|
const queue = addToCurrentFrame ? thisFrame : nextFrame;
|
|
444
448
|
if (keepAlive)
|
|
445
449
|
toKeepAlive.add(callback);
|
|
446
|
-
|
|
447
|
-
queue.add(callback);
|
|
450
|
+
queue.add(callback);
|
|
448
451
|
return callback;
|
|
449
452
|
},
|
|
450
453
|
/**
|
|
@@ -469,7 +472,10 @@
|
|
|
469
472
|
return;
|
|
470
473
|
}
|
|
471
474
|
isProcessing = true;
|
|
472
|
-
|
|
475
|
+
// Swap this frame and the next to avoid GC
|
|
476
|
+
const prevFrame = thisFrame;
|
|
477
|
+
thisFrame = nextFrame;
|
|
478
|
+
nextFrame = prevFrame;
|
|
473
479
|
// Execute this frame
|
|
474
480
|
thisFrame.forEach(triggerCallback);
|
|
475
481
|
/**
|
|
@@ -508,11 +514,12 @@
|
|
|
508
514
|
}, {});
|
|
509
515
|
const { setup, read, resolveKeyframes, preUpdate, update, preRender, render, postRender, } = steps;
|
|
510
516
|
const processBatch = () => {
|
|
511
|
-
const
|
|
517
|
+
const useManualTiming = MotionGlobalConfig.useManualTiming;
|
|
518
|
+
const timestamp = useManualTiming
|
|
512
519
|
? state.timestamp
|
|
513
520
|
: performance.now();
|
|
514
521
|
runNextFrame = false;
|
|
515
|
-
if (!
|
|
522
|
+
if (!useManualTiming) {
|
|
516
523
|
state.delta = useDefaultElapsed
|
|
517
524
|
? 1000 / 60
|
|
518
525
|
: Math.max(Math.min(timestamp - state.timestamp, maxElapsed$1), 1);
|
|
@@ -1704,9 +1711,9 @@
|
|
|
1704
1711
|
};
|
|
1705
1712
|
}
|
|
1706
1713
|
|
|
1707
|
-
const isNotNull
|
|
1708
|
-
function getFinalKeyframe
|
|
1709
|
-
const resolvedKeyframes = keyframes.filter(isNotNull
|
|
1714
|
+
const isNotNull = (value) => value !== null;
|
|
1715
|
+
function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyframe, speed = 1) {
|
|
1716
|
+
const resolvedKeyframes = keyframes.filter(isNotNull);
|
|
1710
1717
|
const useFirstKeyframe = speed < 0 || (repeat && repeatType !== "loop" && repeat % 2 === 1);
|
|
1711
1718
|
const index = useFirstKeyframe ? 0 : resolvedKeyframes.length - 1;
|
|
1712
1719
|
return !index || finalKeyframe === undefined
|
|
@@ -1771,6 +1778,14 @@
|
|
|
1771
1778
|
* Playback speed as a factor. 0 would be stopped, -1 reverse and 2 double speed.
|
|
1772
1779
|
*/
|
|
1773
1780
|
this.playbackSpeed = 1;
|
|
1781
|
+
/**
|
|
1782
|
+
* Reusable state object for the delay phase to avoid
|
|
1783
|
+
* allocating a new object every frame.
|
|
1784
|
+
*/
|
|
1785
|
+
this.delayState = {
|
|
1786
|
+
done: false,
|
|
1787
|
+
value: undefined,
|
|
1788
|
+
};
|
|
1774
1789
|
/**
|
|
1775
1790
|
* This method is bound to the instance to fix a pattern where
|
|
1776
1791
|
* animation.stop is returned as a reference from a useEffect.
|
|
@@ -1932,9 +1947,14 @@
|
|
|
1932
1947
|
* This prevents delay: x, duration: 0 animations from finishing
|
|
1933
1948
|
* instantly.
|
|
1934
1949
|
*/
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1950
|
+
let state;
|
|
1951
|
+
if (isInDelayPhase) {
|
|
1952
|
+
this.delayState.value = keyframes[0];
|
|
1953
|
+
state = this.delayState;
|
|
1954
|
+
}
|
|
1955
|
+
else {
|
|
1956
|
+
state = frameGenerator.next(elapsed);
|
|
1957
|
+
}
|
|
1938
1958
|
if (mixKeyframes && !isInDelayPhase) {
|
|
1939
1959
|
state.value = mixKeyframes(state.value);
|
|
1940
1960
|
}
|
|
@@ -1949,7 +1969,7 @@
|
|
|
1949
1969
|
(this.state === "finished" || (this.state === "running" && done));
|
|
1950
1970
|
// TODO: The exception for inertia could be cleaner here
|
|
1951
1971
|
if (isAnimationFinished && type !== inertia) {
|
|
1952
|
-
state.value = getFinalKeyframe
|
|
1972
|
+
state.value = getFinalKeyframe(keyframes, this.options, finalKeyframe, this.speed);
|
|
1953
1973
|
}
|
|
1954
1974
|
if (onUpdate) {
|
|
1955
1975
|
onUpdate(state.value);
|
|
@@ -2244,8 +2264,18 @@
|
|
|
2244
2264
|
}
|
|
2245
2265
|
const positionalValues = {
|
|
2246
2266
|
// Dimensions
|
|
2247
|
-
width: ({ x }, { paddingLeft = "0", paddingRight = "0" }) =>
|
|
2248
|
-
|
|
2267
|
+
width: ({ x }, { paddingLeft = "0", paddingRight = "0", boxSizing }) => {
|
|
2268
|
+
const width = x.max - x.min;
|
|
2269
|
+
return boxSizing === "border-box"
|
|
2270
|
+
? width
|
|
2271
|
+
: width - parseFloat(paddingLeft) - parseFloat(paddingRight);
|
|
2272
|
+
},
|
|
2273
|
+
height: ({ y }, { paddingTop = "0", paddingBottom = "0", boxSizing }) => {
|
|
2274
|
+
const height = y.max - y.min;
|
|
2275
|
+
return boxSizing === "border-box"
|
|
2276
|
+
? height
|
|
2277
|
+
: height - parseFloat(paddingTop) - parseFloat(paddingBottom);
|
|
2278
|
+
},
|
|
2249
2279
|
top: (_bbox, { top }) => parseFloat(top),
|
|
2250
2280
|
left: (_bbox, { left }) => parseFloat(left),
|
|
2251
2281
|
bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
|
|
@@ -2547,7 +2577,7 @@
|
|
|
2547
2577
|
this.animation.onfinish = () => {
|
|
2548
2578
|
this.finishedTime = this.time;
|
|
2549
2579
|
if (!pseudoElement) {
|
|
2550
|
-
const keyframe = getFinalKeyframe
|
|
2580
|
+
const keyframe = getFinalKeyframe(keyframes, this.options, finalKeyframe, this.speed);
|
|
2551
2581
|
if (this.updateMotionValue) {
|
|
2552
2582
|
this.updateMotionValue(keyframe);
|
|
2553
2583
|
}
|
|
@@ -2853,17 +2883,42 @@
|
|
|
2853
2883
|
/**
|
|
2854
2884
|
* A list of values that can be hardware-accelerated.
|
|
2855
2885
|
*/
|
|
2856
|
-
const acceleratedValues
|
|
2886
|
+
const acceleratedValues = new Set([
|
|
2857
2887
|
"opacity",
|
|
2858
2888
|
"clipPath",
|
|
2859
2889
|
"filter",
|
|
2860
2890
|
"transform",
|
|
2861
|
-
// TODO:
|
|
2891
|
+
// TODO: Can be accelerated but currently disabled until https://issues.chromium.org/issues/41491098 is resolved
|
|
2892
|
+
// or until we implement support for linear() easing.
|
|
2862
2893
|
// "background-color"
|
|
2863
2894
|
]);
|
|
2895
|
+
|
|
2896
|
+
const browserColorFunctions = /^(?:oklch|oklab|lab|lch|color|color-mix|light-dark)\(/;
|
|
2897
|
+
function hasBrowserOnlyColors(keyframes) {
|
|
2898
|
+
for (let i = 0; i < keyframes.length; i++) {
|
|
2899
|
+
if (typeof keyframes[i] === "string" &&
|
|
2900
|
+
browserColorFunctions.test(keyframes[i])) {
|
|
2901
|
+
return true;
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
return false;
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
const colorProperties = new Set([
|
|
2908
|
+
"color",
|
|
2909
|
+
"backgroundColor",
|
|
2910
|
+
"outlineColor",
|
|
2911
|
+
"fill",
|
|
2912
|
+
"stroke",
|
|
2913
|
+
"borderColor",
|
|
2914
|
+
"borderTopColor",
|
|
2915
|
+
"borderRightColor",
|
|
2916
|
+
"borderBottomColor",
|
|
2917
|
+
"borderLeftColor",
|
|
2918
|
+
]);
|
|
2864
2919
|
const supportsWaapi = /*@__PURE__*/ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
|
|
2865
2920
|
function supportsBrowserAnimation(options) {
|
|
2866
|
-
const { motionValue, name, repeatDelay, repeatType, damping, type } = options;
|
|
2921
|
+
const { motionValue, name, repeatDelay, repeatType, damping, type, keyframes, } = options;
|
|
2867
2922
|
const subject = motionValue?.owner?.current;
|
|
2868
2923
|
/**
|
|
2869
2924
|
* We use this check instead of isHTMLElement() because we explicitly
|
|
@@ -2877,7 +2932,13 @@
|
|
|
2877
2932
|
const { onUpdate, transformTemplate } = motionValue.owner.getProps();
|
|
2878
2933
|
return (supportsWaapi() &&
|
|
2879
2934
|
name &&
|
|
2880
|
-
|
|
2935
|
+
/**
|
|
2936
|
+
* Force WAAPI for color properties with browser-only color formats
|
|
2937
|
+
* (oklch, oklab, lab, lch, etc.) that the JS animation path can't parse.
|
|
2938
|
+
*/
|
|
2939
|
+
(acceleratedValues.has(name) ||
|
|
2940
|
+
(colorProperties.has(name) &&
|
|
2941
|
+
hasBrowserOnlyColors(keyframes))) &&
|
|
2881
2942
|
(name !== "transform" || !transformTemplate) &&
|
|
2882
2943
|
/**
|
|
2883
2944
|
* If we're outputting values to onUpdate then we can't use WAAPI as there's
|
|
@@ -2937,9 +2998,11 @@
|
|
|
2937
2998
|
* If we can't animate this value with the resolved keyframes
|
|
2938
2999
|
* then we should complete it immediately.
|
|
2939
3000
|
*/
|
|
3001
|
+
let canAnimateValue = true;
|
|
2940
3002
|
if (!canAnimate(keyframes, name, type, velocity)) {
|
|
3003
|
+
canAnimateValue = false;
|
|
2941
3004
|
if (MotionGlobalConfig.instantAnimations || !delay) {
|
|
2942
|
-
onUpdate?.(getFinalKeyframe
|
|
3005
|
+
onUpdate?.(getFinalKeyframe(keyframes, options, finalKeyframe));
|
|
2943
3006
|
}
|
|
2944
3007
|
keyframes[0] = keyframes[keyframes.length - 1];
|
|
2945
3008
|
makeAnimationInstant(options);
|
|
@@ -2974,15 +3037,29 @@
|
|
|
2974
3037
|
* Animate via WAAPI if possible. If this is a handoff animation, the optimised animation will be running via
|
|
2975
3038
|
* WAAPI. Therefore, this animation must be JS to ensure it runs "under" the
|
|
2976
3039
|
* optimised animation.
|
|
3040
|
+
*
|
|
3041
|
+
* Also skip WAAPI when keyframes aren't animatable, as the resolved
|
|
3042
|
+
* values may not be valid CSS and would trigger browser warnings.
|
|
2977
3043
|
*/
|
|
2978
|
-
const useWaapi =
|
|
3044
|
+
const useWaapi = canAnimateValue &&
|
|
3045
|
+
!isHandoff &&
|
|
3046
|
+
supportsBrowserAnimation(resolvedOptions);
|
|
2979
3047
|
const element = resolvedOptions.motionValue?.owner?.current;
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
3048
|
+
let animation;
|
|
3049
|
+
if (useWaapi) {
|
|
3050
|
+
try {
|
|
3051
|
+
animation = new NativeAnimationExtended({
|
|
3052
|
+
...resolvedOptions,
|
|
3053
|
+
element,
|
|
3054
|
+
});
|
|
3055
|
+
}
|
|
3056
|
+
catch {
|
|
3057
|
+
animation = new JSAnimation(resolvedOptions);
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
else {
|
|
3061
|
+
animation = new JSAnimation(resolvedOptions);
|
|
3062
|
+
}
|
|
2986
3063
|
animation.finished.then(() => {
|
|
2987
3064
|
this.notifyFinished();
|
|
2988
3065
|
}).catch(noop$1);
|
|
@@ -3160,8 +3237,11 @@
|
|
|
3160
3237
|
const animationMaps = new WeakMap();
|
|
3161
3238
|
const animationMapKey = (name, pseudoElement = "") => `${name}:${pseudoElement}`;
|
|
3162
3239
|
function getAnimationMap(element) {
|
|
3163
|
-
|
|
3164
|
-
|
|
3240
|
+
let map = animationMaps.get(element);
|
|
3241
|
+
if (!map) {
|
|
3242
|
+
map = new Map();
|
|
3243
|
+
animationMaps.set(element, map);
|
|
3244
|
+
}
|
|
3165
3245
|
return map;
|
|
3166
3246
|
}
|
|
3167
3247
|
|
|
@@ -3253,17 +3333,6 @@
|
|
|
3253
3333
|
return ease;
|
|
3254
3334
|
};
|
|
3255
3335
|
|
|
3256
|
-
const isNotNull = (value) => value !== null;
|
|
3257
|
-
function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyframe) {
|
|
3258
|
-
const resolvedKeyframes = keyframes.filter(isNotNull);
|
|
3259
|
-
const index = repeat && repeatType !== "loop" && repeat % 2 === 1
|
|
3260
|
-
? 0
|
|
3261
|
-
: resolvedKeyframes.length - 1;
|
|
3262
|
-
return !index || finalKeyframe === undefined
|
|
3263
|
-
? resolvedKeyframes[index]
|
|
3264
|
-
: finalKeyframe;
|
|
3265
|
-
}
|
|
3266
|
-
|
|
3267
3336
|
/**
|
|
3268
3337
|
* If `transition` has `inherit: true`, shallow-merge it with
|
|
3269
3338
|
* `parentTransition` (child keys win) and strip the `inherit` key.
|
|
@@ -3287,13 +3356,29 @@
|
|
|
3287
3356
|
return valueTransition;
|
|
3288
3357
|
}
|
|
3289
3358
|
|
|
3359
|
+
const orchestrationKeys = new Set([
|
|
3360
|
+
"when",
|
|
3361
|
+
"delay",
|
|
3362
|
+
"delayChildren",
|
|
3363
|
+
"staggerChildren",
|
|
3364
|
+
"staggerDirection",
|
|
3365
|
+
"repeat",
|
|
3366
|
+
"repeatType",
|
|
3367
|
+
"repeatDelay",
|
|
3368
|
+
"from",
|
|
3369
|
+
"elapsed",
|
|
3370
|
+
]);
|
|
3290
3371
|
/**
|
|
3291
3372
|
* Decide whether a transition is defined on a given Transition.
|
|
3292
3373
|
* This filters out orchestration options and returns true
|
|
3293
3374
|
* if any options are left.
|
|
3294
3375
|
*/
|
|
3295
|
-
function isTransitionDefined(
|
|
3296
|
-
|
|
3376
|
+
function isTransitionDefined(transition) {
|
|
3377
|
+
for (const key in transition) {
|
|
3378
|
+
if (!orchestrationKeys.has(key))
|
|
3379
|
+
return true;
|
|
3380
|
+
}
|
|
3381
|
+
return false;
|
|
3297
3382
|
}
|
|
3298
3383
|
|
|
3299
3384
|
const animateMotionValue = (name, value, target, transition = {}, element, isHandoff) => (onComplete) => {
|
|
@@ -4425,19 +4510,6 @@
|
|
|
4425
4510
|
return true;
|
|
4426
4511
|
});
|
|
4427
4512
|
|
|
4428
|
-
/**
|
|
4429
|
-
* A list of values that can be hardware-accelerated.
|
|
4430
|
-
*/
|
|
4431
|
-
const acceleratedValues = new Set([
|
|
4432
|
-
"opacity",
|
|
4433
|
-
"clipPath",
|
|
4434
|
-
"filter",
|
|
4435
|
-
"transform",
|
|
4436
|
-
// TODO: Can be accelerated but currently disabled until https://issues.chromium.org/issues/41491098 is resolved
|
|
4437
|
-
// or until we implement support for linear() easing.
|
|
4438
|
-
// "background-color"
|
|
4439
|
-
]);
|
|
4440
|
-
|
|
4441
4513
|
function resolveElements(elementOrSelector, scope, selectorCache) {
|
|
4442
4514
|
if (elementOrSelector == null) {
|
|
4443
4515
|
return [];
|
|
@@ -4583,7 +4655,9 @@
|
|
|
4583
4655
|
* that works across iframes
|
|
4584
4656
|
*/
|
|
4585
4657
|
function isHTMLElement(element) {
|
|
4586
|
-
return isObject(element) &&
|
|
4658
|
+
return (isObject(element) &&
|
|
4659
|
+
"offsetHeight" in element &&
|
|
4660
|
+
!("ownerSVGElement" in element));
|
|
4587
4661
|
}
|
|
4588
4662
|
|
|
4589
4663
|
const translateAlias$1 = {
|
|
@@ -5321,6 +5395,7 @@
|
|
|
5321
5395
|
activeAnimation.stop();
|
|
5322
5396
|
activeAnimation = null;
|
|
5323
5397
|
}
|
|
5398
|
+
value.animation = undefined;
|
|
5324
5399
|
};
|
|
5325
5400
|
const startAnimation = () => {
|
|
5326
5401
|
const currentValue = asNumber$1(value.get());
|
|
@@ -5352,8 +5427,10 @@
|
|
|
5352
5427
|
// multiple calls within the same frame (e.g. rapid mouse events)
|
|
5353
5428
|
const scheduleAnimation = () => {
|
|
5354
5429
|
startAnimation();
|
|
5430
|
+
value.animation = activeAnimation ?? undefined;
|
|
5355
5431
|
value["events"].animationStart?.notify();
|
|
5356
5432
|
activeAnimation?.then(() => {
|
|
5433
|
+
value.animation = undefined;
|
|
5357
5434
|
value["events"].animationComplete?.notify();
|
|
5358
5435
|
});
|
|
5359
5436
|
};
|
|
@@ -5363,7 +5440,16 @@
|
|
|
5363
5440
|
frame.postRender(scheduleAnimation);
|
|
5364
5441
|
}, stopAnimation);
|
|
5365
5442
|
if (isMotionValue(source)) {
|
|
5366
|
-
|
|
5443
|
+
let skipNextAnimation = options.skipInitialAnimation === true;
|
|
5444
|
+
const removeSourceOnChange = source.on("change", (v) => {
|
|
5445
|
+
if (skipNextAnimation) {
|
|
5446
|
+
skipNextAnimation = false;
|
|
5447
|
+
value.jump(parseValue(v, unit), false);
|
|
5448
|
+
}
|
|
5449
|
+
else {
|
|
5450
|
+
value.set(parseValue(v, unit));
|
|
5451
|
+
}
|
|
5452
|
+
});
|
|
5367
5453
|
const removeValueOnDestroy = value.on("destroy", removeSourceOnChange);
|
|
5368
5454
|
return () => {
|
|
5369
5455
|
removeSourceOnChange();
|
|
@@ -6643,10 +6729,8 @@
|
|
|
6643
6729
|
node.options.layoutScroll &&
|
|
6644
6730
|
node.scroll &&
|
|
6645
6731
|
node !== node.root) {
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
y: -node.scroll.offset.y,
|
|
6649
|
-
});
|
|
6732
|
+
translateAxis(box.x, -node.scroll.offset.x);
|
|
6733
|
+
translateAxis(box.y, -node.scroll.offset.y);
|
|
6650
6734
|
}
|
|
6651
6735
|
if (delta) {
|
|
6652
6736
|
// Incoporate each ancestor's scale into a cumulative treeScale for this component
|
|
@@ -6673,8 +6757,8 @@
|
|
|
6673
6757
|
}
|
|
6674
6758
|
}
|
|
6675
6759
|
function translateAxis(axis, distance) {
|
|
6676
|
-
axis.min
|
|
6677
|
-
axis.max
|
|
6760
|
+
axis.min += distance;
|
|
6761
|
+
axis.max += distance;
|
|
6678
6762
|
}
|
|
6679
6763
|
/**
|
|
6680
6764
|
* Apply a transform to an axis from the latest resolved motion values.
|
|
@@ -7841,8 +7925,13 @@
|
|
|
7841
7925
|
return transform || "none";
|
|
7842
7926
|
}
|
|
7843
7927
|
|
|
7844
|
-
const
|
|
7845
|
-
|
|
7928
|
+
const borderLabels = [
|
|
7929
|
+
"borderTopLeftRadius",
|
|
7930
|
+
"borderTopRightRadius",
|
|
7931
|
+
"borderBottomLeftRadius",
|
|
7932
|
+
"borderBottomRightRadius",
|
|
7933
|
+
];
|
|
7934
|
+
const numBorders = borderLabels.length;
|
|
7846
7935
|
const asNumber = (value) => typeof value === "string" ? parseFloat(value) : value;
|
|
7847
7936
|
const isPx = (value) => typeof value === "number" || px.test(value);
|
|
7848
7937
|
function mixValues(target, follow, lead, progress, shouldCrossfadeOpacity, isOnlyMember) {
|
|
@@ -7857,7 +7946,7 @@
|
|
|
7857
7946
|
* Mix border radius
|
|
7858
7947
|
*/
|
|
7859
7948
|
for (let i = 0; i < numBorders; i++) {
|
|
7860
|
-
const borderLabel =
|
|
7949
|
+
const borderLabel = borderLabels[i];
|
|
7861
7950
|
let followRadius = getRadius(follow, borderLabel);
|
|
7862
7951
|
let leadRadius = getRadius(lead, borderLabel);
|
|
7863
7952
|
if (followRadius === undefined && leadRadius === undefined)
|
|
@@ -8502,6 +8591,11 @@
|
|
|
8502
8591
|
}
|
|
8503
8592
|
else {
|
|
8504
8593
|
this.isUpdating = false;
|
|
8594
|
+
/**
|
|
8595
|
+
* Ensure animation-blocked nodes (e.g. during drag)
|
|
8596
|
+
* get measured even when memoized (willUpdate skipped).
|
|
8597
|
+
*/
|
|
8598
|
+
this.nodes.forEach(ensureDraggedNodesSnapshotted);
|
|
8505
8599
|
/**
|
|
8506
8600
|
* Write
|
|
8507
8601
|
*/
|
|
@@ -8600,7 +8694,8 @@
|
|
|
8600
8694
|
const prevLayout = this.layout;
|
|
8601
8695
|
this.layout = this.measure(false);
|
|
8602
8696
|
this.layoutVersion++;
|
|
8603
|
-
this.layoutCorrected
|
|
8697
|
+
if (!this.layoutCorrected)
|
|
8698
|
+
this.layoutCorrected = createBox();
|
|
8604
8699
|
this.isLayoutDirty = false;
|
|
8605
8700
|
this.projectionDelta = undefined;
|
|
8606
8701
|
this.notifyListeners("measure", this.layout.layoutBox);
|
|
@@ -8711,8 +8806,8 @@
|
|
|
8711
8806
|
}
|
|
8712
8807
|
return boxWithoutScroll;
|
|
8713
8808
|
}
|
|
8714
|
-
applyTransform(box, transformOnly = false) {
|
|
8715
|
-
const withTransforms = createBox();
|
|
8809
|
+
applyTransform(box, transformOnly = false, output) {
|
|
8810
|
+
const withTransforms = output || createBox();
|
|
8716
8811
|
copyBoxInto(withTransforms, box);
|
|
8717
8812
|
for (let i = 0; i < this.path.length; i++) {
|
|
8718
8813
|
const node = this.path[i];
|
|
@@ -8720,10 +8815,8 @@
|
|
|
8720
8815
|
node.options.layoutScroll &&
|
|
8721
8816
|
node.scroll &&
|
|
8722
8817
|
node !== node.root) {
|
|
8723
|
-
|
|
8724
|
-
|
|
8725
|
-
y: -node.scroll.offset.y,
|
|
8726
|
-
});
|
|
8818
|
+
translateAxis(withTransforms.x, -node.scroll.offset.x);
|
|
8819
|
+
translateAxis(withTransforms.y, -node.scroll.offset.y);
|
|
8727
8820
|
}
|
|
8728
8821
|
if (!hasTransform(node.latestValues))
|
|
8729
8822
|
continue;
|
|
@@ -8866,8 +8959,7 @@
|
|
|
8866
8959
|
}
|
|
8867
8960
|
else if (this.targetDelta) {
|
|
8868
8961
|
if (Boolean(this.resumingFrom)) {
|
|
8869
|
-
|
|
8870
|
-
this.target = this.applyTransform(this.layout.layoutBox);
|
|
8962
|
+
this.applyTransform(this.layout.layoutBox, false, this.target);
|
|
8871
8963
|
}
|
|
8872
8964
|
else {
|
|
8873
8965
|
copyBoxInto(this.target, this.layout.layoutBox);
|
|
@@ -9477,6 +9569,12 @@
|
|
|
9477
9569
|
axisSnapshot.max = axisSnapshot.min + length;
|
|
9478
9570
|
});
|
|
9479
9571
|
}
|
|
9572
|
+
else if (animationType === "x" || animationType === "y") {
|
|
9573
|
+
const snapAxis = animationType === "x" ? "y" : "x";
|
|
9574
|
+
copyAxisInto(isShared
|
|
9575
|
+
? snapshot.measuredBox[snapAxis]
|
|
9576
|
+
: snapshot.layoutBox[snapAxis], layout[snapAxis]);
|
|
9577
|
+
}
|
|
9480
9578
|
else if (shouldAnimatePositionOnly(animationType, snapshot.layoutBox, layout)) {
|
|
9481
9579
|
eachAxis((axis) => {
|
|
9482
9580
|
const axisSnapshot = isShared
|
|
@@ -9592,6 +9690,18 @@
|
|
|
9592
9690
|
function clearIsLayoutDirty(node) {
|
|
9593
9691
|
node.isLayoutDirty = false;
|
|
9594
9692
|
}
|
|
9693
|
+
/**
|
|
9694
|
+
* When a node is animation-blocked (e.g. during drag) and its component
|
|
9695
|
+
* didn't re-render (memoized), willUpdate() is never called so there's
|
|
9696
|
+
* no snapshot. Use the previous layout as a snapshot and mark dirty so
|
|
9697
|
+
* resetTransform/updateLayout/notifyLayoutUpdate process it normally.
|
|
9698
|
+
*/
|
|
9699
|
+
function ensureDraggedNodesSnapshotted(node) {
|
|
9700
|
+
if (node.isAnimationBlocked && node.layout && !node.isLayoutDirty) {
|
|
9701
|
+
node.snapshot = node.layout;
|
|
9702
|
+
node.isLayoutDirty = true;
|
|
9703
|
+
}
|
|
9704
|
+
}
|
|
9595
9705
|
function resetTransformStyle(node) {
|
|
9596
9706
|
const { visualElement } = node.options;
|
|
9597
9707
|
if (visualElement && visualElement.getProps().onBeforeLayoutMeasure) {
|
|
@@ -10147,6 +10257,7 @@
|
|
|
10147
10257
|
`);
|
|
10148
10258
|
}
|
|
10149
10259
|
return () => {
|
|
10260
|
+
ref.current?.removeAttribute("data-motion-pop-id");
|
|
10150
10261
|
if (parent.contains(style)) {
|
|
10151
10262
|
parent.removeChild(style);
|
|
10152
10263
|
}
|
|
@@ -10425,8 +10536,8 @@
|
|
|
10425
10536
|
if (exitingComponents.current.has(key)) {
|
|
10426
10537
|
return;
|
|
10427
10538
|
}
|
|
10428
|
-
exitingComponents.current.add(key);
|
|
10429
10539
|
if (exitComplete.has(key)) {
|
|
10540
|
+
exitingComponents.current.add(key);
|
|
10430
10541
|
exitComplete.set(key, true);
|
|
10431
10542
|
}
|
|
10432
10543
|
else {
|
|
@@ -10706,8 +10817,12 @@
|
|
|
10706
10817
|
* We attempt to import this package but require won't be defined in esm environments, in that case
|
|
10707
10818
|
* isPropValid will have to be provided via `MotionContext`. In a 6.0.0 this should probably be removed
|
|
10708
10819
|
* in favour of explicit injection.
|
|
10820
|
+
*
|
|
10821
|
+
* String concatenation prevents bundlers like webpack (e.g. Storybook)
|
|
10822
|
+
* from statically resolving this optional dependency at build time.
|
|
10709
10823
|
*/
|
|
10710
|
-
|
|
10824
|
+
const emotionPkg = "@emotion/is-prop-" + "valid";
|
|
10825
|
+
loadExternalIsValidProp(require(emotionPkg).default);
|
|
10711
10826
|
}
|
|
10712
10827
|
catch {
|
|
10713
10828
|
// We don't need to actually do anything here - the fallback is the existing `isPropValid`.
|
|
@@ -10724,6 +10839,8 @@
|
|
|
10724
10839
|
*/
|
|
10725
10840
|
if (key === "values" && typeof props.values === "object")
|
|
10726
10841
|
continue;
|
|
10842
|
+
if (isMotionValue(props[key]))
|
|
10843
|
+
continue;
|
|
10727
10844
|
if (shouldForward(key) ||
|
|
10728
10845
|
(forwardMotionProps === true && isValidMotionProp(key)) ||
|
|
10729
10846
|
(!isDom && !isValidMotionProp(key)) ||
|
|
@@ -11436,6 +11553,7 @@
|
|
|
11436
11553
|
constructor() {
|
|
11437
11554
|
super(...arguments);
|
|
11438
11555
|
this.id = id$1++;
|
|
11556
|
+
this.isExitComplete = false;
|
|
11439
11557
|
}
|
|
11440
11558
|
update() {
|
|
11441
11559
|
if (!this.node.presenceContext)
|
|
@@ -11445,9 +11563,38 @@
|
|
|
11445
11563
|
if (!this.node.animationState || isPresent === prevIsPresent) {
|
|
11446
11564
|
return;
|
|
11447
11565
|
}
|
|
11566
|
+
if (isPresent && prevIsPresent === false) {
|
|
11567
|
+
/**
|
|
11568
|
+
* When re-entering, if the exit animation already completed
|
|
11569
|
+
* (element is at rest), reset to initial values so the enter
|
|
11570
|
+
* animation replays from the correct position.
|
|
11571
|
+
*/
|
|
11572
|
+
if (this.isExitComplete) {
|
|
11573
|
+
const { initial, custom } = this.node.getProps();
|
|
11574
|
+
if (typeof initial === "string") {
|
|
11575
|
+
const resolved = resolveVariant(this.node, initial, custom);
|
|
11576
|
+
if (resolved) {
|
|
11577
|
+
const { transition, transitionEnd, ...target } = resolved;
|
|
11578
|
+
for (const key in target) {
|
|
11579
|
+
this.node
|
|
11580
|
+
.getValue(key)
|
|
11581
|
+
?.jump(target[key]);
|
|
11582
|
+
}
|
|
11583
|
+
}
|
|
11584
|
+
}
|
|
11585
|
+
this.node.animationState.reset();
|
|
11586
|
+
this.node.animationState.animateChanges();
|
|
11587
|
+
}
|
|
11588
|
+
else {
|
|
11589
|
+
this.node.animationState.setActive("exit", false);
|
|
11590
|
+
}
|
|
11591
|
+
this.isExitComplete = false;
|
|
11592
|
+
return;
|
|
11593
|
+
}
|
|
11448
11594
|
const exitAnimation = this.node.animationState.setActive("exit", !isPresent);
|
|
11449
11595
|
if (onExitComplete && !isPresent) {
|
|
11450
11596
|
exitAnimation.then(() => {
|
|
11597
|
+
this.isExitComplete = true;
|
|
11451
11598
|
onExitComplete(this.id);
|
|
11452
11599
|
});
|
|
11453
11600
|
}
|
|
@@ -12174,7 +12321,8 @@
|
|
|
12174
12321
|
return;
|
|
12175
12322
|
}
|
|
12176
12323
|
let transition = (constraints && constraints[axis]) || {};
|
|
12177
|
-
if (dragSnapToOrigin
|
|
12324
|
+
if (dragSnapToOrigin === true ||
|
|
12325
|
+
dragSnapToOrigin === axis)
|
|
12178
12326
|
transition = { min: 0, max: 0 };
|
|
12179
12327
|
/**
|
|
12180
12328
|
* Overdamp the boundary spring if `dragElastic` is disabled. There's still a frame
|
|
@@ -12815,7 +12963,7 @@
|
|
|
12815
12963
|
this.isInView = false;
|
|
12816
12964
|
}
|
|
12817
12965
|
startObserver() {
|
|
12818
|
-
this.
|
|
12966
|
+
this.stopObserver?.();
|
|
12819
12967
|
const { viewport = {} } = this.node.getProps();
|
|
12820
12968
|
const { root, margin: rootMargin, amount = "some", once } = viewport;
|
|
12821
12969
|
const options = {
|
|
@@ -12852,7 +13000,7 @@
|
|
|
12852
13000
|
const callback = isIntersecting ? onViewportEnter : onViewportLeave;
|
|
12853
13001
|
callback && callback(entry);
|
|
12854
13002
|
};
|
|
12855
|
-
|
|
13003
|
+
this.stopObserver = observeIntersection(this.node.current, options, onIntersectionUpdate);
|
|
12856
13004
|
}
|
|
12857
13005
|
mount() {
|
|
12858
13006
|
this.startObserver();
|
|
@@ -12866,7 +13014,11 @@
|
|
|
12866
13014
|
this.startObserver();
|
|
12867
13015
|
}
|
|
12868
13016
|
}
|
|
12869
|
-
unmount() {
|
|
13017
|
+
unmount() {
|
|
13018
|
+
this.stopObserver?.();
|
|
13019
|
+
this.hasEnteredView = false;
|
|
13020
|
+
this.isInView = false;
|
|
13021
|
+
}
|
|
12870
13022
|
}
|
|
12871
13023
|
function hasViewportOptionChanged({ viewport = {} }, { viewport: prevViewport = {} } = {}) {
|
|
12872
13024
|
return (name) => viewport[name] !== prevViewport[name];
|
|
@@ -14320,16 +14472,48 @@
|
|
|
14320
14472
|
[ScrollOffset.Any, "cover"],
|
|
14321
14473
|
[ScrollOffset.All, "contain"],
|
|
14322
14474
|
];
|
|
14323
|
-
|
|
14475
|
+
const stringToProgress = {
|
|
14476
|
+
start: 0,
|
|
14477
|
+
end: 1,
|
|
14478
|
+
};
|
|
14479
|
+
function parseStringOffset(s) {
|
|
14480
|
+
const parts = s.trim().split(/\s+/);
|
|
14481
|
+
if (parts.length !== 2)
|
|
14482
|
+
return undefined;
|
|
14483
|
+
const a = stringToProgress[parts[0]];
|
|
14484
|
+
const b = stringToProgress[parts[1]];
|
|
14485
|
+
if (a === undefined || b === undefined)
|
|
14486
|
+
return undefined;
|
|
14487
|
+
return [a, b];
|
|
14488
|
+
}
|
|
14489
|
+
function normaliseOffset(offset) {
|
|
14324
14490
|
if (offset.length !== 2)
|
|
14491
|
+
return undefined;
|
|
14492
|
+
const result = [];
|
|
14493
|
+
for (const item of offset) {
|
|
14494
|
+
if (Array.isArray(item)) {
|
|
14495
|
+
result.push(item);
|
|
14496
|
+
}
|
|
14497
|
+
else if (typeof item === "string") {
|
|
14498
|
+
const parsed = parseStringOffset(item);
|
|
14499
|
+
if (!parsed)
|
|
14500
|
+
return undefined;
|
|
14501
|
+
result.push(parsed);
|
|
14502
|
+
}
|
|
14503
|
+
else {
|
|
14504
|
+
return undefined;
|
|
14505
|
+
}
|
|
14506
|
+
}
|
|
14507
|
+
return result;
|
|
14508
|
+
}
|
|
14509
|
+
function matchesPreset(offset, preset) {
|
|
14510
|
+
const normalised = normaliseOffset(offset);
|
|
14511
|
+
if (!normalised)
|
|
14325
14512
|
return false;
|
|
14326
14513
|
for (let i = 0; i < 2; i++) {
|
|
14327
|
-
const o =
|
|
14514
|
+
const o = normalised[i];
|
|
14328
14515
|
const p = preset[i];
|
|
14329
|
-
if (
|
|
14330
|
-
o.length !== 2 ||
|
|
14331
|
-
o[0] !== p[0] ||
|
|
14332
|
-
o[1] !== p[1])
|
|
14516
|
+
if (o[0] !== p[0] || o[1] !== p[1])
|
|
14333
14517
|
return false;
|
|
14334
14518
|
}
|
|
14335
14519
|
return true;
|