framer-motion 12.8.0 → 12.9.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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var create = require('./create-Bv1Fn_mR.js');
5
+ var create = require('./create-BMX8oz9O.js');
6
6
  require('motion-dom');
7
7
  require('motion-utils');
8
8
  require('react/jsx-runtime');
@@ -2720,7 +2720,7 @@ function updateMotionValuesFromProps(element, next, prev) {
2720
2720
  * and warn against mismatches.
2721
2721
  */
2722
2722
  if (process.env.NODE_ENV === "development") {
2723
- motionUtils.warnOnce(nextValue.version === "12.8.0", `Attempting to mix Motion versions ${nextValue.version} with 12.8.0 may not work as expected.`);
2723
+ motionUtils.warnOnce(nextValue.version === "12.9.0", `Attempting to mix Motion versions ${nextValue.version} with 12.9.0 may not work as expected.`);
2724
2724
  }
2725
2725
  }
2726
2726
  else if (isMotionValue(prevValue)) {
@@ -2888,8 +2888,7 @@ class VisualElement {
2888
2888
  motionDom.frame.render(this.render, false, true);
2889
2889
  }
2890
2890
  };
2891
- const { latestValues, renderState, onUpdate } = visualState;
2892
- this.onUpdate = onUpdate;
2891
+ const { latestValues, renderState } = visualState;
2893
2892
  this.latestValues = latestValues;
2894
2893
  this.baseTarget = { ...latestValues };
2895
2894
  this.initialValues = props.initial ? { ...latestValues } : {};
@@ -3091,7 +3090,6 @@ class VisualElement {
3091
3090
  if (this.handleChildMotionValue) {
3092
3091
  this.handleChildMotionValue();
3093
3092
  }
3094
- this.onUpdate && this.onUpdate(this);
3095
3093
  }
3096
3094
  getProps() {
3097
3095
  return this.props;
@@ -3675,6 +3673,17 @@ function animateTarget(visualElement, targetAndTransition, { delay = 0, transiti
3675
3673
  delay,
3676
3674
  ...motionDom.getValueTransition(transition || {}, key),
3677
3675
  };
3676
+ /**
3677
+ * If the value is already at the defined target, skip the animation.
3678
+ */
3679
+ const currentValue = value.get();
3680
+ if (currentValue !== undefined &&
3681
+ !value.isAnimating &&
3682
+ !Array.isArray(valueTarget) &&
3683
+ valueTarget === currentValue &&
3684
+ !valueTransition.velocity) {
3685
+ continue;
3686
+ }
3678
3687
  /**
3679
3688
  * If this is the first time a value is being animated, check
3680
3689
  * to see if we're handling off from an existing animation.
@@ -4497,7 +4506,7 @@ function calcViewportConstraints(layoutBox, constraintsBox) {
4497
4506
  * Calculate a transform origin relative to the source axis, between 0-1, that results
4498
4507
  * in an asthetically pleasing scale/transform needed to project from source to target.
4499
4508
  */
4500
- function calcOrigin$1(source, target) {
4509
+ function calcOrigin(source, target) {
4501
4510
  let origin = 0.5;
4502
4511
  const sourceLength = calcLength(source);
4503
4512
  const targetLength = calcLength(target);
@@ -4891,7 +4900,7 @@ class VisualElementDragControls {
4891
4900
  const axisValue = this.getAxisMotionValue(axis);
4892
4901
  if (axisValue && this.constraints !== false) {
4893
4902
  const latest = axisValue.get();
4894
- boxProgress[axis] = calcOrigin$1({ min: latest, max: latest }, this.constraints[axis]);
4903
+ boxProgress[axis] = calcOrigin({ min: latest, max: latest }, this.constraints[axis]);
4895
4904
  }
4896
4905
  });
4897
4906
  /**
@@ -5843,25 +5852,10 @@ function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true
5843
5852
  attrs[keys.array] = `${pathLength} ${pathSpacing}`;
5844
5853
  }
5845
5854
 
5846
- function calcOrigin(origin, offset, size) {
5847
- return typeof origin === "string"
5848
- ? origin
5849
- : motionDom.px.transform(offset + size * origin);
5850
- }
5851
- /**
5852
- * The SVG transform origin defaults are different to CSS and is less intuitive,
5853
- * so we use the measured dimensions of the SVG to reconcile these.
5854
- */
5855
- function calcSVGTransformOrigin(dimensions, originX, originY) {
5856
- const pxOriginX = calcOrigin(originX, dimensions.x, dimensions.width);
5857
- const pxOriginY = calcOrigin(originY, dimensions.y, dimensions.height);
5858
- return `${pxOriginX} ${pxOriginY}`;
5859
- }
5860
-
5861
5855
  /**
5862
5856
  * Build SVG visual attrbutes, like cx and style.transform
5863
5857
  */
5864
- function buildSVGAttrs(state, { attrX, attrY, attrScale, originX, originY, pathLength, pathSpacing = 1, pathOffset = 0,
5858
+ function buildSVGAttrs(state, { attrX, attrY, attrScale, pathLength, pathSpacing = 1, pathOffset = 0,
5865
5859
  // This is object creation, which we try to avoid per-frame.
5866
5860
  ...latest }, isSVGTag, transformTemplate) {
5867
5861
  buildHTMLStyles(state, latest, transformTemplate);
@@ -5877,20 +5871,26 @@ function buildSVGAttrs(state, { attrX, attrY, attrScale, originX, originY, pathL
5877
5871
  }
5878
5872
  state.attrs = state.style;
5879
5873
  state.style = {};
5880
- const { attrs, style, dimensions } = state;
5874
+ const { attrs, style } = state;
5881
5875
  /**
5882
- * However, we apply transforms as CSS transforms. So if we detect a transform we take it from attrs
5883
- * and copy it into style.
5876
+ * However, we apply transforms as CSS transforms.
5877
+ * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.
5884
5878
  */
5885
5879
  if (attrs.transform) {
5886
- if (dimensions)
5887
- style.transform = attrs.transform;
5880
+ style.transform = attrs.transform;
5888
5881
  delete attrs.transform;
5889
5882
  }
5890
- // Parse transformOrigin
5891
- if (dimensions &&
5892
- (originX !== undefined || originY !== undefined || style.transform)) {
5893
- style.transformOrigin = calcSVGTransformOrigin(dimensions, originX !== undefined ? originX : 0.5, originY !== undefined ? originY : 0.5);
5883
+ if (style.transform || attrs.transformOrigin) {
5884
+ style.transformOrigin = attrs.transformOrigin ?? "50% 50%";
5885
+ delete attrs.transformOrigin;
5886
+ }
5887
+ if (style.transform) {
5888
+ /**
5889
+ * SVG's element transform-origin uses its own median as a reference.
5890
+ * Therefore, transformBox becomes a fill-box
5891
+ */
5892
+ style.transformBox = "fill-box";
5893
+ delete attrs.transformBox;
5894
5894
  }
5895
5895
  // Render attrX/attrY/attrScale as attributes
5896
5896
  if (attrX !== undefined)
@@ -5954,20 +5954,11 @@ function createUseRender(forwardMotionProps = false) {
5954
5954
  return useRender;
5955
5955
  }
5956
5956
 
5957
- function makeState({ scrapeMotionValuesFromProps, createRenderState, onUpdate, }, props, context, presenceContext) {
5957
+ function makeState({ scrapeMotionValuesFromProps, createRenderState, }, props, context, presenceContext) {
5958
5958
  const state = {
5959
5959
  latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps),
5960
5960
  renderState: createRenderState(),
5961
5961
  };
5962
- if (onUpdate) {
5963
- /**
5964
- * onMount works without the VisualElement because it could be
5965
- * called before the VisualElement payload has been hydrated.
5966
- * (e.g. if someone is using m components <m.circle />)
5967
- */
5968
- state.onMount = (instance) => onUpdate({ props, current: instance, ...state });
5969
- state.onUpdate = (visualElement) => onUpdate(visualElement);
5970
- }
5971
5962
  return state;
5972
5963
  }
5973
5964
  const makeUseVisualState = (config) => (props, isStatic) => {
@@ -6039,22 +6030,41 @@ const htmlMotionConfig = {
6039
6030
  }),
6040
6031
  };
6041
6032
 
6042
- function updateSVGDimensions(instance, renderState) {
6043
- try {
6044
- renderState.dimensions =
6045
- typeof instance.getBBox === "function"
6046
- ? instance.getBBox()
6047
- : instance.getBoundingClientRect();
6048
- }
6049
- catch (e) {
6050
- // Most likely trying to measure an unrendered element under Firefox
6051
- renderState.dimensions = {
6052
- x: 0,
6053
- y: 0,
6054
- width: 0,
6055
- height: 0,
6056
- };
6033
+ function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
6034
+ const newValues = scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
6035
+ for (const key in props) {
6036
+ if (isMotionValue(props[key]) ||
6037
+ isMotionValue(prevProps[key])) {
6038
+ const targetKey = motionDom.transformPropOrder.indexOf(key) !== -1
6039
+ ? "attr" + key.charAt(0).toUpperCase() + key.substring(1)
6040
+ : key;
6041
+ newValues[targetKey] = props[key];
6042
+ }
6057
6043
  }
6044
+ return newValues;
6045
+ }
6046
+
6047
+ const svgMotionConfig = {
6048
+ useVisualState: makeUseVisualState({
6049
+ scrapeMotionValuesFromProps: scrapeMotionValuesFromProps,
6050
+ createRenderState: createSvgRenderState,
6051
+ }),
6052
+ };
6053
+
6054
+ function createMotionComponentFactory(preloadedFeatures, createVisualElement) {
6055
+ return function createMotionComponent(Component, { forwardMotionProps } = { forwardMotionProps: false }) {
6056
+ const baseConfig = isSVGComponent(Component)
6057
+ ? svgMotionConfig
6058
+ : htmlMotionConfig;
6059
+ const config = {
6060
+ ...baseConfig,
6061
+ preloadedFeatures,
6062
+ useRender: createUseRender(forwardMotionProps),
6063
+ createVisualElement,
6064
+ Component,
6065
+ };
6066
+ return createRendererMotionComponent(config);
6067
+ };
6058
6068
  }
6059
6069
 
6060
6070
  /**
@@ -6093,93 +6103,12 @@ function renderSVG(element, renderState, _styleProp, projection) {
6093
6103
  }
6094
6104
  }
6095
6105
 
6096
- function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
6097
- const newValues = scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
6098
- for (const key in props) {
6099
- if (isMotionValue(props[key]) ||
6100
- isMotionValue(prevProps[key])) {
6101
- const targetKey = motionDom.transformPropOrder.indexOf(key) !== -1
6102
- ? "attr" + key.charAt(0).toUpperCase() + key.substring(1)
6103
- : key;
6104
- newValues[targetKey] = props[key];
6105
- }
6106
- }
6107
- return newValues;
6108
- }
6109
-
6110
- const layoutProps = ["x", "y", "width", "height", "cx", "cy", "r"];
6111
- const svgMotionConfig = {
6112
- useVisualState: makeUseVisualState({
6113
- scrapeMotionValuesFromProps: scrapeMotionValuesFromProps,
6114
- createRenderState: createSvgRenderState,
6115
- onUpdate: ({ props, prevProps, current, renderState, latestValues, }) => {
6116
- if (!current)
6117
- return;
6118
- let hasTransform = !!props.drag;
6119
- if (!hasTransform) {
6120
- for (const key in latestValues) {
6121
- if (motionDom.transformProps.has(key)) {
6122
- hasTransform = true;
6123
- break;
6124
- }
6125
- }
6126
- }
6127
- if (!hasTransform)
6128
- return;
6129
- let needsMeasure = !prevProps;
6130
- if (prevProps) {
6131
- /**
6132
- * Check the layout props for changes, if any are found we need to
6133
- * measure the element again.
6134
- */
6135
- for (let i = 0; i < layoutProps.length; i++) {
6136
- const key = layoutProps[i];
6137
- if (props[key] !==
6138
- prevProps[key]) {
6139
- needsMeasure = true;
6140
- }
6141
- }
6142
- }
6143
- if (!needsMeasure)
6144
- return;
6145
- motionDom.frame.read(() => {
6146
- updateSVGDimensions(current, renderState);
6147
- motionDom.frame.render(() => {
6148
- buildSVGAttrs(renderState, latestValues, isSVGTag(current.tagName), props.transformTemplate);
6149
- renderSVG(current, renderState);
6150
- });
6151
- });
6152
- },
6153
- }),
6154
- };
6155
-
6156
- function createMotionComponentFactory(preloadedFeatures, createVisualElement) {
6157
- return function createMotionComponent(Component, { forwardMotionProps } = { forwardMotionProps: false }) {
6158
- const baseConfig = isSVGComponent(Component)
6159
- ? svgMotionConfig
6160
- : htmlMotionConfig;
6161
- const config = {
6162
- ...baseConfig,
6163
- preloadedFeatures,
6164
- useRender: createUseRender(forwardMotionProps),
6165
- createVisualElement,
6166
- Component,
6167
- };
6168
- return createRendererMotionComponent(config);
6169
- };
6170
- }
6171
-
6172
6106
  class SVGVisualElement extends DOMVisualElement {
6173
6107
  constructor() {
6174
6108
  super(...arguments);
6175
6109
  this.type = "svg";
6176
6110
  this.isSVGTag = false;
6177
6111
  this.measureInstanceViewportBox = createBox;
6178
- this.updateDimensions = () => {
6179
- if (this.current && !this.renderState.dimensions) {
6180
- updateSVGDimensions(this.current, this.renderState);
6181
- }
6182
- };
6183
6112
  }
6184
6113
  getBaseTargetFromProps(props, key) {
6185
6114
  return props[key];
@@ -6195,11 +6124,6 @@ class SVGVisualElement extends DOMVisualElement {
6195
6124
  scrapeMotionValuesFromProps(props, prevProps, visualElement) {
6196
6125
  return scrapeMotionValuesFromProps(props, prevProps, visualElement);
6197
6126
  }
6198
- onBindTransform() {
6199
- if (this.current && !this.renderState.dimensions) {
6200
- motionDom.frame.postRender(this.updateDimensions);
6201
- }
6202
- }
6203
6127
  build(renderState, latestValues, props) {
6204
6128
  buildSVGAttrs(renderState, latestValues, this.isSVGTag, props.transformTemplate);
6205
6129
  }
package/dist/cjs/dom.js CHANGED
@@ -620,6 +620,17 @@ function animateTarget(visualElement, targetAndTransition, { delay = 0, transiti
620
620
  delay,
621
621
  ...motionDom.getValueTransition(transition || {}, key),
622
622
  };
623
+ /**
624
+ * If the value is already at the defined target, skip the animation.
625
+ */
626
+ const currentValue = value.get();
627
+ if (currentValue !== undefined &&
628
+ !value.isAnimating &&
629
+ !Array.isArray(valueTarget) &&
630
+ valueTarget === currentValue &&
631
+ !valueTransition.velocity) {
632
+ continue;
633
+ }
623
634
  /**
624
635
  * If this is the first time a value is being animated, check
625
636
  * to see if we're handling off from an existing animation.
@@ -759,7 +770,7 @@ function updateMotionValuesFromProps(element, next, prev) {
759
770
  * and warn against mismatches.
760
771
  */
761
772
  if (process.env.NODE_ENV === "development") {
762
- motionUtils.warnOnce(nextValue.version === "12.8.0", `Attempting to mix Motion versions ${nextValue.version} with 12.8.0 may not work as expected.`);
773
+ motionUtils.warnOnce(nextValue.version === "12.9.0", `Attempting to mix Motion versions ${nextValue.version} with 12.9.0 may not work as expected.`);
763
774
  }
764
775
  }
765
776
  else if (isMotionValue(prevValue)) {
@@ -892,8 +903,7 @@ class VisualElement {
892
903
  motionDom.frame.render(this.render, false, true);
893
904
  }
894
905
  };
895
- const { latestValues, renderState, onUpdate } = visualState;
896
- this.onUpdate = onUpdate;
906
+ const { latestValues, renderState } = visualState;
897
907
  this.latestValues = latestValues;
898
908
  this.baseTarget = { ...latestValues };
899
909
  this.initialValues = props.initial ? { ...latestValues } : {};
@@ -1095,7 +1105,6 @@ class VisualElement {
1095
1105
  if (this.handleChildMotionValue) {
1096
1106
  this.handleChildMotionValue();
1097
1107
  }
1098
- this.onUpdate && this.onUpdate(this);
1099
1108
  }
1100
1109
  getProps() {
1101
1110
  return this.props;
@@ -1437,25 +1446,10 @@ function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true
1437
1446
  attrs[keys.array] = `${pathLength} ${pathSpacing}`;
1438
1447
  }
1439
1448
 
1440
- function calcOrigin(origin, offset, size) {
1441
- return typeof origin === "string"
1442
- ? origin
1443
- : motionDom.px.transform(offset + size * origin);
1444
- }
1445
- /**
1446
- * The SVG transform origin defaults are different to CSS and is less intuitive,
1447
- * so we use the measured dimensions of the SVG to reconcile these.
1448
- */
1449
- function calcSVGTransformOrigin(dimensions, originX, originY) {
1450
- const pxOriginX = calcOrigin(originX, dimensions.x, dimensions.width);
1451
- const pxOriginY = calcOrigin(originY, dimensions.y, dimensions.height);
1452
- return `${pxOriginX} ${pxOriginY}`;
1453
- }
1454
-
1455
1449
  /**
1456
1450
  * Build SVG visual attrbutes, like cx and style.transform
1457
1451
  */
1458
- function buildSVGAttrs(state, { attrX, attrY, attrScale, originX, originY, pathLength, pathSpacing = 1, pathOffset = 0,
1452
+ function buildSVGAttrs(state, { attrX, attrY, attrScale, pathLength, pathSpacing = 1, pathOffset = 0,
1459
1453
  // This is object creation, which we try to avoid per-frame.
1460
1454
  ...latest }, isSVGTag, transformTemplate) {
1461
1455
  buildHTMLStyles(state, latest, transformTemplate);
@@ -1471,20 +1465,26 @@ function buildSVGAttrs(state, { attrX, attrY, attrScale, originX, originY, pathL
1471
1465
  }
1472
1466
  state.attrs = state.style;
1473
1467
  state.style = {};
1474
- const { attrs, style, dimensions } = state;
1468
+ const { attrs, style } = state;
1475
1469
  /**
1476
- * However, we apply transforms as CSS transforms. So if we detect a transform we take it from attrs
1477
- * and copy it into style.
1470
+ * However, we apply transforms as CSS transforms.
1471
+ * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.
1478
1472
  */
1479
1473
  if (attrs.transform) {
1480
- if (dimensions)
1481
- style.transform = attrs.transform;
1474
+ style.transform = attrs.transform;
1482
1475
  delete attrs.transform;
1483
1476
  }
1484
- // Parse transformOrigin
1485
- if (dimensions &&
1486
- (originX !== undefined || originY !== undefined || style.transform)) {
1487
- style.transformOrigin = calcSVGTransformOrigin(dimensions, originX !== undefined ? originX : 0.5, originY !== undefined ? originY : 0.5);
1477
+ if (style.transform || attrs.transformOrigin) {
1478
+ style.transformOrigin = attrs.transformOrigin ?? "50% 50%";
1479
+ delete attrs.transformOrigin;
1480
+ }
1481
+ if (style.transform) {
1482
+ /**
1483
+ * SVG's element transform-origin uses its own median as a reference.
1484
+ * Therefore, transformBox becomes a fill-box
1485
+ */
1486
+ style.transformBox = "fill-box";
1487
+ delete attrs.transformBox;
1488
1488
  }
1489
1489
  // Render attrX/attrY/attrScale as attributes
1490
1490
  if (attrX !== undefined)
@@ -1530,24 +1530,6 @@ const camelCaseAttributes = new Set([
1530
1530
 
1531
1531
  const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
1532
1532
 
1533
- function updateSVGDimensions(instance, renderState) {
1534
- try {
1535
- renderState.dimensions =
1536
- typeof instance.getBBox === "function"
1537
- ? instance.getBBox()
1538
- : instance.getBoundingClientRect();
1539
- }
1540
- catch (e) {
1541
- // Most likely trying to measure an unrendered element under Firefox
1542
- renderState.dimensions = {
1543
- x: 0,
1544
- y: 0,
1545
- width: 0,
1546
- height: 0,
1547
- };
1548
- }
1549
- }
1550
-
1551
1533
  function renderHTML(element, { style, vars }, styleProp, projection) {
1552
1534
  Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
1553
1535
  // Loop over any CSS variables and assign those.
@@ -1607,11 +1589,6 @@ class SVGVisualElement extends DOMVisualElement {
1607
1589
  this.type = "svg";
1608
1590
  this.isSVGTag = false;
1609
1591
  this.measureInstanceViewportBox = createBox;
1610
- this.updateDimensions = () => {
1611
- if (this.current && !this.renderState.dimensions) {
1612
- updateSVGDimensions(this.current, this.renderState);
1613
- }
1614
- };
1615
1592
  }
1616
1593
  getBaseTargetFromProps(props, key) {
1617
1594
  return props[key];
@@ -1627,11 +1604,6 @@ class SVGVisualElement extends DOMVisualElement {
1627
1604
  scrapeMotionValuesFromProps(props, prevProps, visualElement) {
1628
1605
  return scrapeMotionValuesFromProps(props, prevProps, visualElement);
1629
1606
  }
1630
- onBindTransform() {
1631
- if (this.current && !this.renderState.dimensions) {
1632
- motionDom.frame.postRender(this.updateDimensions);
1633
- }
1634
- }
1635
1607
  build(renderState, latestValues, props) {
1636
1608
  buildSVGAttrs(renderState, latestValues, this.isSVGTag, props.transformTemplate);
1637
1609
  }
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 create = require('./create-Bv1Fn_mR.js');
7
+ var create = require('./create-BMX8oz9O.js');
8
8
  var motionDom = require('motion-dom');
9
9
  var motionUtils = require('motion-utils');
10
10
 
package/dist/cjs/m.js CHANGED
@@ -764,25 +764,10 @@ function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true
764
764
  attrs[keys.array] = `${pathLength} ${pathSpacing}`;
765
765
  }
766
766
 
767
- function calcOrigin(origin, offset, size) {
768
- return typeof origin === "string"
769
- ? origin
770
- : motionDom.px.transform(offset + size * origin);
771
- }
772
- /**
773
- * The SVG transform origin defaults are different to CSS and is less intuitive,
774
- * so we use the measured dimensions of the SVG to reconcile these.
775
- */
776
- function calcSVGTransformOrigin(dimensions, originX, originY) {
777
- const pxOriginX = calcOrigin(originX, dimensions.x, dimensions.width);
778
- const pxOriginY = calcOrigin(originY, dimensions.y, dimensions.height);
779
- return `${pxOriginX} ${pxOriginY}`;
780
- }
781
-
782
767
  /**
783
768
  * Build SVG visual attrbutes, like cx and style.transform
784
769
  */
785
- function buildSVGAttrs(state, { attrX, attrY, attrScale, originX, originY, pathLength, pathSpacing = 1, pathOffset = 0,
770
+ function buildSVGAttrs(state, { attrX, attrY, attrScale, pathLength, pathSpacing = 1, pathOffset = 0,
786
771
  // This is object creation, which we try to avoid per-frame.
787
772
  ...latest }, isSVGTag, transformTemplate) {
788
773
  buildHTMLStyles(state, latest, transformTemplate);
@@ -798,20 +783,26 @@ function buildSVGAttrs(state, { attrX, attrY, attrScale, originX, originY, pathL
798
783
  }
799
784
  state.attrs = state.style;
800
785
  state.style = {};
801
- const { attrs, style, dimensions } = state;
786
+ const { attrs, style } = state;
802
787
  /**
803
- * However, we apply transforms as CSS transforms. So if we detect a transform we take it from attrs
804
- * and copy it into style.
788
+ * However, we apply transforms as CSS transforms.
789
+ * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.
805
790
  */
806
791
  if (attrs.transform) {
807
- if (dimensions)
808
- style.transform = attrs.transform;
792
+ style.transform = attrs.transform;
809
793
  delete attrs.transform;
810
794
  }
811
- // Parse transformOrigin
812
- if (dimensions &&
813
- (originX !== undefined || originY !== undefined || style.transform)) {
814
- style.transformOrigin = calcSVGTransformOrigin(dimensions, originX !== undefined ? originX : 0.5, originY !== undefined ? originY : 0.5);
795
+ if (style.transform || attrs.transformOrigin) {
796
+ style.transformOrigin = attrs.transformOrigin ?? "50% 50%";
797
+ delete attrs.transformOrigin;
798
+ }
799
+ if (style.transform) {
800
+ /**
801
+ * SVG's element transform-origin uses its own median as a reference.
802
+ * Therefore, transformBox becomes a fill-box
803
+ */
804
+ style.transformBox = "fill-box";
805
+ delete attrs.transformBox;
815
806
  }
816
807
  // Render attrX/attrY/attrScale as attributes
817
808
  if (attrX !== undefined)
@@ -934,20 +925,11 @@ function resolveMotionValue(value) {
934
925
  return isMotionValue(value) ? value.get() : value;
935
926
  }
936
927
 
937
- function makeState({ scrapeMotionValuesFromProps, createRenderState, onUpdate, }, props, context, presenceContext) {
928
+ function makeState({ scrapeMotionValuesFromProps, createRenderState, }, props, context, presenceContext) {
938
929
  const state = {
939
930
  latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps),
940
931
  renderState: createRenderState(),
941
932
  };
942
- if (onUpdate) {
943
- /**
944
- * onMount works without the VisualElement because it could be
945
- * called before the VisualElement payload has been hydrated.
946
- * (e.g. if someone is using m components <m.circle />)
947
- */
948
- state.onMount = (instance) => onUpdate({ props, current: instance, ...state });
949
- state.onUpdate = (visualElement) => onUpdate(visualElement);
950
- }
951
933
  return state;
952
934
  }
953
935
  const makeUseVisualState = (config) => (props, isStatic) => {
@@ -1034,68 +1016,6 @@ const htmlMotionConfig = {
1034
1016
  }),
1035
1017
  };
1036
1018
 
1037
- function updateSVGDimensions(instance, renderState) {
1038
- try {
1039
- renderState.dimensions =
1040
- typeof instance.getBBox === "function"
1041
- ? instance.getBBox()
1042
- : instance.getBoundingClientRect();
1043
- }
1044
- catch (e) {
1045
- // Most likely trying to measure an unrendered element under Firefox
1046
- renderState.dimensions = {
1047
- x: 0,
1048
- y: 0,
1049
- width: 0,
1050
- height: 0,
1051
- };
1052
- }
1053
- }
1054
-
1055
- function renderHTML(element, { style, vars }, styleProp, projection) {
1056
- Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
1057
- // Loop over any CSS variables and assign those.
1058
- for (const key in vars) {
1059
- element.style.setProperty(key, vars[key]);
1060
- }
1061
- }
1062
-
1063
- /**
1064
- * A set of attribute names that are always read/written as camel case.
1065
- */
1066
- const camelCaseAttributes = new Set([
1067
- "baseFrequency",
1068
- "diffuseConstant",
1069
- "kernelMatrix",
1070
- "kernelUnitLength",
1071
- "keySplines",
1072
- "keyTimes",
1073
- "limitingConeAngle",
1074
- "markerHeight",
1075
- "markerWidth",
1076
- "numOctaves",
1077
- "targetX",
1078
- "targetY",
1079
- "surfaceScale",
1080
- "specularConstant",
1081
- "specularExponent",
1082
- "stdDeviation",
1083
- "tableValues",
1084
- "viewBox",
1085
- "gradientTransform",
1086
- "pathLength",
1087
- "startOffset",
1088
- "textLength",
1089
- "lengthAdjust",
1090
- ]);
1091
-
1092
- function renderSVG(element, renderState, _styleProp, projection) {
1093
- renderHTML(element, renderState, undefined, projection);
1094
- for (const key in renderState.attrs) {
1095
- element.setAttribute(!camelCaseAttributes.has(key) ? camelToDash(key) : key, renderState.attrs[key]);
1096
- }
1097
- }
1098
-
1099
1019
  function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
1100
1020
  const newValues = scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
1101
1021
  for (const key in props) {
@@ -1110,49 +1030,10 @@ function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
1110
1030
  return newValues;
1111
1031
  }
1112
1032
 
1113
- const layoutProps = ["x", "y", "width", "height", "cx", "cy", "r"];
1114
1033
  const svgMotionConfig = {
1115
1034
  useVisualState: makeUseVisualState({
1116
1035
  scrapeMotionValuesFromProps: scrapeMotionValuesFromProps,
1117
1036
  createRenderState: createSvgRenderState,
1118
- onUpdate: ({ props, prevProps, current, renderState, latestValues, }) => {
1119
- if (!current)
1120
- return;
1121
- let hasTransform = !!props.drag;
1122
- if (!hasTransform) {
1123
- for (const key in latestValues) {
1124
- if (motionDom.transformProps.has(key)) {
1125
- hasTransform = true;
1126
- break;
1127
- }
1128
- }
1129
- }
1130
- if (!hasTransform)
1131
- return;
1132
- let needsMeasure = !prevProps;
1133
- if (prevProps) {
1134
- /**
1135
- * Check the layout props for changes, if any are found we need to
1136
- * measure the element again.
1137
- */
1138
- for (let i = 0; i < layoutProps.length; i++) {
1139
- const key = layoutProps[i];
1140
- if (props[key] !==
1141
- prevProps[key]) {
1142
- needsMeasure = true;
1143
- }
1144
- }
1145
- }
1146
- if (!needsMeasure)
1147
- return;
1148
- motionDom.frame.read(() => {
1149
- updateSVGDimensions(current, renderState);
1150
- motionDom.frame.render(() => {
1151
- buildSVGAttrs(renderState, latestValues, isSVGTag(current.tagName), props.transformTemplate);
1152
- renderSVG(current, renderState);
1153
- });
1154
- });
1155
- },
1156
1037
  }),
1157
1038
  };
1158
1039