framer-motion 12.23.24 → 12.23.25

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 CHANGED
@@ -108,21 +108,27 @@ Motion is sustainable thanks to the kind support of its sponsors.
108
108
 
109
109
  [Become a sponsor](https://motion.dev/sponsor)
110
110
 
111
- ### Partner
111
+ ### Partners
112
112
 
113
- Motion powers Framer animations, the web builder for creative pros. Design and ship your dream site. Zero code, maximum speed.
113
+ Motion powers the animations for all websites built with Framer, the web builder for creative pros. The Motion website itself is built on Framer, for its delightful canvas-based editing and powerful CMS features.
114
114
 
115
115
  <a href="https://framer.link/FlnUbQY">
116
116
  <img alt="Framer" src="https://github.com/user-attachments/assets/22a79be7-672e-4336-bfb7-5d55d1deb917" width="250px" height="150px">
117
117
  </a>
118
118
 
119
+ Motion drives the animations on the Cursor homepage, and is working with Cursor to bring powerful AI workflows to the Motion examples and docs.
120
+
121
+ <a href="https://cursor.com">
122
+ <img alt="Cursor" src="https://github.com/user-attachments/assets/81c482d3-c2c2-4b35-bbcf-933b28d5b448" width="250px" height="150px" />
123
+ </a>
124
+
119
125
  ### Platinum
120
126
 
121
- <a href="https://linear.app"><img alt="Linear" src="https://github.com/user-attachments/assets/f9ce44b4-af28-4770-bb6e-9515b474bfb2" width="250px" height="150px"></a> <a href="https://figma.com"><img alt="Figma" src="https://github.com/user-attachments/assets/1077d0ab-4305-4a1f-81c8-d5be8c4c6717" width="250px" height="150px"></a> <a href="https://sanity.io"><img alt="Sanity" src="https://github.com/user-attachments/assets/80134088-f456-483f-8edd-940593c120ce" width="250px" height="150px"></a>
127
+ <a href="https://linear.app"><img alt="Linear" src="https://github.com/user-attachments/assets/f9ce44b4-af28-4770-bb6e-9515b474bfb2" width="250px" height="150px"></a> <a href="https://figma.com"><img alt="Figma" src="https://github.com/user-attachments/assets/1077d0ab-4305-4a1f-81c8-d5be8c4c6717" width="250px" height="150px"></a> <a href="https://sanity.io"><img alt="Sanity" src="https://github.com/user-attachments/assets/80134088-f456-483f-8edd-940593c120ce" width="250px" height="150px"></a> <a href="https://animations.dev"><img alt="Sanity" src="https://github.com/user-attachments/assets/7c5ab87d-c7d9-44b4-9c7e-f9e6a9f3ba3b" width="250px" height="150px"></a>
122
128
 
123
129
  ### Gold
124
130
 
125
- <a href="https://tailwindcss.com"><img alt="Tailwind" src="https://github.com/user-attachments/assets/1d5f2571-8bc3-4367-9fec-14d291168ff0" width="200px" height="120px"></a> <a href="https://emilkowal.ski"><img alt="Emil Kowalski" src="https://github.com/user-attachments/assets/33d1cb98-238a-4eed-a0df-9c7ab097d65b" width="200px" height="120px"></a> <a href="https://liveblocks.io"><img alt="Liveblocks" src="https://github.com/user-attachments/assets/28eddbe5-1617-4e74-969d-2eb6fcd481af" width="200px" height="120px"></a> <a href="https://lu.ma"><img alt="Luma" src="https://github.com/user-attachments/assets/ac282433-6adb-4ad2-9fd2-5c6ee513c14b" width="200px" height="120px"></a> <a href="https://notion.com"><img alt="Notion" src="https://github.com/user-attachments/assets/a27a6033-3cb0-4232-a6bb-625e1824517b" width="200px" height="120px"></a> <a href="https://lottiefiles.com"><img alt="LottieFiles" src="https://github.com/user-attachments/assets/4e99d8c7-4cba-43ee-93c5-93861ae708ec" width="200px" height="120px"></a>
131
+ <a href="https://liveblocks.io"><img alt="Liveblocks" src="https://github.com/user-attachments/assets/28eddbe5-1617-4e74-969d-2eb6fcd481af" width="200px" height="120px"></a> <a href="https://lu.ma"><img alt="Luma" src="https://github.com/user-attachments/assets/ac282433-6adb-4ad2-9fd2-5c6ee513c14b" width="200px" height="120px"></a> <a href="https://notion.com"><img alt="Notion" src="https://github.com/user-attachments/assets/a27a6033-3cb0-4232-a6bb-625e1824517b" width="200px" height="120px"></a> <a href="https://lottiefiles.com"><img alt="LottieFiles" src="https://github.com/user-attachments/assets/4e99d8c7-4cba-43ee-93c5-93861ae708ec" width="200px" height="120px"></a>
126
132
 
127
133
  ### Silver
128
134
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var featureBundle = require('./feature-bundle-v2Gb94eA.js');
5
+ var featureBundle = require('./feature-bundle-DUrrFqHS.js');
6
6
  require('react');
7
7
  require('motion-dom');
8
8
  require('motion-utils');
@@ -1042,6 +1042,7 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
1042
1042
  */
1043
1043
  this.eventHandlers = new Map();
1044
1044
  this.hasTreeAnimated = false;
1045
+ this.layoutVersion = 0;
1045
1046
  // Note: Currently only running on root node
1046
1047
  this.updateScheduled = false;
1047
1048
  this.scheduleUpdate = () => this.update();
@@ -1081,6 +1082,7 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
1081
1082
  * Frame calculations
1082
1083
  */
1083
1084
  this.resolvedRelativeTargetAt = 0.0;
1085
+ this.linkedParentVersion = 0;
1084
1086
  this.hasProjected = false;
1085
1087
  this.isVisible = true;
1086
1088
  this.animationProgress = 0;
@@ -1434,6 +1436,7 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
1434
1436
  }
1435
1437
  const prevLayout = this.layout;
1436
1438
  this.layout = this.measure(false);
1439
+ this.layoutVersion++;
1437
1440
  this.layoutCorrected = createBox();
1438
1441
  this.isLayoutDirty = false;
1439
1442
  this.projectionDelta = undefined;
@@ -1653,25 +1656,23 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
1653
1656
  if (!this.layout || !(layout || layoutId))
1654
1657
  return;
1655
1658
  this.resolvedRelativeTargetAt = motionDom.frameData.timestamp;
1659
+ const relativeParent = this.getClosestProjectingParent();
1660
+ if (relativeParent &&
1661
+ this.linkedParentVersion !== relativeParent.layoutVersion &&
1662
+ !relativeParent.options.layoutRoot) {
1663
+ this.removeRelativeTarget();
1664
+ }
1656
1665
  /**
1657
1666
  * If we don't have a targetDelta but do have a layout, we can attempt to resolve
1658
1667
  * a relativeParent. This will allow a component to perform scale correction
1659
1668
  * even if no animation has started.
1660
1669
  */
1661
1670
  if (!this.targetDelta && !this.relativeTarget) {
1662
- const relativeParent = this.getClosestProjectingParent();
1663
- if (relativeParent &&
1664
- relativeParent.layout &&
1665
- this.animationProgress !== 1) {
1666
- this.relativeParent = relativeParent;
1667
- this.forceRelativeParentToResolveTarget();
1668
- this.relativeTarget = createBox();
1669
- this.relativeTargetOrigin = createBox();
1670
- calcRelativePosition(this.relativeTargetOrigin, this.layout.layoutBox, relativeParent.layout.layoutBox);
1671
- copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
1671
+ if (relativeParent && relativeParent.layout) {
1672
+ this.createRelativeTarget(relativeParent, this.layout.layoutBox, relativeParent.layout.layoutBox);
1672
1673
  }
1673
1674
  else {
1674
- this.relativeParent = this.relativeTarget = undefined;
1675
+ this.removeRelativeTarget();
1675
1676
  }
1676
1677
  }
1677
1678
  /**
@@ -1721,19 +1722,13 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
1721
1722
  */
1722
1723
  if (this.attemptToResolveRelativeTarget) {
1723
1724
  this.attemptToResolveRelativeTarget = false;
1724
- const relativeParent = this.getClosestProjectingParent();
1725
1725
  if (relativeParent &&
1726
1726
  Boolean(relativeParent.resumingFrom) ===
1727
1727
  Boolean(this.resumingFrom) &&
1728
1728
  !relativeParent.options.layoutScroll &&
1729
1729
  relativeParent.target &&
1730
1730
  this.animationProgress !== 1) {
1731
- this.relativeParent = relativeParent;
1732
- this.forceRelativeParentToResolveTarget();
1733
- this.relativeTarget = createBox();
1734
- this.relativeTargetOrigin = createBox();
1735
- calcRelativePosition(this.relativeTargetOrigin, this.target, relativeParent.target);
1736
- copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
1731
+ this.createRelativeTarget(relativeParent, this.target, relativeParent.target);
1737
1732
  }
1738
1733
  else {
1739
1734
  this.relativeParent = this.relativeTarget = undefined;
@@ -1765,6 +1760,18 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
1765
1760
  this.options.layoutRoot) &&
1766
1761
  this.layout);
1767
1762
  }
1763
+ createRelativeTarget(relativeParent, layout, parentLayout) {
1764
+ this.relativeParent = relativeParent;
1765
+ this.linkedParentVersion = relativeParent.layoutVersion;
1766
+ this.forceRelativeParentToResolveTarget();
1767
+ this.relativeTarget = createBox();
1768
+ this.relativeTargetOrigin = createBox();
1769
+ calcRelativePosition(this.relativeTargetOrigin, layout, parentLayout);
1770
+ copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
1771
+ }
1772
+ removeRelativeTarget() {
1773
+ this.relativeParent = this.relativeTarget = undefined;
1774
+ }
1768
1775
  calcProjection() {
1769
1776
  const lead = this.getLead();
1770
1777
  const isShared = Boolean(this.resumingFrom) || this !== lead;
package/dist/cjs/index.js CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var React = require('react');
7
- var featureBundle = require('./feature-bundle-v2Gb94eA.js');
7
+ var featureBundle = require('./feature-bundle-DUrrFqHS.js');
8
8
  var motionDom = require('motion-dom');
9
9
  var motionUtils = require('motion-utils');
10
10
 
@@ -8,7 +8,7 @@ import { resolveMotionValue } from '../../value/utils/resolve-motion-value.mjs';
8
8
  import { mixValues } from '../animation/mix-values.mjs';
9
9
  import { copyBoxInto, copyAxisDeltaInto } from '../geometry/copy.mjs';
10
10
  import { translateAxis, transformBox, applyBoxDelta, applyTreeDeltas } from '../geometry/delta-apply.mjs';
11
- import { calcLength, calcRelativePosition, calcRelativeBox, calcBoxDelta, isNear } from '../geometry/delta-calc.mjs';
11
+ import { calcLength, calcRelativeBox, calcRelativePosition, calcBoxDelta, isNear } from '../geometry/delta-calc.mjs';
12
12
  import { removeBoxTransforms } from '../geometry/delta-remove.mjs';
13
13
  import { createBox, createDelta } from '../geometry/models.mjs';
14
14
  import { boxEqualsRounded, isDeltaZero, axisDeltaEquals, aspectRatio, boxEquals } from '../geometry/utils.mjs';
@@ -156,6 +156,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
156
156
  */
157
157
  this.eventHandlers = new Map();
158
158
  this.hasTreeAnimated = false;
159
+ this.layoutVersion = 0;
159
160
  // Note: Currently only running on root node
160
161
  this.updateScheduled = false;
161
162
  this.scheduleUpdate = () => this.update();
@@ -195,6 +196,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
195
196
  * Frame calculations
196
197
  */
197
198
  this.resolvedRelativeTargetAt = 0.0;
199
+ this.linkedParentVersion = 0;
198
200
  this.hasProjected = false;
199
201
  this.isVisible = true;
200
202
  this.animationProgress = 0;
@@ -548,6 +550,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
548
550
  }
549
551
  const prevLayout = this.layout;
550
552
  this.layout = this.measure(false);
553
+ this.layoutVersion++;
551
554
  this.layoutCorrected = createBox();
552
555
  this.isLayoutDirty = false;
553
556
  this.projectionDelta = undefined;
@@ -767,25 +770,23 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
767
770
  if (!this.layout || !(layout || layoutId))
768
771
  return;
769
772
  this.resolvedRelativeTargetAt = frameData.timestamp;
773
+ const relativeParent = this.getClosestProjectingParent();
774
+ if (relativeParent &&
775
+ this.linkedParentVersion !== relativeParent.layoutVersion &&
776
+ !relativeParent.options.layoutRoot) {
777
+ this.removeRelativeTarget();
778
+ }
770
779
  /**
771
780
  * If we don't have a targetDelta but do have a layout, we can attempt to resolve
772
781
  * a relativeParent. This will allow a component to perform scale correction
773
782
  * even if no animation has started.
774
783
  */
775
784
  if (!this.targetDelta && !this.relativeTarget) {
776
- const relativeParent = this.getClosestProjectingParent();
777
- if (relativeParent &&
778
- relativeParent.layout &&
779
- this.animationProgress !== 1) {
780
- this.relativeParent = relativeParent;
781
- this.forceRelativeParentToResolveTarget();
782
- this.relativeTarget = createBox();
783
- this.relativeTargetOrigin = createBox();
784
- calcRelativePosition(this.relativeTargetOrigin, this.layout.layoutBox, relativeParent.layout.layoutBox);
785
- copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
785
+ if (relativeParent && relativeParent.layout) {
786
+ this.createRelativeTarget(relativeParent, this.layout.layoutBox, relativeParent.layout.layoutBox);
786
787
  }
787
788
  else {
788
- this.relativeParent = this.relativeTarget = undefined;
789
+ this.removeRelativeTarget();
789
790
  }
790
791
  }
791
792
  /**
@@ -835,19 +836,13 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
835
836
  */
836
837
  if (this.attemptToResolveRelativeTarget) {
837
838
  this.attemptToResolveRelativeTarget = false;
838
- const relativeParent = this.getClosestProjectingParent();
839
839
  if (relativeParent &&
840
840
  Boolean(relativeParent.resumingFrom) ===
841
841
  Boolean(this.resumingFrom) &&
842
842
  !relativeParent.options.layoutScroll &&
843
843
  relativeParent.target &&
844
844
  this.animationProgress !== 1) {
845
- this.relativeParent = relativeParent;
846
- this.forceRelativeParentToResolveTarget();
847
- this.relativeTarget = createBox();
848
- this.relativeTargetOrigin = createBox();
849
- calcRelativePosition(this.relativeTargetOrigin, this.target, relativeParent.target);
850
- copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
845
+ this.createRelativeTarget(relativeParent, this.target, relativeParent.target);
851
846
  }
852
847
  else {
853
848
  this.relativeParent = this.relativeTarget = undefined;
@@ -879,6 +874,18 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
879
874
  this.options.layoutRoot) &&
880
875
  this.layout);
881
876
  }
877
+ createRelativeTarget(relativeParent, layout, parentLayout) {
878
+ this.relativeParent = relativeParent;
879
+ this.linkedParentVersion = relativeParent.layoutVersion;
880
+ this.forceRelativeParentToResolveTarget();
881
+ this.relativeTarget = createBox();
882
+ this.relativeTargetOrigin = createBox();
883
+ calcRelativePosition(this.relativeTargetOrigin, layout, parentLayout);
884
+ copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
885
+ }
886
+ removeRelativeTarget() {
887
+ this.relativeParent = this.relativeTarget = undefined;
888
+ }
882
889
  calcProjection() {
883
890
  const lead = this.getLead();
884
891
  const isShared = Boolean(this.resumingFrom) || this !== lead;
@@ -6445,6 +6445,7 @@
6445
6445
  */
6446
6446
  this.eventHandlers = new Map();
6447
6447
  this.hasTreeAnimated = false;
6448
+ this.layoutVersion = 0;
6448
6449
  // Note: Currently only running on root node
6449
6450
  this.updateScheduled = false;
6450
6451
  this.scheduleUpdate = () => this.update();
@@ -6484,6 +6485,7 @@
6484
6485
  * Frame calculations
6485
6486
  */
6486
6487
  this.resolvedRelativeTargetAt = 0.0;
6488
+ this.linkedParentVersion = 0;
6487
6489
  this.hasProjected = false;
6488
6490
  this.isVisible = true;
6489
6491
  this.animationProgress = 0;
@@ -6837,6 +6839,7 @@
6837
6839
  }
6838
6840
  const prevLayout = this.layout;
6839
6841
  this.layout = this.measure(false);
6842
+ this.layoutVersion++;
6840
6843
  this.layoutCorrected = createBox();
6841
6844
  this.isLayoutDirty = false;
6842
6845
  this.projectionDelta = undefined;
@@ -7056,25 +7059,23 @@
7056
7059
  if (!this.layout || !(layout || layoutId))
7057
7060
  return;
7058
7061
  this.resolvedRelativeTargetAt = frameData.timestamp;
7062
+ const relativeParent = this.getClosestProjectingParent();
7063
+ if (relativeParent &&
7064
+ this.linkedParentVersion !== relativeParent.layoutVersion &&
7065
+ !relativeParent.options.layoutRoot) {
7066
+ this.removeRelativeTarget();
7067
+ }
7059
7068
  /**
7060
7069
  * If we don't have a targetDelta but do have a layout, we can attempt to resolve
7061
7070
  * a relativeParent. This will allow a component to perform scale correction
7062
7071
  * even if no animation has started.
7063
7072
  */
7064
7073
  if (!this.targetDelta && !this.relativeTarget) {
7065
- const relativeParent = this.getClosestProjectingParent();
7066
- if (relativeParent &&
7067
- relativeParent.layout &&
7068
- this.animationProgress !== 1) {
7069
- this.relativeParent = relativeParent;
7070
- this.forceRelativeParentToResolveTarget();
7071
- this.relativeTarget = createBox();
7072
- this.relativeTargetOrigin = createBox();
7073
- calcRelativePosition(this.relativeTargetOrigin, this.layout.layoutBox, relativeParent.layout.layoutBox);
7074
- copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
7074
+ if (relativeParent && relativeParent.layout) {
7075
+ this.createRelativeTarget(relativeParent, this.layout.layoutBox, relativeParent.layout.layoutBox);
7075
7076
  }
7076
7077
  else {
7077
- this.relativeParent = this.relativeTarget = undefined;
7078
+ this.removeRelativeTarget();
7078
7079
  }
7079
7080
  }
7080
7081
  /**
@@ -7124,19 +7125,13 @@
7124
7125
  */
7125
7126
  if (this.attemptToResolveRelativeTarget) {
7126
7127
  this.attemptToResolveRelativeTarget = false;
7127
- const relativeParent = this.getClosestProjectingParent();
7128
7128
  if (relativeParent &&
7129
7129
  Boolean(relativeParent.resumingFrom) ===
7130
7130
  Boolean(this.resumingFrom) &&
7131
7131
  !relativeParent.options.layoutScroll &&
7132
7132
  relativeParent.target &&
7133
7133
  this.animationProgress !== 1) {
7134
- this.relativeParent = relativeParent;
7135
- this.forceRelativeParentToResolveTarget();
7136
- this.relativeTarget = createBox();
7137
- this.relativeTargetOrigin = createBox();
7138
- calcRelativePosition(this.relativeTargetOrigin, this.target, relativeParent.target);
7139
- copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
7134
+ this.createRelativeTarget(relativeParent, this.target, relativeParent.target);
7140
7135
  }
7141
7136
  else {
7142
7137
  this.relativeParent = this.relativeTarget = undefined;
@@ -7168,6 +7163,18 @@
7168
7163
  this.options.layoutRoot) &&
7169
7164
  this.layout);
7170
7165
  }
7166
+ createRelativeTarget(relativeParent, layout, parentLayout) {
7167
+ this.relativeParent = relativeParent;
7168
+ this.linkedParentVersion = relativeParent.layoutVersion;
7169
+ this.forceRelativeParentToResolveTarget();
7170
+ this.relativeTarget = createBox();
7171
+ this.relativeTargetOrigin = createBox();
7172
+ calcRelativePosition(this.relativeTargetOrigin, layout, parentLayout);
7173
+ copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
7174
+ }
7175
+ removeRelativeTarget() {
7176
+ this.relativeParent = this.relativeTarget = undefined;
7177
+ }
7171
7178
  calcProjection() {
7172
7179
  const lead = this.getLead();
7173
7180
  const isShared = Boolean(this.resumingFrom) || this !== lead;