framer-motion 8.4.7 → 8.5.2-alpha.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/dist/cjs/index.js +92 -40
- package/dist/es/animation/legacy-popmotion/spring.mjs +9 -6
- package/dist/es/animation/optimized-appear/handoff.mjs +18 -12
- package/dist/es/animation/optimized-appear/start.mjs +28 -5
- package/dist/es/motion/utils/valid-prop.mjs +2 -1
- package/dist/es/projection/node/create-projection-node.mjs +31 -13
- package/dist/es/render/VisualElement.mjs +2 -1
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/value/index.mjs +1 -1
- package/dist/framer-motion.dev.js +92 -40
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +11 -3
- package/dist/projection.dev.js +44 -22
- 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.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 +9 -1
- package/package.json +7 -7
package/dist/cjs/index.js
CHANGED
|
@@ -850,6 +850,8 @@ const validMotionProps = new Set([
|
|
|
850
850
|
"layout",
|
|
851
851
|
"layoutId",
|
|
852
852
|
"layoutDependency",
|
|
853
|
+
"layoutScroll",
|
|
854
|
+
"layoutRoot",
|
|
853
855
|
"onLayoutAnimationStart",
|
|
854
856
|
"onLayoutAnimationComplete",
|
|
855
857
|
"onLayoutMeasure",
|
|
@@ -877,7 +879,6 @@ const validMotionProps = new Set([
|
|
|
877
879
|
"dragTransition",
|
|
878
880
|
"onHoverStart",
|
|
879
881
|
"onHoverEnd",
|
|
880
|
-
"layoutScroll",
|
|
881
882
|
...inViewProps,
|
|
882
883
|
...tapProps,
|
|
883
884
|
...animationProps,
|
|
@@ -2104,7 +2105,7 @@ class MotionValue {
|
|
|
2104
2105
|
* This will be replaced by the build step with the latest version number.
|
|
2105
2106
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
2106
2107
|
*/
|
|
2107
|
-
this.version = "8.
|
|
2108
|
+
this.version = "8.5.2-alpha.0";
|
|
2108
2109
|
/**
|
|
2109
2110
|
* Duration, in milliseconds, since last updating frame.
|
|
2110
2111
|
*
|
|
@@ -2803,8 +2804,21 @@ const appearStoreId = (id, value) => `${id}: ${value}`;
|
|
|
2803
2804
|
function handoffOptimizedAppearAnimation(id, name, value) {
|
|
2804
2805
|
const { MotionAppearAnimations } = window;
|
|
2805
2806
|
const animationId = appearStoreId(id, transformProps.has(name) ? "transform" : name);
|
|
2806
|
-
const animation = MotionAppearAnimations && MotionAppearAnimations.get(animationId)
|
|
2807
|
-
|
|
2807
|
+
const { animation, ready } = (MotionAppearAnimations && MotionAppearAnimations.get(animationId)) ||
|
|
2808
|
+
{};
|
|
2809
|
+
if (!animation)
|
|
2810
|
+
return 0;
|
|
2811
|
+
const cancelOptimisedAnimation = () => {
|
|
2812
|
+
MotionAppearAnimations.delete(animationId);
|
|
2813
|
+
/**
|
|
2814
|
+
* Animation.cancel() throws so it needs to be wrapped in a try/catch
|
|
2815
|
+
*/
|
|
2816
|
+
try {
|
|
2817
|
+
animation.cancel();
|
|
2818
|
+
}
|
|
2819
|
+
catch (e) { }
|
|
2820
|
+
};
|
|
2821
|
+
if (ready) {
|
|
2808
2822
|
const sampledTime = performance.now();
|
|
2809
2823
|
/**
|
|
2810
2824
|
* Resync handoff animation with optimised animation.
|
|
@@ -2829,19 +2843,12 @@ function handoffOptimizedAppearAnimation(id, name, value) {
|
|
|
2829
2843
|
* 2. As all independent transforms share a single transform animation, stopping
|
|
2830
2844
|
* it synchronously would prevent subsequent transforms from handing off.
|
|
2831
2845
|
*/
|
|
2832
|
-
sync.render(
|
|
2833
|
-
|
|
2834
|
-
/**
|
|
2835
|
-
* Animation.cancel() throws so it needs to be wrapped in a try/catch
|
|
2836
|
-
*/
|
|
2837
|
-
try {
|
|
2838
|
-
animation.cancel();
|
|
2839
|
-
}
|
|
2840
|
-
catch (e) { }
|
|
2841
|
-
});
|
|
2846
|
+
sync.render(cancelOptimisedAnimation);
|
|
2847
|
+
console.log(animation.currentTime);
|
|
2842
2848
|
return animation.currentTime || 0;
|
|
2843
2849
|
}
|
|
2844
2850
|
else {
|
|
2851
|
+
cancelOptimisedAnimation();
|
|
2845
2852
|
return 0;
|
|
2846
2853
|
}
|
|
2847
2854
|
}
|
|
@@ -3383,7 +3390,7 @@ const velocitySampleDuration = 5;
|
|
|
3383
3390
|
/**
|
|
3384
3391
|
* This is based on the spring implementation of Wobble https://github.com/skevy/wobble
|
|
3385
3392
|
*/
|
|
3386
|
-
function spring({ keyframes,
|
|
3393
|
+
function spring({ keyframes, restDelta, restSpeed, ...options }) {
|
|
3387
3394
|
let origin = keyframes[0];
|
|
3388
3395
|
let target = keyframes[keyframes.length - 1];
|
|
3389
3396
|
/**
|
|
@@ -3399,12 +3406,15 @@ function spring({ keyframes, restSpeed = 2, restDelta = 0.01, ...options }) {
|
|
|
3399
3406
|
const initialDelta = target - origin;
|
|
3400
3407
|
const undampedAngularFreq = Math.sqrt(stiffness / mass) / 1000;
|
|
3401
3408
|
/**
|
|
3402
|
-
* If we're working
|
|
3403
|
-
*
|
|
3409
|
+
* If we're working on a granular scale, use smaller defaults for determining
|
|
3410
|
+
* when the spring is finished.
|
|
3411
|
+
*
|
|
3412
|
+
* These defaults have been selected emprically based on what strikes a good
|
|
3413
|
+
* ratio between feeling good and finishing as soon as changes are imperceptible.
|
|
3404
3414
|
*/
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3415
|
+
const isGranularScale = Math.abs(initialDelta) < 5;
|
|
3416
|
+
restSpeed || (restSpeed = isGranularScale ? 0.01 : 2);
|
|
3417
|
+
restDelta || (restDelta = isGranularScale ? 0.005 : 0.5);
|
|
3408
3418
|
if (dampingRatio < 1) {
|
|
3409
3419
|
const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
|
|
3410
3420
|
// Underdamped spring
|
|
@@ -5997,7 +6007,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
5997
6007
|
* and warn against mismatches.
|
|
5998
6008
|
*/
|
|
5999
6009
|
if (process.env.NODE_ENV === "development") {
|
|
6000
|
-
warnOnce(nextValue.version === "8.
|
|
6010
|
+
warnOnce(nextValue.version === "8.5.2-alpha.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 8.5.2-alpha.0 may not work as expected.`);
|
|
6001
6011
|
}
|
|
6002
6012
|
}
|
|
6003
6013
|
else if (isMotionValue(prevValue)) {
|
|
@@ -6255,7 +6265,7 @@ class VisualElement {
|
|
|
6255
6265
|
}
|
|
6256
6266
|
if (!this.projection && ProjectionNodeConstructor) {
|
|
6257
6267
|
this.projection = new ProjectionNodeConstructor(projectionId, this.latestValues, this.parent && this.parent.projection);
|
|
6258
|
-
const { layoutId, layout, drag, dragConstraints, layoutScroll } = renderedProps;
|
|
6268
|
+
const { layoutId, layout, drag, dragConstraints, layoutScroll, layoutRoot, } = renderedProps;
|
|
6259
6269
|
this.projection.setOptions({
|
|
6260
6270
|
layoutId,
|
|
6261
6271
|
layout,
|
|
@@ -6273,6 +6283,7 @@ class VisualElement {
|
|
|
6273
6283
|
animationType: typeof layout === "string" ? layout : "both",
|
|
6274
6284
|
initialPromotionConfig: initialLayoutGroupConfig,
|
|
6275
6285
|
layoutScroll,
|
|
6286
|
+
layoutRoot,
|
|
6276
6287
|
});
|
|
6277
6288
|
}
|
|
6278
6289
|
return features;
|
|
@@ -7413,7 +7424,8 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
7413
7424
|
* relative to its parent has indeed changed. So here we check for that.
|
|
7414
7425
|
*/
|
|
7415
7426
|
const hasOnlyRelativeTargetChanged = !hasLayoutChanged && hasRelativeTargetChanged;
|
|
7416
|
-
if (
|
|
7427
|
+
if (this.options.layoutRoot ||
|
|
7428
|
+
((_c = this.resumeFrom) === null || _c === void 0 ? void 0 : _c.instance) ||
|
|
7417
7429
|
hasOnlyRelativeTargetChanged ||
|
|
7418
7430
|
(hasLayoutChanged &&
|
|
7419
7431
|
(targetChanged || !this.currentAnimation))) {
|
|
@@ -7427,7 +7439,8 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
7427
7439
|
onPlay: onLayoutAnimationStart,
|
|
7428
7440
|
onComplete: onLayoutAnimationComplete,
|
|
7429
7441
|
};
|
|
7430
|
-
if (visualElement.shouldReduceMotion
|
|
7442
|
+
if (visualElement.shouldReduceMotion ||
|
|
7443
|
+
this.options.layoutRoot) {
|
|
7431
7444
|
animationOptions.delay = 0;
|
|
7432
7445
|
animationOptions.type = false;
|
|
7433
7446
|
}
|
|
@@ -7483,6 +7496,10 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
7483
7496
|
(_a = this.nodes) === null || _a === void 0 ? void 0 : _a.forEach(resetRotation);
|
|
7484
7497
|
this.animationId++;
|
|
7485
7498
|
}
|
|
7499
|
+
getTransformTemplate() {
|
|
7500
|
+
var _a;
|
|
7501
|
+
return (_a = this.options.visualElement) === null || _a === void 0 ? void 0 : _a.getProps().transformTemplate;
|
|
7502
|
+
}
|
|
7486
7503
|
willUpdate(shouldNotifyListeners = true) {
|
|
7487
7504
|
var _a, _b, _c;
|
|
7488
7505
|
if (this.root.isUpdateBlocked()) {
|
|
@@ -7497,12 +7514,14 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
7497
7514
|
const node = this.path[i];
|
|
7498
7515
|
node.shouldResetTransform = true;
|
|
7499
7516
|
node.updateScroll("snapshot");
|
|
7517
|
+
if (node.options.layoutRoot) {
|
|
7518
|
+
node.willUpdate(false);
|
|
7519
|
+
}
|
|
7500
7520
|
}
|
|
7501
7521
|
const { layoutId, layout } = this.options;
|
|
7502
7522
|
if (layoutId === undefined && !layout)
|
|
7503
7523
|
return;
|
|
7504
|
-
|
|
7505
|
-
this.prevTransformTemplateValue = transformTemplate === null || transformTemplate === void 0 ? void 0 : transformTemplate(this.latestValues, "");
|
|
7524
|
+
this.prevTransformTemplateValue = (_c = this.getTransformTemplate()) === null || _c === void 0 ? void 0 : _c(this.latestValues, "");
|
|
7506
7525
|
this.updateSnapshot();
|
|
7507
7526
|
shouldNotifyListeners && this.notifyListeners("willUpdate");
|
|
7508
7527
|
}
|
|
@@ -7634,8 +7653,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
7634
7653
|
return;
|
|
7635
7654
|
const isResetRequested = this.isLayoutDirty || this.shouldResetTransform;
|
|
7636
7655
|
const hasProjection = this.projectionDelta && !isDeltaZero(this.projectionDelta);
|
|
7637
|
-
const
|
|
7638
|
-
const transformTemplateValue = transformTemplate === null || transformTemplate === void 0 ? void 0 : transformTemplate(this.latestValues, "");
|
|
7656
|
+
const transformTemplateValue = (_a = this.getTransformTemplate()) === null || _a === void 0 ? void 0 : _a(this.latestValues, "");
|
|
7639
7657
|
const transformTemplateHasChanged = transformTemplateValue !== this.prevTransformTemplateValue;
|
|
7640
7658
|
if (isResetRequested &&
|
|
7641
7659
|
(hasProjection ||
|
|
@@ -7890,9 +7908,12 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
7890
7908
|
getClosestProjectingParent() {
|
|
7891
7909
|
if (!this.parent ||
|
|
7892
7910
|
hasScale(this.parent.latestValues) ||
|
|
7893
|
-
has2DTranslate(this.parent.latestValues))
|
|
7911
|
+
has2DTranslate(this.parent.latestValues)) {
|
|
7894
7912
|
return undefined;
|
|
7895
|
-
|
|
7913
|
+
}
|
|
7914
|
+
if ((this.parent.relativeTarget ||
|
|
7915
|
+
this.parent.targetDelta ||
|
|
7916
|
+
this.parent.options.layoutRoot) &&
|
|
7896
7917
|
this.parent.layout) {
|
|
7897
7918
|
return this.parent;
|
|
7898
7919
|
}
|
|
@@ -7987,7 +8008,10 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
7987
8008
|
const snapshotLatestValues = (snapshot === null || snapshot === void 0 ? void 0 : snapshot.latestValues) || {};
|
|
7988
8009
|
const mixedValues = { ...this.latestValues };
|
|
7989
8010
|
const targetDelta = createDelta();
|
|
7990
|
-
|
|
8011
|
+
if (!this.relativeParent ||
|
|
8012
|
+
!this.relativeParent.options.layoutRoot) {
|
|
8013
|
+
this.relativeTarget = this.relativeTargetOrigin = undefined;
|
|
8014
|
+
}
|
|
7991
8015
|
this.attemptToResolveRelativeTarget = !hasOnlyRelativeTargetChanged;
|
|
7992
8016
|
const relativeLayout = createBox();
|
|
7993
8017
|
const isSharedLayoutAnimation = (snapshot === null || snapshot === void 0 ? void 0 : snapshot.source) !== ((_a = this.layout) === null || _a === void 0 ? void 0 : _a.source);
|
|
@@ -8018,7 +8042,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
8018
8042
|
this.scheduleRender();
|
|
8019
8043
|
this.animationProgress = progress;
|
|
8020
8044
|
};
|
|
8021
|
-
this.mixTargetDelta(0);
|
|
8045
|
+
this.mixTargetDelta(this.options.layoutRoot ? 1000 : 0);
|
|
8022
8046
|
}
|
|
8023
8047
|
startAnimation(options) {
|
|
8024
8048
|
var _a, _b;
|
|
@@ -8208,7 +8232,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
8208
8232
|
visualElement.scheduleRender();
|
|
8209
8233
|
}
|
|
8210
8234
|
getProjectionStyles(styleProp = {}) {
|
|
8211
|
-
var _a, _b
|
|
8235
|
+
var _a, _b;
|
|
8212
8236
|
// TODO: Return lifecycle-persistent object
|
|
8213
8237
|
const styles = {};
|
|
8214
8238
|
if (!this.instance || this.isSVG)
|
|
@@ -8219,7 +8243,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
8219
8243
|
else {
|
|
8220
8244
|
styles.visibility = "";
|
|
8221
8245
|
}
|
|
8222
|
-
const transformTemplate =
|
|
8246
|
+
const transformTemplate = this.getTransformTemplate();
|
|
8223
8247
|
if (this.needsReset) {
|
|
8224
8248
|
this.needsReset = false;
|
|
8225
8249
|
styles.opacity = "";
|
|
@@ -8264,7 +8288,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
8264
8288
|
*/
|
|
8265
8289
|
styles.opacity =
|
|
8266
8290
|
lead === this
|
|
8267
|
-
? (
|
|
8291
|
+
? (_b = (_a = valuesToRender.opacity) !== null && _a !== void 0 ? _a : this.latestValues.opacity) !== null && _b !== void 0 ? _b : 1
|
|
8268
8292
|
: this.preserveOpacity
|
|
8269
8293
|
? this.latestValues.opacity
|
|
8270
8294
|
: valuesToRender.opacityExit;
|
|
@@ -8394,6 +8418,11 @@ function notifyLayoutUpdate(node) {
|
|
|
8394
8418
|
if (!boxEquals(relativeSnapshot, relativeLayout)) {
|
|
8395
8419
|
hasRelativeTargetChanged = true;
|
|
8396
8420
|
}
|
|
8421
|
+
if (relativeParent.options.layoutRoot) {
|
|
8422
|
+
node.relativeTarget = relativeLayout;
|
|
8423
|
+
node.relativeTargetOrigin = relativeSnapshot;
|
|
8424
|
+
node.relativeParent = relativeParent;
|
|
8425
|
+
}
|
|
8397
8426
|
}
|
|
8398
8427
|
}
|
|
8399
8428
|
}
|
|
@@ -9840,14 +9869,37 @@ function useResetProjection() {
|
|
|
9840
9869
|
return reset;
|
|
9841
9870
|
}
|
|
9842
9871
|
|
|
9843
|
-
function startOptimizedAppearAnimation(element, name, keyframes, options) {
|
|
9872
|
+
function startOptimizedAppearAnimation(element, name, keyframes, options, onReady) {
|
|
9844
9873
|
window.MotionAppearAnimations || (window.MotionAppearAnimations = new Map());
|
|
9845
9874
|
const id = element.dataset[optimizedAppearDataId];
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9875
|
+
if (!id)
|
|
9876
|
+
return;
|
|
9877
|
+
const storeId = appearStoreId(id, name);
|
|
9878
|
+
/**
|
|
9879
|
+
* Use a dummy animation to detect when Chrome is ready to start
|
|
9880
|
+
* painting the page and hold off from triggering the real animation
|
|
9881
|
+
* until then.
|
|
9882
|
+
*/
|
|
9883
|
+
const readyAnimation = animateStyle(element, name, [keyframes[0], keyframes[0]], { duration: 1 });
|
|
9884
|
+
window.MotionAppearAnimations.set(storeId, {
|
|
9885
|
+
animation: readyAnimation,
|
|
9886
|
+
ready: false,
|
|
9887
|
+
});
|
|
9888
|
+
const startAnimation = () => {
|
|
9889
|
+
const animation = animateStyle(element, name, keyframes, options);
|
|
9890
|
+
window.MotionAppearAnimations.set(storeId, { animation, ready: true });
|
|
9891
|
+
if (onReady)
|
|
9892
|
+
onReady(animation);
|
|
9893
|
+
};
|
|
9894
|
+
if (readyAnimation.ready) {
|
|
9895
|
+
readyAnimation.ready.then(() => {
|
|
9896
|
+
readyAnimation.cancel();
|
|
9897
|
+
startAnimation();
|
|
9898
|
+
});
|
|
9899
|
+
}
|
|
9900
|
+
else {
|
|
9901
|
+
startAnimation();
|
|
9849
9902
|
}
|
|
9850
|
-
return animation;
|
|
9851
9903
|
}
|
|
9852
9904
|
|
|
9853
9905
|
const createObject = () => ({});
|
|
@@ -33,7 +33,7 @@ const velocitySampleDuration = 5;
|
|
|
33
33
|
/**
|
|
34
34
|
* This is based on the spring implementation of Wobble https://github.com/skevy/wobble
|
|
35
35
|
*/
|
|
36
|
-
function spring({ keyframes,
|
|
36
|
+
function spring({ keyframes, restDelta, restSpeed, ...options }) {
|
|
37
37
|
let origin = keyframes[0];
|
|
38
38
|
let target = keyframes[keyframes.length - 1];
|
|
39
39
|
/**
|
|
@@ -49,12 +49,15 @@ function spring({ keyframes, restSpeed = 2, restDelta = 0.01, ...options }) {
|
|
|
49
49
|
const initialDelta = target - origin;
|
|
50
50
|
const undampedAngularFreq = Math.sqrt(stiffness / mass) / 1000;
|
|
51
51
|
/**
|
|
52
|
-
* If we're working
|
|
53
|
-
*
|
|
52
|
+
* If we're working on a granular scale, use smaller defaults for determining
|
|
53
|
+
* when the spring is finished.
|
|
54
|
+
*
|
|
55
|
+
* These defaults have been selected emprically based on what strikes a good
|
|
56
|
+
* ratio between feeling good and finishing as soon as changes are imperceptible.
|
|
54
57
|
*/
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
const isGranularScale = Math.abs(initialDelta) < 5;
|
|
59
|
+
restSpeed || (restSpeed = isGranularScale ? 0.01 : 2);
|
|
60
|
+
restDelta || (restDelta = isGranularScale ? 0.005 : 0.5);
|
|
58
61
|
if (dampingRatio < 1) {
|
|
59
62
|
const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
|
|
60
63
|
// Underdamped spring
|
|
@@ -5,8 +5,21 @@ import { appearStoreId } from './store-id.mjs';
|
|
|
5
5
|
function handoffOptimizedAppearAnimation(id, name, value) {
|
|
6
6
|
const { MotionAppearAnimations } = window;
|
|
7
7
|
const animationId = appearStoreId(id, transformProps.has(name) ? "transform" : name);
|
|
8
|
-
const animation = MotionAppearAnimations && MotionAppearAnimations.get(animationId)
|
|
9
|
-
|
|
8
|
+
const { animation, ready } = (MotionAppearAnimations && MotionAppearAnimations.get(animationId)) ||
|
|
9
|
+
{};
|
|
10
|
+
if (!animation)
|
|
11
|
+
return 0;
|
|
12
|
+
const cancelOptimisedAnimation = () => {
|
|
13
|
+
MotionAppearAnimations.delete(animationId);
|
|
14
|
+
/**
|
|
15
|
+
* Animation.cancel() throws so it needs to be wrapped in a try/catch
|
|
16
|
+
*/
|
|
17
|
+
try {
|
|
18
|
+
animation.cancel();
|
|
19
|
+
}
|
|
20
|
+
catch (e) { }
|
|
21
|
+
};
|
|
22
|
+
if (ready) {
|
|
10
23
|
const sampledTime = performance.now();
|
|
11
24
|
/**
|
|
12
25
|
* Resync handoff animation with optimised animation.
|
|
@@ -31,19 +44,12 @@ function handoffOptimizedAppearAnimation(id, name, value) {
|
|
|
31
44
|
* 2. As all independent transforms share a single transform animation, stopping
|
|
32
45
|
* it synchronously would prevent subsequent transforms from handing off.
|
|
33
46
|
*/
|
|
34
|
-
sync.render(
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Animation.cancel() throws so it needs to be wrapped in a try/catch
|
|
38
|
-
*/
|
|
39
|
-
try {
|
|
40
|
-
animation.cancel();
|
|
41
|
-
}
|
|
42
|
-
catch (e) { }
|
|
43
|
-
});
|
|
47
|
+
sync.render(cancelOptimisedAnimation);
|
|
48
|
+
console.log(animation.currentTime);
|
|
44
49
|
return animation.currentTime || 0;
|
|
45
50
|
}
|
|
46
51
|
else {
|
|
52
|
+
cancelOptimisedAnimation();
|
|
47
53
|
return 0;
|
|
48
54
|
}
|
|
49
55
|
}
|
|
@@ -2,14 +2,37 @@ import { appearStoreId } from './store-id.mjs';
|
|
|
2
2
|
import { animateStyle } from '../waapi/index.mjs';
|
|
3
3
|
import { optimizedAppearDataId } from './data-id.mjs';
|
|
4
4
|
|
|
5
|
-
function startOptimizedAppearAnimation(element, name, keyframes, options) {
|
|
5
|
+
function startOptimizedAppearAnimation(element, name, keyframes, options, onReady) {
|
|
6
6
|
window.MotionAppearAnimations || (window.MotionAppearAnimations = new Map());
|
|
7
7
|
const id = element.dataset[optimizedAppearDataId];
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
if (!id)
|
|
9
|
+
return;
|
|
10
|
+
const storeId = appearStoreId(id, name);
|
|
11
|
+
/**
|
|
12
|
+
* Use a dummy animation to detect when Chrome is ready to start
|
|
13
|
+
* painting the page and hold off from triggering the real animation
|
|
14
|
+
* until then.
|
|
15
|
+
*/
|
|
16
|
+
const readyAnimation = animateStyle(element, name, [keyframes[0], keyframes[0]], { duration: 1 });
|
|
17
|
+
window.MotionAppearAnimations.set(storeId, {
|
|
18
|
+
animation: readyAnimation,
|
|
19
|
+
ready: false,
|
|
20
|
+
});
|
|
21
|
+
const startAnimation = () => {
|
|
22
|
+
const animation = animateStyle(element, name, keyframes, options);
|
|
23
|
+
window.MotionAppearAnimations.set(storeId, { animation, ready: true });
|
|
24
|
+
if (onReady)
|
|
25
|
+
onReady(animation);
|
|
26
|
+
};
|
|
27
|
+
if (readyAnimation.ready) {
|
|
28
|
+
readyAnimation.ready.then(() => {
|
|
29
|
+
readyAnimation.cancel();
|
|
30
|
+
startAnimation();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
startAnimation();
|
|
11
35
|
}
|
|
12
|
-
return animation;
|
|
13
36
|
}
|
|
14
37
|
|
|
15
38
|
export { startOptimizedAppearAnimation };
|
|
@@ -35,6 +35,8 @@ const validMotionProps = new Set([
|
|
|
35
35
|
"layout",
|
|
36
36
|
"layoutId",
|
|
37
37
|
"layoutDependency",
|
|
38
|
+
"layoutScroll",
|
|
39
|
+
"layoutRoot",
|
|
38
40
|
"onLayoutAnimationStart",
|
|
39
41
|
"onLayoutAnimationComplete",
|
|
40
42
|
"onLayoutMeasure",
|
|
@@ -62,7 +64,6 @@ const validMotionProps = new Set([
|
|
|
62
64
|
"dragTransition",
|
|
63
65
|
"onHoverStart",
|
|
64
66
|
"onHoverEnd",
|
|
65
|
-
"layoutScroll",
|
|
66
67
|
...inViewProps,
|
|
67
68
|
...tapProps,
|
|
68
69
|
...animationProps,
|
|
@@ -224,7 +224,8 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
224
224
|
* relative to its parent has indeed changed. So here we check for that.
|
|
225
225
|
*/
|
|
226
226
|
const hasOnlyRelativeTargetChanged = !hasLayoutChanged && hasRelativeTargetChanged;
|
|
227
|
-
if (
|
|
227
|
+
if (this.options.layoutRoot ||
|
|
228
|
+
((_c = this.resumeFrom) === null || _c === void 0 ? void 0 : _c.instance) ||
|
|
228
229
|
hasOnlyRelativeTargetChanged ||
|
|
229
230
|
(hasLayoutChanged &&
|
|
230
231
|
(targetChanged || !this.currentAnimation))) {
|
|
@@ -238,7 +239,8 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
238
239
|
onPlay: onLayoutAnimationStart,
|
|
239
240
|
onComplete: onLayoutAnimationComplete,
|
|
240
241
|
};
|
|
241
|
-
if (visualElement.shouldReduceMotion
|
|
242
|
+
if (visualElement.shouldReduceMotion ||
|
|
243
|
+
this.options.layoutRoot) {
|
|
242
244
|
animationOptions.delay = 0;
|
|
243
245
|
animationOptions.type = false;
|
|
244
246
|
}
|
|
@@ -294,6 +296,10 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
294
296
|
(_a = this.nodes) === null || _a === void 0 ? void 0 : _a.forEach(resetRotation);
|
|
295
297
|
this.animationId++;
|
|
296
298
|
}
|
|
299
|
+
getTransformTemplate() {
|
|
300
|
+
var _a;
|
|
301
|
+
return (_a = this.options.visualElement) === null || _a === void 0 ? void 0 : _a.getProps().transformTemplate;
|
|
302
|
+
}
|
|
297
303
|
willUpdate(shouldNotifyListeners = true) {
|
|
298
304
|
var _a, _b, _c;
|
|
299
305
|
if (this.root.isUpdateBlocked()) {
|
|
@@ -308,12 +314,14 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
308
314
|
const node = this.path[i];
|
|
309
315
|
node.shouldResetTransform = true;
|
|
310
316
|
node.updateScroll("snapshot");
|
|
317
|
+
if (node.options.layoutRoot) {
|
|
318
|
+
node.willUpdate(false);
|
|
319
|
+
}
|
|
311
320
|
}
|
|
312
321
|
const { layoutId, layout } = this.options;
|
|
313
322
|
if (layoutId === undefined && !layout)
|
|
314
323
|
return;
|
|
315
|
-
|
|
316
|
-
this.prevTransformTemplateValue = transformTemplate === null || transformTemplate === void 0 ? void 0 : transformTemplate(this.latestValues, "");
|
|
324
|
+
this.prevTransformTemplateValue = (_c = this.getTransformTemplate()) === null || _c === void 0 ? void 0 : _c(this.latestValues, "");
|
|
317
325
|
this.updateSnapshot();
|
|
318
326
|
shouldNotifyListeners && this.notifyListeners("willUpdate");
|
|
319
327
|
}
|
|
@@ -445,8 +453,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
445
453
|
return;
|
|
446
454
|
const isResetRequested = this.isLayoutDirty || this.shouldResetTransform;
|
|
447
455
|
const hasProjection = this.projectionDelta && !isDeltaZero(this.projectionDelta);
|
|
448
|
-
const
|
|
449
|
-
const transformTemplateValue = transformTemplate === null || transformTemplate === void 0 ? void 0 : transformTemplate(this.latestValues, "");
|
|
456
|
+
const transformTemplateValue = (_a = this.getTransformTemplate()) === null || _a === void 0 ? void 0 : _a(this.latestValues, "");
|
|
450
457
|
const transformTemplateHasChanged = transformTemplateValue !== this.prevTransformTemplateValue;
|
|
451
458
|
if (isResetRequested &&
|
|
452
459
|
(hasProjection ||
|
|
@@ -701,9 +708,12 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
701
708
|
getClosestProjectingParent() {
|
|
702
709
|
if (!this.parent ||
|
|
703
710
|
hasScale(this.parent.latestValues) ||
|
|
704
|
-
has2DTranslate(this.parent.latestValues))
|
|
711
|
+
has2DTranslate(this.parent.latestValues)) {
|
|
705
712
|
return undefined;
|
|
706
|
-
|
|
713
|
+
}
|
|
714
|
+
if ((this.parent.relativeTarget ||
|
|
715
|
+
this.parent.targetDelta ||
|
|
716
|
+
this.parent.options.layoutRoot) &&
|
|
707
717
|
this.parent.layout) {
|
|
708
718
|
return this.parent;
|
|
709
719
|
}
|
|
@@ -798,7 +808,10 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
798
808
|
const snapshotLatestValues = (snapshot === null || snapshot === void 0 ? void 0 : snapshot.latestValues) || {};
|
|
799
809
|
const mixedValues = { ...this.latestValues };
|
|
800
810
|
const targetDelta = createDelta();
|
|
801
|
-
|
|
811
|
+
if (!this.relativeParent ||
|
|
812
|
+
!this.relativeParent.options.layoutRoot) {
|
|
813
|
+
this.relativeTarget = this.relativeTargetOrigin = undefined;
|
|
814
|
+
}
|
|
802
815
|
this.attemptToResolveRelativeTarget = !hasOnlyRelativeTargetChanged;
|
|
803
816
|
const relativeLayout = createBox();
|
|
804
817
|
const isSharedLayoutAnimation = (snapshot === null || snapshot === void 0 ? void 0 : snapshot.source) !== ((_a = this.layout) === null || _a === void 0 ? void 0 : _a.source);
|
|
@@ -829,7 +842,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
829
842
|
this.scheduleRender();
|
|
830
843
|
this.animationProgress = progress;
|
|
831
844
|
};
|
|
832
|
-
this.mixTargetDelta(0);
|
|
845
|
+
this.mixTargetDelta(this.options.layoutRoot ? 1000 : 0);
|
|
833
846
|
}
|
|
834
847
|
startAnimation(options) {
|
|
835
848
|
var _a, _b;
|
|
@@ -1019,7 +1032,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
1019
1032
|
visualElement.scheduleRender();
|
|
1020
1033
|
}
|
|
1021
1034
|
getProjectionStyles(styleProp = {}) {
|
|
1022
|
-
var _a, _b
|
|
1035
|
+
var _a, _b;
|
|
1023
1036
|
// TODO: Return lifecycle-persistent object
|
|
1024
1037
|
const styles = {};
|
|
1025
1038
|
if (!this.instance || this.isSVG)
|
|
@@ -1030,7 +1043,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
1030
1043
|
else {
|
|
1031
1044
|
styles.visibility = "";
|
|
1032
1045
|
}
|
|
1033
|
-
const transformTemplate =
|
|
1046
|
+
const transformTemplate = this.getTransformTemplate();
|
|
1034
1047
|
if (this.needsReset) {
|
|
1035
1048
|
this.needsReset = false;
|
|
1036
1049
|
styles.opacity = "";
|
|
@@ -1075,7 +1088,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
1075
1088
|
*/
|
|
1076
1089
|
styles.opacity =
|
|
1077
1090
|
lead === this
|
|
1078
|
-
? (
|
|
1091
|
+
? (_b = (_a = valuesToRender.opacity) !== null && _a !== void 0 ? _a : this.latestValues.opacity) !== null && _b !== void 0 ? _b : 1
|
|
1079
1092
|
: this.preserveOpacity
|
|
1080
1093
|
? this.latestValues.opacity
|
|
1081
1094
|
: valuesToRender.opacityExit;
|
|
@@ -1205,6 +1218,11 @@ function notifyLayoutUpdate(node) {
|
|
|
1205
1218
|
if (!boxEquals(relativeSnapshot, relativeLayout)) {
|
|
1206
1219
|
hasRelativeTargetChanged = true;
|
|
1207
1220
|
}
|
|
1221
|
+
if (relativeParent.options.layoutRoot) {
|
|
1222
|
+
node.relativeTarget = relativeLayout;
|
|
1223
|
+
node.relativeTargetOrigin = relativeSnapshot;
|
|
1224
|
+
node.relativeParent = relativeParent;
|
|
1225
|
+
}
|
|
1208
1226
|
}
|
|
1209
1227
|
}
|
|
1210
1228
|
}
|
|
@@ -238,7 +238,7 @@ class VisualElement {
|
|
|
238
238
|
}
|
|
239
239
|
if (!this.projection && ProjectionNodeConstructor) {
|
|
240
240
|
this.projection = new ProjectionNodeConstructor(projectionId, this.latestValues, this.parent && this.parent.projection);
|
|
241
|
-
const { layoutId, layout, drag, dragConstraints, layoutScroll } = renderedProps;
|
|
241
|
+
const { layoutId, layout, drag, dragConstraints, layoutScroll, layoutRoot, } = renderedProps;
|
|
242
242
|
this.projection.setOptions({
|
|
243
243
|
layoutId,
|
|
244
244
|
layout,
|
|
@@ -256,6 +256,7 @@ class VisualElement {
|
|
|
256
256
|
animationType: typeof layout === "string" ? layout : "both",
|
|
257
257
|
initialPromotionConfig: initialLayoutGroupConfig,
|
|
258
258
|
layoutScroll,
|
|
259
|
+
layoutRoot,
|
|
259
260
|
});
|
|
260
261
|
}
|
|
261
262
|
return features;
|
|
@@ -22,7 +22,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
22
22
|
* and warn against mismatches.
|
|
23
23
|
*/
|
|
24
24
|
if (process.env.NODE_ENV === "development") {
|
|
25
|
-
warnOnce(nextValue.version === "8.
|
|
25
|
+
warnOnce(nextValue.version === "8.5.2-alpha.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 8.5.2-alpha.0 may not work as expected.`);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
else if (isMotionValue(prevValue)) {
|
package/dist/es/value/index.mjs
CHANGED
|
@@ -25,7 +25,7 @@ class MotionValue {
|
|
|
25
25
|
* This will be replaced by the build step with the latest version number.
|
|
26
26
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
27
27
|
*/
|
|
28
|
-
this.version = "8.
|
|
28
|
+
this.version = "8.5.2-alpha.0";
|
|
29
29
|
/**
|
|
30
30
|
* Duration, in milliseconds, since last updating frame.
|
|
31
31
|
*
|