framer-motion 11.0.12 → 11.0.14
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/dom-entry.js +1 -1
- package/dist/cjs/{index-legacy-4a7bf96d.js → index-legacy-c9b3fc9b.js} +99 -40
- package/dist/cjs/index.js +1 -1
- package/dist/dom.js +1 -1
- package/dist/es/animation/animators/AcceleratedAnimation.mjs +51 -15
- package/dist/es/animation/animators/BaseAnimation.mjs +4 -4
- package/dist/es/animation/animators/MainThreadAnimation.mjs +14 -3
- package/dist/es/animation/animators/waapi/utils/get-final-keyframe.mjs +4 -2
- package/dist/es/render/dom/DOMKeyframesResolver.mjs +21 -10
- package/dist/es/render/dom/value-types/number.mjs +2 -0
- package/dist/es/render/utils/KeyframesResolver.mjs +3 -5
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/value/index.mjs +1 -1
- package/dist/framer-motion.dev.js +99 -40
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +11 -6
- package/dist/projection.dev.js +99 -40
- package/dist/three-entry.d.ts +2 -1
- package/package.json +9 -9
package/dist/cjs/dom-entry.js
CHANGED
|
@@ -466,6 +466,8 @@ const numberValueTypes = {
|
|
|
466
466
|
originZ: px,
|
|
467
467
|
// Misc
|
|
468
468
|
zIndex: int,
|
|
469
|
+
backgroundPositionX: px,
|
|
470
|
+
backgroundPositionY: px,
|
|
469
471
|
// SVG
|
|
470
472
|
fillOpacity: alpha,
|
|
471
473
|
strokeOpacity: alpha,
|
|
@@ -837,12 +839,14 @@ const instantAnimationState = {
|
|
|
837
839
|
};
|
|
838
840
|
|
|
839
841
|
const isNotNull = (value) => value !== null;
|
|
840
|
-
function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }) {
|
|
842
|
+
function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyframe) {
|
|
841
843
|
const resolvedKeyframes = keyframes.filter(isNotNull);
|
|
842
844
|
const index = repeat && repeatType !== "loop" && repeat % 2 === 1
|
|
843
845
|
? 0
|
|
844
846
|
: resolvedKeyframes.length - 1;
|
|
845
|
-
return
|
|
847
|
+
return !index || finalKeyframe === undefined
|
|
848
|
+
? resolvedKeyframes[index]
|
|
849
|
+
: finalKeyframe;
|
|
846
850
|
}
|
|
847
851
|
|
|
848
852
|
let now;
|
|
@@ -1065,13 +1069,10 @@ function readAllKeyframes() {
|
|
|
1065
1069
|
anyNeedsMeasurement = true;
|
|
1066
1070
|
}
|
|
1067
1071
|
});
|
|
1068
|
-
frame.resolveKeyframes(measureAllKeyframes);
|
|
1069
1072
|
}
|
|
1070
1073
|
function flushKeyframeResolvers() {
|
|
1071
1074
|
readAllKeyframes();
|
|
1072
1075
|
measureAllKeyframes();
|
|
1073
|
-
cancelFrame(readAllKeyframes);
|
|
1074
|
-
cancelFrame(measureAllKeyframes);
|
|
1075
1076
|
}
|
|
1076
1077
|
class KeyframeResolver {
|
|
1077
1078
|
constructor(unresolvedKeyframes, onComplete, name, motionValue, element, isAsync = false) {
|
|
@@ -1110,6 +1111,7 @@ class KeyframeResolver {
|
|
|
1110
1111
|
if (!isScheduled) {
|
|
1111
1112
|
isScheduled = true;
|
|
1112
1113
|
frame.read(readAllKeyframes);
|
|
1114
|
+
frame.resolveKeyframes(measureAllKeyframes);
|
|
1113
1115
|
}
|
|
1114
1116
|
}
|
|
1115
1117
|
else {
|
|
@@ -1159,7 +1161,7 @@ class KeyframeResolver {
|
|
|
1159
1161
|
measureEndState() { }
|
|
1160
1162
|
complete() {
|
|
1161
1163
|
this.isComplete = true;
|
|
1162
|
-
this.onComplete(this.unresolvedKeyframes);
|
|
1164
|
+
this.onComplete(this.unresolvedKeyframes, this.finalKeyframe);
|
|
1163
1165
|
toResolve.delete(this);
|
|
1164
1166
|
}
|
|
1165
1167
|
cancel() {
|
|
@@ -1466,7 +1468,6 @@ class DOMKeyframesResolver extends KeyframeResolver {
|
|
|
1466
1468
|
const { unresolvedKeyframes, element, name } = this;
|
|
1467
1469
|
if (!element.current)
|
|
1468
1470
|
return;
|
|
1469
|
-
const noneKeyframeIndexes = [];
|
|
1470
1471
|
super.readKeyframes();
|
|
1471
1472
|
/**
|
|
1472
1473
|
* If any keyframe is a CSS variable, we need to find its value by sampling the element
|
|
@@ -1479,12 +1480,6 @@ class DOMKeyframesResolver extends KeyframeResolver {
|
|
|
1479
1480
|
unresolvedKeyframes[i] = resolved;
|
|
1480
1481
|
}
|
|
1481
1482
|
}
|
|
1482
|
-
if (isNone(unresolvedKeyframes[i])) {
|
|
1483
|
-
noneKeyframeIndexes.push(i);
|
|
1484
|
-
}
|
|
1485
|
-
}
|
|
1486
|
-
if (noneKeyframeIndexes.length) {
|
|
1487
|
-
makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name);
|
|
1488
1483
|
}
|
|
1489
1484
|
/**
|
|
1490
1485
|
* Check to see if unit type has changed. If so schedule jobs that will
|
|
@@ -1493,7 +1488,7 @@ class DOMKeyframesResolver extends KeyframeResolver {
|
|
|
1493
1488
|
* TODO: We can throw if there are multiple keyframes and the value type changes.
|
|
1494
1489
|
*/
|
|
1495
1490
|
if (!positionalKeys.has(name) || unresolvedKeyframes.length !== 2) {
|
|
1496
|
-
return;
|
|
1491
|
+
return this.resolveNoneKeyframes();
|
|
1497
1492
|
}
|
|
1498
1493
|
const [origin, target] = unresolvedKeyframes;
|
|
1499
1494
|
const originType = findDimensionValueType(origin);
|
|
@@ -1501,7 +1496,7 @@ class DOMKeyframesResolver extends KeyframeResolver {
|
|
|
1501
1496
|
/**
|
|
1502
1497
|
* Either we don't recognise these value types or we can animate between them.
|
|
1503
1498
|
*/
|
|
1504
|
-
if (
|
|
1499
|
+
if (originType === targetType)
|
|
1505
1500
|
return;
|
|
1506
1501
|
/**
|
|
1507
1502
|
* If both values are numbers or pixels, we can animate between them by
|
|
@@ -1522,6 +1517,18 @@ class DOMKeyframesResolver extends KeyframeResolver {
|
|
|
1522
1517
|
this.needsMeasurement = true;
|
|
1523
1518
|
}
|
|
1524
1519
|
}
|
|
1520
|
+
resolveNoneKeyframes() {
|
|
1521
|
+
const { unresolvedKeyframes, name } = this;
|
|
1522
|
+
const noneKeyframeIndexes = [];
|
|
1523
|
+
for (let i = 0; i < unresolvedKeyframes.length; i++) {
|
|
1524
|
+
if (isNone(unresolvedKeyframes[i])) {
|
|
1525
|
+
noneKeyframeIndexes.push(i);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
if (noneKeyframeIndexes.length) {
|
|
1529
|
+
makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name);
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1525
1532
|
unsetTransforms() {
|
|
1526
1533
|
const { element, name, unresolvedKeyframes } = this;
|
|
1527
1534
|
if (!element.current)
|
|
@@ -1550,7 +1557,12 @@ class DOMKeyframesResolver extends KeyframeResolver {
|
|
|
1550
1557
|
return;
|
|
1551
1558
|
const value = element.getValue(name);
|
|
1552
1559
|
value && value.jump(this.measuredOrigin, false);
|
|
1553
|
-
unresolvedKeyframes
|
|
1560
|
+
const finalKeyframeIndex = unresolvedKeyframes.length - 1;
|
|
1561
|
+
const finalKeyframe = unresolvedKeyframes[finalKeyframeIndex];
|
|
1562
|
+
unresolvedKeyframes[finalKeyframeIndex] = positionalValues[name](element.measureViewportBox(), window.getComputedStyle(element.current));
|
|
1563
|
+
if (finalKeyframe !== null) {
|
|
1564
|
+
this.finalKeyframe = finalKeyframe;
|
|
1565
|
+
}
|
|
1554
1566
|
if (name === "height" && this.suspendedScrollY !== undefined) {
|
|
1555
1567
|
window.scrollTo(0, this.suspendedScrollY);
|
|
1556
1568
|
}
|
|
@@ -1562,6 +1574,7 @@ class DOMKeyframesResolver extends KeyframeResolver {
|
|
|
1562
1574
|
.set(unsetTransformValue);
|
|
1563
1575
|
});
|
|
1564
1576
|
}
|
|
1577
|
+
this.resolveNoneKeyframes();
|
|
1565
1578
|
}
|
|
1566
1579
|
}
|
|
1567
1580
|
|
|
@@ -1660,7 +1673,7 @@ class BaseAnimation {
|
|
|
1660
1673
|
* will check if its possible to run the animation and, if not, skip it.
|
|
1661
1674
|
* Otherwise, it will call initPlayback on the implementing class.
|
|
1662
1675
|
*/
|
|
1663
|
-
onKeyframesResolved(keyframes) {
|
|
1676
|
+
onKeyframesResolved(keyframes, finalKeyframe) {
|
|
1664
1677
|
const { name, type, velocity, delay, onComplete, onUpdate } = this.options;
|
|
1665
1678
|
/**
|
|
1666
1679
|
* If we can't animate this value with the resolved keyframes
|
|
@@ -1669,8 +1682,7 @@ class BaseAnimation {
|
|
|
1669
1682
|
if (!canAnimate(keyframes, name, type, velocity)) {
|
|
1670
1683
|
// Finish immediately
|
|
1671
1684
|
if (instantAnimationState.current || !delay) {
|
|
1672
|
-
|
|
1673
|
-
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(finalKeyframe);
|
|
1685
|
+
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(getFinalKeyframe(keyframes, this.options, finalKeyframe));
|
|
1674
1686
|
onComplete === null || onComplete === void 0 ? void 0 : onComplete();
|
|
1675
1687
|
this.resolveFinishedPromise();
|
|
1676
1688
|
this.updateFinishedPromise();
|
|
@@ -1683,7 +1695,8 @@ class BaseAnimation {
|
|
|
1683
1695
|
}
|
|
1684
1696
|
this._resolved = {
|
|
1685
1697
|
keyframes,
|
|
1686
|
-
|
|
1698
|
+
finalKeyframe,
|
|
1699
|
+
...this.initPlayback(keyframes, finalKeyframe),
|
|
1687
1700
|
};
|
|
1688
1701
|
this.onPostResolved();
|
|
1689
1702
|
}
|
|
@@ -2524,7 +2537,7 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
2524
2537
|
this.pendingPlayState = "running";
|
|
2525
2538
|
this.state = "idle";
|
|
2526
2539
|
const { name, motionValue, keyframes } = this.options;
|
|
2527
|
-
const onResolved = (resolvedKeyframes) => this.onKeyframesResolved(resolvedKeyframes);
|
|
2540
|
+
const onResolved = (resolvedKeyframes, finalKeyframe) => this.onKeyframesResolved(resolvedKeyframes, finalKeyframe);
|
|
2528
2541
|
if (name && motionValue && motionValue.owner) {
|
|
2529
2542
|
this.resolver = motionValue.owner.resolveKeyframes(keyframes, onResolved, name, motionValue);
|
|
2530
2543
|
}
|
|
@@ -2598,7 +2611,13 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
2598
2611
|
}
|
|
2599
2612
|
}
|
|
2600
2613
|
tick(timestamp, sample = false) {
|
|
2601
|
-
const {
|
|
2614
|
+
const { resolved } = this;
|
|
2615
|
+
// If the animations has failed to resolve, return the final keyframe.
|
|
2616
|
+
if (!resolved) {
|
|
2617
|
+
const { keyframes } = this.options;
|
|
2618
|
+
return { done: true, value: keyframes[keyframes.length - 1] };
|
|
2619
|
+
}
|
|
2620
|
+
const { finalKeyframe, generator, mirroredGenerator, mapPercentToKeyframes, keyframes, calculatedDuration, totalDuration, resolvedDuration, } = resolved;
|
|
2602
2621
|
if (this.startTime === null)
|
|
2603
2622
|
return generator.next(0);
|
|
2604
2623
|
const { delay, repeat, repeatType, repeatDelay, onUpdate } = this.options;
|
|
@@ -2703,6 +2722,9 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
2703
2722
|
}
|
|
2704
2723
|
const isAnimationFinished = this.holdTime === null &&
|
|
2705
2724
|
(this.state === "finished" || (this.state === "running" && done));
|
|
2725
|
+
if (isAnimationFinished && finalKeyframe !== undefined) {
|
|
2726
|
+
state.value = getFinalKeyframe(keyframes, this.options, finalKeyframe);
|
|
2727
|
+
}
|
|
2706
2728
|
if (onUpdate) {
|
|
2707
2729
|
onUpdate(state.value);
|
|
2708
2730
|
}
|
|
@@ -2712,7 +2734,8 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
2712
2734
|
return state;
|
|
2713
2735
|
}
|
|
2714
2736
|
get duration() {
|
|
2715
|
-
|
|
2737
|
+
const { resolved } = this;
|
|
2738
|
+
return resolved ? millisecondsToSeconds(resolved.calculatedDuration) : 0;
|
|
2716
2739
|
}
|
|
2717
2740
|
get time() {
|
|
2718
2741
|
return millisecondsToSeconds(this.currentTime);
|
|
@@ -2951,10 +2974,10 @@ class AcceleratedAnimation extends BaseAnimation {
|
|
|
2951
2974
|
constructor(options) {
|
|
2952
2975
|
super(options);
|
|
2953
2976
|
const { name, motionValue, keyframes } = this.options;
|
|
2954
|
-
this.resolver = new DOMKeyframesResolver(keyframes, (resolvedKeyframes) => this.onKeyframesResolved(resolvedKeyframes), name, motionValue);
|
|
2977
|
+
this.resolver = new DOMKeyframesResolver(keyframes, (resolvedKeyframes, finalKeyframe) => this.onKeyframesResolved(resolvedKeyframes, finalKeyframe), name, motionValue);
|
|
2955
2978
|
this.resolver.scheduleResolve();
|
|
2956
2979
|
}
|
|
2957
|
-
initPlayback(keyframes) {
|
|
2980
|
+
initPlayback(keyframes, finalKeyframe) {
|
|
2958
2981
|
let duration = this.options.duration || 300;
|
|
2959
2982
|
/**
|
|
2960
2983
|
* If this animation needs pre-generated keyframes then generate.
|
|
@@ -2987,7 +3010,7 @@ class AcceleratedAnimation extends BaseAnimation {
|
|
|
2987
3010
|
*/
|
|
2988
3011
|
animation.onfinish = () => {
|
|
2989
3012
|
const { onComplete } = this.options;
|
|
2990
|
-
motionValue.set(getFinalKeyframe(keyframes, this.options));
|
|
3013
|
+
motionValue.set(getFinalKeyframe(keyframes, this.options, finalKeyframe));
|
|
2991
3014
|
onComplete && onComplete();
|
|
2992
3015
|
this.cancel();
|
|
2993
3016
|
this.resolveFinishedPromise();
|
|
@@ -3001,27 +3024,45 @@ class AcceleratedAnimation extends BaseAnimation {
|
|
|
3001
3024
|
};
|
|
3002
3025
|
}
|
|
3003
3026
|
get duration() {
|
|
3004
|
-
const {
|
|
3027
|
+
const { resolved } = this;
|
|
3028
|
+
if (!resolved)
|
|
3029
|
+
return 0;
|
|
3030
|
+
const { duration } = resolved;
|
|
3005
3031
|
return millisecondsToSeconds(duration);
|
|
3006
3032
|
}
|
|
3007
3033
|
get time() {
|
|
3008
|
-
const {
|
|
3034
|
+
const { resolved } = this;
|
|
3035
|
+
if (!resolved)
|
|
3036
|
+
return 0;
|
|
3037
|
+
const { animation } = resolved;
|
|
3009
3038
|
return millisecondsToSeconds(animation.currentTime || 0);
|
|
3010
3039
|
}
|
|
3011
3040
|
set time(newTime) {
|
|
3012
|
-
const {
|
|
3041
|
+
const { resolved } = this;
|
|
3042
|
+
if (!resolved)
|
|
3043
|
+
return;
|
|
3044
|
+
const { animation } = resolved;
|
|
3013
3045
|
animation.currentTime = secondsToMilliseconds(newTime);
|
|
3014
3046
|
}
|
|
3015
3047
|
get speed() {
|
|
3016
|
-
const {
|
|
3048
|
+
const { resolved } = this;
|
|
3049
|
+
if (!resolved)
|
|
3050
|
+
return 1;
|
|
3051
|
+
const { animation } = resolved;
|
|
3017
3052
|
return animation.playbackRate;
|
|
3018
3053
|
}
|
|
3019
3054
|
set speed(newSpeed) {
|
|
3020
|
-
const {
|
|
3055
|
+
const { resolved } = this;
|
|
3056
|
+
if (!resolved)
|
|
3057
|
+
return;
|
|
3058
|
+
const { animation } = resolved;
|
|
3021
3059
|
animation.playbackRate = newSpeed;
|
|
3022
3060
|
}
|
|
3023
3061
|
get state() {
|
|
3024
|
-
const {
|
|
3062
|
+
const { resolved } = this;
|
|
3063
|
+
if (!resolved)
|
|
3064
|
+
return "idle";
|
|
3065
|
+
const { animation } = resolved;
|
|
3025
3066
|
return animation.playState;
|
|
3026
3067
|
}
|
|
3027
3068
|
/**
|
|
@@ -3033,7 +3074,10 @@ class AcceleratedAnimation extends BaseAnimation {
|
|
|
3033
3074
|
this.pendingTimeline = timeline;
|
|
3034
3075
|
}
|
|
3035
3076
|
else {
|
|
3036
|
-
const {
|
|
3077
|
+
const { resolved } = this;
|
|
3078
|
+
if (!resolved)
|
|
3079
|
+
return noop;
|
|
3080
|
+
const { animation } = resolved;
|
|
3037
3081
|
animation.timeline = timeline;
|
|
3038
3082
|
animation.onfinish = null;
|
|
3039
3083
|
}
|
|
@@ -3042,16 +3086,25 @@ class AcceleratedAnimation extends BaseAnimation {
|
|
|
3042
3086
|
play() {
|
|
3043
3087
|
if (this.isStopped)
|
|
3044
3088
|
return;
|
|
3045
|
-
const {
|
|
3089
|
+
const { resolved } = this;
|
|
3090
|
+
if (!resolved)
|
|
3091
|
+
return;
|
|
3092
|
+
const { animation } = resolved;
|
|
3046
3093
|
animation.play();
|
|
3047
3094
|
}
|
|
3048
3095
|
pause() {
|
|
3049
|
-
const {
|
|
3096
|
+
const { resolved } = this;
|
|
3097
|
+
if (!resolved)
|
|
3098
|
+
return;
|
|
3099
|
+
const { animation } = resolved;
|
|
3050
3100
|
animation.pause();
|
|
3051
3101
|
}
|
|
3052
3102
|
stop() {
|
|
3053
3103
|
this.isStopped = true;
|
|
3054
|
-
const {
|
|
3104
|
+
const { resolved } = this;
|
|
3105
|
+
if (!resolved)
|
|
3106
|
+
return;
|
|
3107
|
+
const { animation, keyframes } = resolved;
|
|
3055
3108
|
if (animation.playState === "idle" ||
|
|
3056
3109
|
animation.playState === "finished") {
|
|
3057
3110
|
return;
|
|
@@ -3075,10 +3128,16 @@ class AcceleratedAnimation extends BaseAnimation {
|
|
|
3075
3128
|
this.cancel();
|
|
3076
3129
|
}
|
|
3077
3130
|
complete() {
|
|
3078
|
-
this
|
|
3131
|
+
const { resolved } = this;
|
|
3132
|
+
if (!resolved)
|
|
3133
|
+
return;
|
|
3134
|
+
resolved.animation.finish();
|
|
3079
3135
|
}
|
|
3080
3136
|
cancel() {
|
|
3081
|
-
this
|
|
3137
|
+
const { resolved } = this;
|
|
3138
|
+
if (!resolved)
|
|
3139
|
+
return;
|
|
3140
|
+
resolved.animation.cancel();
|
|
3082
3141
|
}
|
|
3083
3142
|
static supports(options) {
|
|
3084
3143
|
const { motionValue, name, repeatDelay, repeatType, damping, type } = options;
|
|
@@ -3298,7 +3357,7 @@ class MotionValue {
|
|
|
3298
3357
|
* This will be replaced by the build step with the latest version number.
|
|
3299
3358
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
3300
3359
|
*/
|
|
3301
|
-
this.version = "11.0.
|
|
3360
|
+
this.version = "11.0.14";
|
|
3302
3361
|
/**
|
|
3303
3362
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
3304
3363
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -4064,7 +4123,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
4064
4123
|
* and warn against mismatches.
|
|
4065
4124
|
*/
|
|
4066
4125
|
if (process.env.NODE_ENV === "development") {
|
|
4067
|
-
warnOnce(nextValue.version === "11.0.
|
|
4126
|
+
warnOnce(nextValue.version === "11.0.14", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.0.14 may not work as expected.`);
|
|
4068
4127
|
}
|
|
4069
4128
|
}
|
|
4070
4129
|
else if (isMotionValue(prevValue)) {
|
package/dist/cjs/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
|
-
var indexLegacy = require('./index-legacy-
|
|
6
|
+
var indexLegacy = require('./index-legacy-c9b3fc9b.js');
|
|
7
7
|
|
|
8
8
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
9
|
|