framer-motion 7.7.0 → 7.7.2
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 +549 -174
- package/dist/es/animation/legacy-popmotion/index.mjs +5 -3
- package/dist/es/animation/legacy-popmotion/inertia.mjs +2 -2
- package/dist/es/animation/utils/is-animatable.mjs +1 -1
- package/dist/es/animation/utils/transitions.mjs +5 -2
- package/dist/es/frameloop/create-render-step.mjs +88 -0
- package/dist/es/frameloop/data.mjs +6 -0
- package/dist/es/frameloop/index.mjs +59 -0
- package/dist/es/frameloop/on-next-frame.mjs +12 -0
- package/dist/es/gestures/PanSession.mjs +4 -3
- package/dist/es/gestures/drag/VisualElementDragControls.mjs +4 -5
- package/dist/es/gestures/drag/utils/constraints.mjs +1 -2
- package/dist/es/motion/features/layout/MeasureLayout.mjs +1 -1
- package/dist/es/projection/animation/mix-values.mjs +7 -8
- package/dist/es/projection/geometry/delta-remove.mjs +1 -1
- package/dist/es/projection/node/create-projection-node.mjs +1 -1
- package/dist/es/projection/styles/scale-border-radius.mjs +1 -1
- package/dist/es/projection/styles/scale-box-shadow.mjs +1 -1
- package/dist/es/render/VisualElement.mjs +1 -1
- package/dist/es/render/dom/utils/unit-conversion.mjs +2 -1
- package/dist/es/render/dom/value-types/animatable-none.mjs +2 -1
- package/dist/es/render/dom/value-types/defaults.mjs +2 -1
- package/dist/es/render/dom/value-types/dimensions.mjs +2 -1
- package/dist/es/render/dom/value-types/find.mjs +2 -1
- package/dist/es/render/dom/value-types/number.mjs +2 -1
- package/dist/es/render/dom/value-types/type-int.mjs +1 -1
- package/dist/es/render/svg/utils/path.mjs +1 -1
- package/dist/es/render/svg/utils/transform-origin.mjs +1 -1
- package/dist/es/render/utils/animation-state.mjs +1 -2
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/render/utils/setters.mjs +1 -1
- package/dist/es/utils/delay.mjs +1 -1
- package/dist/es/utils/interpolate.mjs +1 -1
- package/dist/es/utils/mix-color.mjs +4 -1
- package/dist/es/utils/mix-complex.mjs +5 -24
- package/dist/es/utils/use-animation-frame.mjs +1 -1
- package/dist/es/utils/use-force-update.mjs +1 -1
- package/dist/es/utils/use-instant-transition.mjs +1 -1
- package/dist/es/value/index.mjs +4 -3
- package/dist/es/value/types/color/hex.mjs +40 -0
- package/dist/es/value/types/color/hsla.mjs +22 -0
- package/dist/es/value/types/color/index.mjs +28 -0
- package/dist/es/value/types/color/rgba.mjs +25 -0
- package/dist/es/value/types/color/utils.mjs +23 -0
- package/dist/es/value/types/complex/filter.mjs +30 -0
- package/dist/es/value/types/complex/index.mjs +61 -0
- package/dist/es/value/types/numbers/index.mjs +17 -0
- package/dist/es/value/types/numbers/units.mjs +19 -0
- package/dist/es/value/types/utils.mjs +15 -0
- package/dist/es/value/use-combine-values.mjs +1 -1
- package/dist/framer-motion.dev.js +304 -249
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/projection.dev.js +5455 -5397
- package/dist/size-rollup-dom-animation-assets.js +1 -1
- package/dist/size-rollup-dom-animation.js +1 -1
- package/dist/size-rollup-dom-max-assets.js +1 -1
- package/dist/size-rollup-dom-max.js +1 -1
- package/dist/size-rollup-m.js +1 -1
- package/dist/size-rollup-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 +7 -2
- package/package.json +9 -11
package/dist/cjs/index.js
CHANGED
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
|
-
var styleValueTypes = require('style-value-types');
|
|
7
6
|
var heyListen = require('hey-listen');
|
|
8
|
-
var sync = require('framesync');
|
|
9
7
|
var dom = require('@motionone/dom');
|
|
10
8
|
|
|
11
9
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -30,7 +28,6 @@ function _interopNamespace(e) {
|
|
|
30
28
|
|
|
31
29
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
32
30
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
33
|
-
var sync__default = /*#__PURE__*/_interopDefaultLegacy(sync);
|
|
34
31
|
|
|
35
32
|
/**
|
|
36
33
|
* @public
|
|
@@ -563,75 +560,121 @@ const getValueAsType = (value, type) => {
|
|
|
563
560
|
: value;
|
|
564
561
|
};
|
|
565
562
|
|
|
563
|
+
const clamp = (min, max, v) => Math.min(Math.max(v, min), max);
|
|
564
|
+
|
|
565
|
+
const number = {
|
|
566
|
+
test: (v) => typeof v === "number",
|
|
567
|
+
parse: parseFloat,
|
|
568
|
+
transform: (v) => v,
|
|
569
|
+
};
|
|
570
|
+
const alpha = {
|
|
571
|
+
...number,
|
|
572
|
+
transform: (v) => clamp(0, 1, v),
|
|
573
|
+
};
|
|
574
|
+
const scale = {
|
|
575
|
+
...number,
|
|
576
|
+
default: 1,
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* TODO: When we move from string as a source of truth to data models
|
|
581
|
+
* everything in this folder should probably be referred to as models vs types
|
|
582
|
+
*/
|
|
583
|
+
// If this number is a decimal, make it just five decimal places
|
|
584
|
+
// to avoid exponents
|
|
585
|
+
const sanitize = (v) => Math.round(v * 100000) / 100000;
|
|
586
|
+
const floatRegex = /(-)?([\d]*\.?[\d])+/g;
|
|
587
|
+
const colorRegex = /(#[0-9a-f]{6}|#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2}(-?[\d\.]+%?)\s*[\,\/]?\s*[\d\.]*%?\))/gi;
|
|
588
|
+
const singleColorRegex = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2}(-?[\d\.]+%?)\s*[\,\/]?\s*[\d\.]*%?\))$/i;
|
|
589
|
+
function isString(v) {
|
|
590
|
+
return typeof v === "string";
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
const createUnitType = (unit) => ({
|
|
594
|
+
test: (v) => isString(v) && v.endsWith(unit) && v.split(" ").length === 1,
|
|
595
|
+
parse: parseFloat,
|
|
596
|
+
transform: (v) => `${v}${unit}`,
|
|
597
|
+
});
|
|
598
|
+
const degrees = createUnitType("deg");
|
|
599
|
+
const percent = createUnitType("%");
|
|
600
|
+
const px = createUnitType("px");
|
|
601
|
+
const vh = createUnitType("vh");
|
|
602
|
+
const vw = createUnitType("vw");
|
|
603
|
+
const progressPercentage = {
|
|
604
|
+
...percent,
|
|
605
|
+
parse: (v) => percent.parse(v) / 100,
|
|
606
|
+
transform: (v) => percent.transform(v * 100),
|
|
607
|
+
};
|
|
608
|
+
|
|
566
609
|
const int = {
|
|
567
|
-
...
|
|
610
|
+
...number,
|
|
568
611
|
transform: Math.round,
|
|
569
612
|
};
|
|
570
613
|
|
|
571
614
|
const numberValueTypes = {
|
|
572
615
|
// Border props
|
|
573
|
-
borderWidth:
|
|
574
|
-
borderTopWidth:
|
|
575
|
-
borderRightWidth:
|
|
576
|
-
borderBottomWidth:
|
|
577
|
-
borderLeftWidth:
|
|
578
|
-
borderRadius:
|
|
579
|
-
radius:
|
|
580
|
-
borderTopLeftRadius:
|
|
581
|
-
borderTopRightRadius:
|
|
582
|
-
borderBottomRightRadius:
|
|
583
|
-
borderBottomLeftRadius:
|
|
616
|
+
borderWidth: px,
|
|
617
|
+
borderTopWidth: px,
|
|
618
|
+
borderRightWidth: px,
|
|
619
|
+
borderBottomWidth: px,
|
|
620
|
+
borderLeftWidth: px,
|
|
621
|
+
borderRadius: px,
|
|
622
|
+
radius: px,
|
|
623
|
+
borderTopLeftRadius: px,
|
|
624
|
+
borderTopRightRadius: px,
|
|
625
|
+
borderBottomRightRadius: px,
|
|
626
|
+
borderBottomLeftRadius: px,
|
|
584
627
|
// Positioning props
|
|
585
|
-
width:
|
|
586
|
-
maxWidth:
|
|
587
|
-
height:
|
|
588
|
-
maxHeight:
|
|
589
|
-
size:
|
|
590
|
-
top:
|
|
591
|
-
right:
|
|
592
|
-
bottom:
|
|
593
|
-
left:
|
|
628
|
+
width: px,
|
|
629
|
+
maxWidth: px,
|
|
630
|
+
height: px,
|
|
631
|
+
maxHeight: px,
|
|
632
|
+
size: px,
|
|
633
|
+
top: px,
|
|
634
|
+
right: px,
|
|
635
|
+
bottom: px,
|
|
636
|
+
left: px,
|
|
594
637
|
// Spacing props
|
|
595
|
-
padding:
|
|
596
|
-
paddingTop:
|
|
597
|
-
paddingRight:
|
|
598
|
-
paddingBottom:
|
|
599
|
-
paddingLeft:
|
|
600
|
-
margin:
|
|
601
|
-
marginTop:
|
|
602
|
-
marginRight:
|
|
603
|
-
marginBottom:
|
|
604
|
-
marginLeft:
|
|
638
|
+
padding: px,
|
|
639
|
+
paddingTop: px,
|
|
640
|
+
paddingRight: px,
|
|
641
|
+
paddingBottom: px,
|
|
642
|
+
paddingLeft: px,
|
|
643
|
+
margin: px,
|
|
644
|
+
marginTop: px,
|
|
645
|
+
marginRight: px,
|
|
646
|
+
marginBottom: px,
|
|
647
|
+
marginLeft: px,
|
|
605
648
|
// Transform props
|
|
606
|
-
rotate:
|
|
607
|
-
rotateX:
|
|
608
|
-
rotateY:
|
|
609
|
-
rotateZ:
|
|
610
|
-
scale
|
|
611
|
-
scaleX:
|
|
612
|
-
scaleY:
|
|
613
|
-
scaleZ:
|
|
614
|
-
skew:
|
|
615
|
-
skewX:
|
|
616
|
-
skewY:
|
|
617
|
-
distance:
|
|
618
|
-
translateX:
|
|
619
|
-
translateY:
|
|
620
|
-
translateZ:
|
|
621
|
-
x:
|
|
622
|
-
y:
|
|
623
|
-
z:
|
|
624
|
-
perspective:
|
|
625
|
-
transformPerspective:
|
|
626
|
-
opacity:
|
|
627
|
-
originX:
|
|
628
|
-
originY:
|
|
629
|
-
originZ:
|
|
649
|
+
rotate: degrees,
|
|
650
|
+
rotateX: degrees,
|
|
651
|
+
rotateY: degrees,
|
|
652
|
+
rotateZ: degrees,
|
|
653
|
+
scale,
|
|
654
|
+
scaleX: scale,
|
|
655
|
+
scaleY: scale,
|
|
656
|
+
scaleZ: scale,
|
|
657
|
+
skew: degrees,
|
|
658
|
+
skewX: degrees,
|
|
659
|
+
skewY: degrees,
|
|
660
|
+
distance: px,
|
|
661
|
+
translateX: px,
|
|
662
|
+
translateY: px,
|
|
663
|
+
translateZ: px,
|
|
664
|
+
x: px,
|
|
665
|
+
y: px,
|
|
666
|
+
z: px,
|
|
667
|
+
perspective: px,
|
|
668
|
+
transformPerspective: px,
|
|
669
|
+
opacity: alpha,
|
|
670
|
+
originX: progressPercentage,
|
|
671
|
+
originY: progressPercentage,
|
|
672
|
+
originZ: px,
|
|
630
673
|
// Misc
|
|
631
674
|
zIndex: int,
|
|
632
675
|
// SVG
|
|
633
|
-
fillOpacity:
|
|
634
|
-
strokeOpacity:
|
|
676
|
+
fillOpacity: alpha,
|
|
677
|
+
strokeOpacity: alpha,
|
|
635
678
|
numOctaves: int,
|
|
636
679
|
};
|
|
637
680
|
|
|
@@ -888,7 +931,7 @@ function filterProps(props, isDom, forwardMotionProps) {
|
|
|
888
931
|
function calcOrigin$1(origin, offset, size) {
|
|
889
932
|
return typeof origin === "string"
|
|
890
933
|
? origin
|
|
891
|
-
:
|
|
934
|
+
: px.transform(offset + size * origin);
|
|
892
935
|
}
|
|
893
936
|
/**
|
|
894
937
|
* The SVG transform origin defaults are different to CSS and is less intuitive,
|
|
@@ -922,10 +965,10 @@ function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true
|
|
|
922
965
|
// when defining props on a React component.
|
|
923
966
|
const keys = useDashCase ? dashKeys : camelKeys;
|
|
924
967
|
// Build the dash offset
|
|
925
|
-
attrs[keys.offset] =
|
|
968
|
+
attrs[keys.offset] = px.transform(-offset);
|
|
926
969
|
// Build the dash array
|
|
927
|
-
const pathLength =
|
|
928
|
-
const pathSpacing =
|
|
970
|
+
const pathLength = px.transform(length);
|
|
971
|
+
const pathSpacing = px.transform(spacing);
|
|
929
972
|
attrs[keys.array] = `${pathLength} ${pathSpacing}`;
|
|
930
973
|
}
|
|
931
974
|
|
|
@@ -1943,6 +1986,175 @@ const isEasingArray = (ease) => {
|
|
|
1943
1986
|
return Array.isArray(ease) && typeof ease[0] !== "number";
|
|
1944
1987
|
};
|
|
1945
1988
|
|
|
1989
|
+
/**
|
|
1990
|
+
* Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,
|
|
1991
|
+
* but false if a number or multiple colors
|
|
1992
|
+
*/
|
|
1993
|
+
const isColorString = (type, testProp) => (v) => {
|
|
1994
|
+
return Boolean((isString(v) && singleColorRegex.test(v) && v.startsWith(type)) ||
|
|
1995
|
+
(testProp && Object.prototype.hasOwnProperty.call(v, testProp)));
|
|
1996
|
+
};
|
|
1997
|
+
const splitColor = (aName, bName, cName) => (v) => {
|
|
1998
|
+
if (!isString(v))
|
|
1999
|
+
return v;
|
|
2000
|
+
const [a, b, c, alpha] = v.match(floatRegex);
|
|
2001
|
+
return {
|
|
2002
|
+
[aName]: parseFloat(a),
|
|
2003
|
+
[bName]: parseFloat(b),
|
|
2004
|
+
[cName]: parseFloat(c),
|
|
2005
|
+
alpha: alpha !== undefined ? parseFloat(alpha) : 1,
|
|
2006
|
+
};
|
|
2007
|
+
};
|
|
2008
|
+
|
|
2009
|
+
const clampRgbUnit = (v) => clamp(0, 255, v);
|
|
2010
|
+
const rgbUnit = {
|
|
2011
|
+
...number,
|
|
2012
|
+
transform: (v) => Math.round(clampRgbUnit(v)),
|
|
2013
|
+
};
|
|
2014
|
+
const rgba = {
|
|
2015
|
+
test: isColorString("rgb", "red"),
|
|
2016
|
+
parse: splitColor("red", "green", "blue"),
|
|
2017
|
+
transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" +
|
|
2018
|
+
rgbUnit.transform(red) +
|
|
2019
|
+
", " +
|
|
2020
|
+
rgbUnit.transform(green) +
|
|
2021
|
+
", " +
|
|
2022
|
+
rgbUnit.transform(blue) +
|
|
2023
|
+
", " +
|
|
2024
|
+
sanitize(alpha.transform(alpha$1)) +
|
|
2025
|
+
")",
|
|
2026
|
+
};
|
|
2027
|
+
|
|
2028
|
+
function parseHex(v) {
|
|
2029
|
+
let r = "";
|
|
2030
|
+
let g = "";
|
|
2031
|
+
let b = "";
|
|
2032
|
+
let a = "";
|
|
2033
|
+
// If we have 6 characters, ie #FF0000
|
|
2034
|
+
if (v.length > 5) {
|
|
2035
|
+
r = v.substring(1, 3);
|
|
2036
|
+
g = v.substring(3, 5);
|
|
2037
|
+
b = v.substring(5, 7);
|
|
2038
|
+
a = v.substring(7, 9);
|
|
2039
|
+
// Or we have 3 characters, ie #F00
|
|
2040
|
+
}
|
|
2041
|
+
else {
|
|
2042
|
+
r = v.substring(1, 2);
|
|
2043
|
+
g = v.substring(2, 3);
|
|
2044
|
+
b = v.substring(3, 4);
|
|
2045
|
+
a = v.substring(4, 5);
|
|
2046
|
+
r += r;
|
|
2047
|
+
g += g;
|
|
2048
|
+
b += b;
|
|
2049
|
+
a += a;
|
|
2050
|
+
}
|
|
2051
|
+
return {
|
|
2052
|
+
red: parseInt(r, 16),
|
|
2053
|
+
green: parseInt(g, 16),
|
|
2054
|
+
blue: parseInt(b, 16),
|
|
2055
|
+
alpha: a ? parseInt(a, 16) / 255 : 1,
|
|
2056
|
+
};
|
|
2057
|
+
}
|
|
2058
|
+
const hex = {
|
|
2059
|
+
test: isColorString("#"),
|
|
2060
|
+
parse: parseHex,
|
|
2061
|
+
transform: rgba.transform,
|
|
2062
|
+
};
|
|
2063
|
+
|
|
2064
|
+
const hsla = {
|
|
2065
|
+
test: isColorString("hsl", "hue"),
|
|
2066
|
+
parse: splitColor("hue", "saturation", "lightness"),
|
|
2067
|
+
transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
|
|
2068
|
+
return ("hsla(" +
|
|
2069
|
+
Math.round(hue) +
|
|
2070
|
+
", " +
|
|
2071
|
+
percent.transform(sanitize(saturation)) +
|
|
2072
|
+
", " +
|
|
2073
|
+
percent.transform(sanitize(lightness)) +
|
|
2074
|
+
", " +
|
|
2075
|
+
sanitize(alpha.transform(alpha$1)) +
|
|
2076
|
+
")");
|
|
2077
|
+
},
|
|
2078
|
+
};
|
|
2079
|
+
|
|
2080
|
+
const color = {
|
|
2081
|
+
test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
|
|
2082
|
+
parse: (v) => {
|
|
2083
|
+
if (rgba.test(v)) {
|
|
2084
|
+
return rgba.parse(v);
|
|
2085
|
+
}
|
|
2086
|
+
else if (hsla.test(v)) {
|
|
2087
|
+
return hsla.parse(v);
|
|
2088
|
+
}
|
|
2089
|
+
else {
|
|
2090
|
+
return hex.parse(v);
|
|
2091
|
+
}
|
|
2092
|
+
},
|
|
2093
|
+
transform: (v) => {
|
|
2094
|
+
return isString(v)
|
|
2095
|
+
? v
|
|
2096
|
+
: v.hasOwnProperty("red")
|
|
2097
|
+
? rgba.transform(v)
|
|
2098
|
+
: hsla.transform(v);
|
|
2099
|
+
},
|
|
2100
|
+
};
|
|
2101
|
+
|
|
2102
|
+
const colorToken = "${c}";
|
|
2103
|
+
const numberToken = "${n}";
|
|
2104
|
+
function test(v) {
|
|
2105
|
+
var _a, _b;
|
|
2106
|
+
return (isNaN(v) &&
|
|
2107
|
+
isString(v) &&
|
|
2108
|
+
(((_a = v.match(floatRegex)) === null || _a === void 0 ? void 0 : _a.length) || 0) +
|
|
2109
|
+
(((_b = v.match(colorRegex)) === null || _b === void 0 ? void 0 : _b.length) || 0) >
|
|
2110
|
+
0);
|
|
2111
|
+
}
|
|
2112
|
+
function analyseComplexValue(v) {
|
|
2113
|
+
if (typeof v === "number")
|
|
2114
|
+
v = `${v}`;
|
|
2115
|
+
const values = [];
|
|
2116
|
+
let numColors = 0;
|
|
2117
|
+
let numNumbers = 0;
|
|
2118
|
+
const colors = v.match(colorRegex);
|
|
2119
|
+
if (colors) {
|
|
2120
|
+
numColors = colors.length;
|
|
2121
|
+
// Strip colors from input so they're not picked up by number regex.
|
|
2122
|
+
// There's a better way to combine these regex searches, but its beyond my regex skills
|
|
2123
|
+
v = v.replace(colorRegex, colorToken);
|
|
2124
|
+
values.push(...colors.map(color.parse));
|
|
2125
|
+
}
|
|
2126
|
+
const numbers = v.match(floatRegex);
|
|
2127
|
+
if (numbers) {
|
|
2128
|
+
numNumbers = numbers.length;
|
|
2129
|
+
v = v.replace(floatRegex, numberToken);
|
|
2130
|
+
values.push(...numbers.map(number.parse));
|
|
2131
|
+
}
|
|
2132
|
+
return { values, numColors, numNumbers, tokenised: v };
|
|
2133
|
+
}
|
|
2134
|
+
function parse(v) {
|
|
2135
|
+
return analyseComplexValue(v).values;
|
|
2136
|
+
}
|
|
2137
|
+
function createTransformer(source) {
|
|
2138
|
+
const { values, numColors, tokenised } = analyseComplexValue(source);
|
|
2139
|
+
const numValues = values.length;
|
|
2140
|
+
return (v) => {
|
|
2141
|
+
let output = tokenised;
|
|
2142
|
+
for (let i = 0; i < numValues; i++) {
|
|
2143
|
+
output = output.replace(i < numColors ? colorToken : numberToken, i < numColors
|
|
2144
|
+
? color.transform(v[i])
|
|
2145
|
+
: sanitize(v[i]));
|
|
2146
|
+
}
|
|
2147
|
+
return output;
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2150
|
+
const convertNumbersToZero = (v) => typeof v === "number" ? 0 : v;
|
|
2151
|
+
function getAnimatableNone$1(v) {
|
|
2152
|
+
const parsed = parse(v);
|
|
2153
|
+
const transformer = createTransformer(v);
|
|
2154
|
+
return transformer(parsed.map(convertNumbersToZero));
|
|
2155
|
+
}
|
|
2156
|
+
const complex = { test, parse, createTransformer, getAnimatableNone: getAnimatableNone$1 };
|
|
2157
|
+
|
|
1946
2158
|
/**
|
|
1947
2159
|
* Check if a value is animatable. Examples:
|
|
1948
2160
|
*
|
|
@@ -1962,7 +2174,7 @@ const isAnimatable = (key, value) => {
|
|
|
1962
2174
|
if (typeof value === "number" || Array.isArray(value))
|
|
1963
2175
|
return true;
|
|
1964
2176
|
if (typeof value === "string" && // It's animatable if we have a string
|
|
1965
|
-
|
|
2177
|
+
complex.test(value) && // And it contains numbers and/or colors
|
|
1966
2178
|
!value.startsWith("url(") // Unless it starts with "url("
|
|
1967
2179
|
) {
|
|
1968
2180
|
return true;
|
|
@@ -2020,25 +2232,51 @@ const getDefaultTransition = (valueKey, to) => {
|
|
|
2020
2232
|
return { to, ...transitionFactory(to) };
|
|
2021
2233
|
};
|
|
2022
2234
|
|
|
2235
|
+
/**
|
|
2236
|
+
* Properties that should default to 1 or 100%
|
|
2237
|
+
*/
|
|
2238
|
+
const maxDefaults = new Set(["brightness", "contrast", "saturate", "opacity"]);
|
|
2239
|
+
function applyDefaultFilter(v) {
|
|
2240
|
+
const [name, value] = v.slice(0, -1).split("(");
|
|
2241
|
+
if (name === "drop-shadow")
|
|
2242
|
+
return v;
|
|
2243
|
+
const [number] = value.match(floatRegex) || [];
|
|
2244
|
+
if (!number)
|
|
2245
|
+
return v;
|
|
2246
|
+
const unit = value.replace(number, "");
|
|
2247
|
+
let defaultValue = maxDefaults.has(name) ? 1 : 0;
|
|
2248
|
+
if (number !== value)
|
|
2249
|
+
defaultValue *= 100;
|
|
2250
|
+
return name + "(" + defaultValue + unit + ")";
|
|
2251
|
+
}
|
|
2252
|
+
const functionRegex = /([a-z-]*)\(.*?\)/g;
|
|
2253
|
+
const filter = {
|
|
2254
|
+
...complex,
|
|
2255
|
+
getAnimatableNone: (v) => {
|
|
2256
|
+
const functions = v.match(functionRegex);
|
|
2257
|
+
return functions ? functions.map(applyDefaultFilter).join(" ") : v;
|
|
2258
|
+
},
|
|
2259
|
+
};
|
|
2260
|
+
|
|
2023
2261
|
/**
|
|
2024
2262
|
* A map of default value types for common values
|
|
2025
2263
|
*/
|
|
2026
2264
|
const defaultValueTypes = {
|
|
2027
2265
|
...numberValueTypes,
|
|
2028
2266
|
// Color props
|
|
2029
|
-
color
|
|
2030
|
-
backgroundColor:
|
|
2031
|
-
outlineColor:
|
|
2032
|
-
fill:
|
|
2033
|
-
stroke:
|
|
2267
|
+
color,
|
|
2268
|
+
backgroundColor: color,
|
|
2269
|
+
outlineColor: color,
|
|
2270
|
+
fill: color,
|
|
2271
|
+
stroke: color,
|
|
2034
2272
|
// Border props
|
|
2035
|
-
borderColor:
|
|
2036
|
-
borderTopColor:
|
|
2037
|
-
borderRightColor:
|
|
2038
|
-
borderBottomColor:
|
|
2039
|
-
borderLeftColor:
|
|
2040
|
-
filter
|
|
2041
|
-
WebkitFilter:
|
|
2273
|
+
borderColor: color,
|
|
2274
|
+
borderTopColor: color,
|
|
2275
|
+
borderRightColor: color,
|
|
2276
|
+
borderBottomColor: color,
|
|
2277
|
+
borderLeftColor: color,
|
|
2278
|
+
filter,
|
|
2279
|
+
WebkitFilter: filter,
|
|
2042
2280
|
};
|
|
2043
2281
|
/**
|
|
2044
2282
|
* Gets the default ValueType for the provided value key
|
|
@@ -2048,8 +2286,8 @@ const getDefaultValueType = (key) => defaultValueTypes[key];
|
|
|
2048
2286
|
function getAnimatableNone(key, value) {
|
|
2049
2287
|
var _a;
|
|
2050
2288
|
let defaultValueType = getDefaultValueType(key);
|
|
2051
|
-
if (defaultValueType !==
|
|
2052
|
-
defaultValueType =
|
|
2289
|
+
if (defaultValueType !== filter)
|
|
2290
|
+
defaultValueType = complex;
|
|
2053
2291
|
// If value is not recognised as animatable, ie "none", create an animatable version origin based on the target
|
|
2054
2292
|
return (_a = defaultValueType.getAnimatableNone) === null || _a === void 0 ? void 0 : _a.call(defaultValueType, value);
|
|
2055
2293
|
}
|
|
@@ -2058,21 +2296,176 @@ const instantAnimationState = {
|
|
|
2058
2296
|
current: false,
|
|
2059
2297
|
};
|
|
2060
2298
|
|
|
2299
|
+
/*
|
|
2300
|
+
Detect and load appropriate clock setting for the execution environment
|
|
2301
|
+
*/
|
|
2302
|
+
const defaultTimestep = (1 / 60) * 1000;
|
|
2303
|
+
const getCurrentTime = typeof performance !== "undefined"
|
|
2304
|
+
? () => performance.now()
|
|
2305
|
+
: () => Date.now();
|
|
2306
|
+
const onNextFrame = typeof window !== "undefined"
|
|
2307
|
+
? (callback) => window.requestAnimationFrame(callback)
|
|
2308
|
+
: (callback) => setTimeout(() => callback(getCurrentTime()), defaultTimestep);
|
|
2309
|
+
|
|
2310
|
+
function createRenderStep(runNextFrame) {
|
|
2311
|
+
/**
|
|
2312
|
+
* We create and reuse two arrays, one to queue jobs for the current frame
|
|
2313
|
+
* and one for the next. We reuse to avoid triggering GC after x frames.
|
|
2314
|
+
*/
|
|
2315
|
+
let toRun = [];
|
|
2316
|
+
let toRunNextFrame = [];
|
|
2317
|
+
/**
|
|
2318
|
+
*
|
|
2319
|
+
*/
|
|
2320
|
+
let numToRun = 0;
|
|
2321
|
+
/**
|
|
2322
|
+
* Track whether we're currently processing jobs in this step. This way
|
|
2323
|
+
* we can decide whether to schedule new jobs for this frame or next.
|
|
2324
|
+
*/
|
|
2325
|
+
let isProcessing = false;
|
|
2326
|
+
let flushNextFrame = false;
|
|
2327
|
+
/**
|
|
2328
|
+
* A set of processes which were marked keepAlive when scheduled.
|
|
2329
|
+
*/
|
|
2330
|
+
const toKeepAlive = new WeakSet();
|
|
2331
|
+
const step = {
|
|
2332
|
+
/**
|
|
2333
|
+
* Schedule a process to run on the next frame.
|
|
2334
|
+
*/
|
|
2335
|
+
schedule: (callback, keepAlive = false, immediate = false) => {
|
|
2336
|
+
const addToCurrentFrame = immediate && isProcessing;
|
|
2337
|
+
const buffer = addToCurrentFrame ? toRun : toRunNextFrame;
|
|
2338
|
+
if (keepAlive)
|
|
2339
|
+
toKeepAlive.add(callback);
|
|
2340
|
+
// If the buffer doesn't already contain this callback, add it
|
|
2341
|
+
if (buffer.indexOf(callback) === -1) {
|
|
2342
|
+
buffer.push(callback);
|
|
2343
|
+
// If we're adding it to the currently running buffer, update its measured size
|
|
2344
|
+
if (addToCurrentFrame && isProcessing)
|
|
2345
|
+
numToRun = toRun.length;
|
|
2346
|
+
}
|
|
2347
|
+
return callback;
|
|
2348
|
+
},
|
|
2349
|
+
/**
|
|
2350
|
+
* Cancel the provided callback from running on the next frame.
|
|
2351
|
+
*/
|
|
2352
|
+
cancel: (callback) => {
|
|
2353
|
+
const index = toRunNextFrame.indexOf(callback);
|
|
2354
|
+
if (index !== -1)
|
|
2355
|
+
toRunNextFrame.splice(index, 1);
|
|
2356
|
+
toKeepAlive.delete(callback);
|
|
2357
|
+
},
|
|
2358
|
+
/**
|
|
2359
|
+
* Execute all schedule callbacks.
|
|
2360
|
+
*/
|
|
2361
|
+
process: (frameData) => {
|
|
2362
|
+
/**
|
|
2363
|
+
* If we're already processing we've probably been triggered by a flushSync
|
|
2364
|
+
* inside an existing process. Instead of executing, mark flushNextFrame
|
|
2365
|
+
* as true and ensure we flush the following frame at the end of this one.
|
|
2366
|
+
*/
|
|
2367
|
+
if (isProcessing) {
|
|
2368
|
+
flushNextFrame = true;
|
|
2369
|
+
return;
|
|
2370
|
+
}
|
|
2371
|
+
isProcessing = true;
|
|
2372
|
+
[toRun, toRunNextFrame] = [toRunNextFrame, toRun];
|
|
2373
|
+
// Clear the next frame list
|
|
2374
|
+
toRunNextFrame.length = 0;
|
|
2375
|
+
// Execute this frame
|
|
2376
|
+
numToRun = toRun.length;
|
|
2377
|
+
if (numToRun) {
|
|
2378
|
+
for (let i = 0; i < numToRun; i++) {
|
|
2379
|
+
const callback = toRun[i];
|
|
2380
|
+
callback(frameData);
|
|
2381
|
+
if (toKeepAlive.has(callback)) {
|
|
2382
|
+
step.schedule(callback);
|
|
2383
|
+
runNextFrame();
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
isProcessing = false;
|
|
2388
|
+
if (flushNextFrame) {
|
|
2389
|
+
flushNextFrame = false;
|
|
2390
|
+
step.process(frameData);
|
|
2391
|
+
}
|
|
2392
|
+
},
|
|
2393
|
+
};
|
|
2394
|
+
return step;
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
const frameData = {
|
|
2398
|
+
delta: 0,
|
|
2399
|
+
timestamp: 0,
|
|
2400
|
+
};
|
|
2401
|
+
|
|
2402
|
+
const maxElapsed = 40;
|
|
2403
|
+
let useDefaultElapsed = true;
|
|
2404
|
+
let runNextFrame = false;
|
|
2405
|
+
let isProcessing = false;
|
|
2406
|
+
const stepsOrder = [
|
|
2407
|
+
"read",
|
|
2408
|
+
"update",
|
|
2409
|
+
"preRender",
|
|
2410
|
+
"render",
|
|
2411
|
+
"postRender",
|
|
2412
|
+
];
|
|
2413
|
+
const steps = stepsOrder.reduce((acc, key) => {
|
|
2414
|
+
acc[key] = createRenderStep(() => (runNextFrame = true));
|
|
2415
|
+
return acc;
|
|
2416
|
+
}, {});
|
|
2417
|
+
const sync = stepsOrder.reduce((acc, key) => {
|
|
2418
|
+
const step = steps[key];
|
|
2419
|
+
acc[key] = (process, keepAlive = false, immediate = false) => {
|
|
2420
|
+
if (!runNextFrame)
|
|
2421
|
+
startLoop();
|
|
2422
|
+
return step.schedule(process, keepAlive, immediate);
|
|
2423
|
+
};
|
|
2424
|
+
return acc;
|
|
2425
|
+
}, {});
|
|
2426
|
+
const cancelSync = stepsOrder.reduce((acc, key) => {
|
|
2427
|
+
acc[key] = steps[key].cancel;
|
|
2428
|
+
return acc;
|
|
2429
|
+
}, {});
|
|
2430
|
+
const flushSync = stepsOrder.reduce((acc, key) => {
|
|
2431
|
+
acc[key] = () => steps[key].process(frameData);
|
|
2432
|
+
return acc;
|
|
2433
|
+
}, {});
|
|
2434
|
+
const processStep = (stepId) => steps[stepId].process(frameData);
|
|
2435
|
+
const processFrame = (timestamp) => {
|
|
2436
|
+
runNextFrame = false;
|
|
2437
|
+
frameData.delta = useDefaultElapsed
|
|
2438
|
+
? defaultTimestep
|
|
2439
|
+
: Math.max(Math.min(timestamp - frameData.timestamp, maxElapsed), 1);
|
|
2440
|
+
frameData.timestamp = timestamp;
|
|
2441
|
+
isProcessing = true;
|
|
2442
|
+
stepsOrder.forEach(processStep);
|
|
2443
|
+
isProcessing = false;
|
|
2444
|
+
if (runNextFrame) {
|
|
2445
|
+
useDefaultElapsed = false;
|
|
2446
|
+
onNextFrame(processFrame);
|
|
2447
|
+
}
|
|
2448
|
+
};
|
|
2449
|
+
const startLoop = () => {
|
|
2450
|
+
runNextFrame = true;
|
|
2451
|
+
useDefaultElapsed = true;
|
|
2452
|
+
if (!isProcessing)
|
|
2453
|
+
onNextFrame(processFrame);
|
|
2454
|
+
};
|
|
2455
|
+
|
|
2061
2456
|
function delay(callback, timeout) {
|
|
2062
2457
|
const start = performance.now();
|
|
2063
2458
|
const checkElapsed = ({ timestamp }) => {
|
|
2064
2459
|
const elapsed = timestamp - start;
|
|
2065
2460
|
if (elapsed >= timeout) {
|
|
2066
|
-
|
|
2461
|
+
cancelSync.read(checkElapsed);
|
|
2067
2462
|
callback(elapsed - timeout);
|
|
2068
2463
|
}
|
|
2069
2464
|
};
|
|
2070
|
-
|
|
2071
|
-
return () =>
|
|
2465
|
+
sync.read(checkElapsed, true);
|
|
2466
|
+
return () => cancelSync.read(checkElapsed);
|
|
2072
2467
|
}
|
|
2073
2468
|
|
|
2074
|
-
const clamp = (min, max, v) => Math.min(Math.max(v, min), max);
|
|
2075
|
-
|
|
2076
2469
|
/*
|
|
2077
2470
|
Value in range from progress
|
|
2078
2471
|
|
|
@@ -2144,13 +2537,14 @@ const mixLinearColor = (from, to, v) => {
|
|
|
2144
2537
|
const fromExpo = from * from;
|
|
2145
2538
|
return Math.sqrt(Math.max(0, v * (to * to - fromExpo) + fromExpo));
|
|
2146
2539
|
};
|
|
2147
|
-
const colorTypes = [
|
|
2540
|
+
const colorTypes = [hex, rgba, hsla];
|
|
2148
2541
|
const getColorType = (v) => colorTypes.find((type) => type.test(v));
|
|
2149
2542
|
function asRGBA(color) {
|
|
2150
2543
|
const type = getColorType(color);
|
|
2151
2544
|
heyListen.invariant(Boolean(type), `'${color}' is not an animatable color. Use the equivalent color code instead.`);
|
|
2152
2545
|
let model = type.parse(color);
|
|
2153
|
-
if (type ===
|
|
2546
|
+
if (type === hsla) {
|
|
2547
|
+
// TODO Remove this cast - needed since Framer Motion's stricter typing
|
|
2154
2548
|
model = hslaToRgba(model);
|
|
2155
2549
|
}
|
|
2156
2550
|
return model;
|
|
@@ -2164,7 +2558,7 @@ const mixColor = (from, to) => {
|
|
|
2164
2558
|
blended.green = mixLinearColor(fromRGBA.green, toRGBA.green, v);
|
|
2165
2559
|
blended.blue = mixLinearColor(fromRGBA.blue, toRGBA.blue, v);
|
|
2166
2560
|
blended.alpha = mix(fromRGBA.alpha, toRGBA.alpha, v);
|
|
2167
|
-
return
|
|
2561
|
+
return rgba.transform(blended);
|
|
2168
2562
|
};
|
|
2169
2563
|
};
|
|
2170
2564
|
|
|
@@ -2172,7 +2566,7 @@ function getMixer$1(origin, target) {
|
|
|
2172
2566
|
if (typeof origin === "number") {
|
|
2173
2567
|
return (v) => mix(origin, target, v);
|
|
2174
2568
|
}
|
|
2175
|
-
else if (
|
|
2569
|
+
else if (color.test(origin)) {
|
|
2176
2570
|
return mixColor(origin, target);
|
|
2177
2571
|
}
|
|
2178
2572
|
else {
|
|
@@ -2205,34 +2599,14 @@ const mixObject = (origin, target) => {
|
|
|
2205
2599
|
return output;
|
|
2206
2600
|
};
|
|
2207
2601
|
};
|
|
2208
|
-
/**
|
|
2209
|
-
* TODO: Combine with function within complex when style-value-types moved inside Framer Motion
|
|
2210
|
-
*/
|
|
2211
|
-
function analyse(value) {
|
|
2212
|
-
const parsed = styleValueTypes.complex.parse(value);
|
|
2213
|
-
const numValues = parsed.length;
|
|
2214
|
-
let numNumbers = 0;
|
|
2215
|
-
let numColors = 0;
|
|
2216
|
-
for (let i = 0; i < numValues; i++) {
|
|
2217
|
-
// Parsed complex values return with colors first, so if we've seen any number
|
|
2218
|
-
// we're already past that part of the array and don't need to continue running typeof
|
|
2219
|
-
if (numNumbers || typeof parsed[i] === "number") {
|
|
2220
|
-
numNumbers++;
|
|
2221
|
-
}
|
|
2222
|
-
else {
|
|
2223
|
-
numColors++;
|
|
2224
|
-
}
|
|
2225
|
-
}
|
|
2226
|
-
return { parsed, numNumbers, numColors };
|
|
2227
|
-
}
|
|
2228
2602
|
const mixComplex = (origin, target) => {
|
|
2229
|
-
const template =
|
|
2230
|
-
const originStats =
|
|
2231
|
-
const targetStats =
|
|
2603
|
+
const template = complex.createTransformer(target);
|
|
2604
|
+
const originStats = analyseComplexValue(origin);
|
|
2605
|
+
const targetStats = analyseComplexValue(target);
|
|
2232
2606
|
const canInterpolate = originStats.numColors === targetStats.numColors &&
|
|
2233
2607
|
originStats.numNumbers >= targetStats.numNumbers;
|
|
2234
2608
|
if (canInterpolate) {
|
|
2235
|
-
return pipe(mixArray(originStats.
|
|
2609
|
+
return pipe(mixArray(originStats.values, targetStats.values), template);
|
|
2236
2610
|
}
|
|
2237
2611
|
else {
|
|
2238
2612
|
heyListen.warning(true, `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`);
|
|
@@ -2263,7 +2637,7 @@ function detectMixerFactory(v) {
|
|
|
2263
2637
|
return mixNumber;
|
|
2264
2638
|
}
|
|
2265
2639
|
else if (typeof v === "string") {
|
|
2266
|
-
if (
|
|
2640
|
+
if (color.test(v)) {
|
|
2267
2641
|
return mixColor;
|
|
2268
2642
|
}
|
|
2269
2643
|
else {
|
|
@@ -2654,8 +3028,8 @@ function hasRepeatDelayElapsed(elapsed, duration, delay, isForwardPlayback) {
|
|
|
2654
3028
|
const framesync = (update) => {
|
|
2655
3029
|
const passTimestamp = ({ delta }) => update(delta);
|
|
2656
3030
|
return {
|
|
2657
|
-
start: () =>
|
|
2658
|
-
stop: () =>
|
|
3031
|
+
start: () => sync.update(passTimestamp, true),
|
|
3032
|
+
stop: () => cancelSync.update(passTimestamp),
|
|
2659
3033
|
};
|
|
2660
3034
|
};
|
|
2661
3035
|
function animate$1({ from, autoplay = true, driver = framesync, elapsed = 0, repeat: repeatMax = 0, repeatType = "loop", repeatDelay = 0, onPlay, onStop, onComplete, onRepeat, onUpdate, type = "keyframes", ...options }) {
|
|
@@ -2709,8 +3083,10 @@ function animate$1({ from, autoplay = true, driver = framesync, elapsed = 0, rep
|
|
|
2709
3083
|
}
|
|
2710
3084
|
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(latest);
|
|
2711
3085
|
if (isComplete) {
|
|
2712
|
-
if (repeatCount === 0)
|
|
2713
|
-
computedDuration
|
|
3086
|
+
if (repeatCount === 0) {
|
|
3087
|
+
computedDuration =
|
|
3088
|
+
computedDuration !== undefined ? computedDuration : elapsed;
|
|
3089
|
+
}
|
|
2714
3090
|
if (repeatCount < repeatMax) {
|
|
2715
3091
|
hasRepeatDelayElapsed(elapsed, computedDuration, repeatDelay, isForwardPlayback) && repeat();
|
|
2716
3092
|
}
|
|
@@ -2801,7 +3177,7 @@ function inertia({ from = 0, velocity = 0, min, max, power = 0.8, timeConstant =
|
|
|
2801
3177
|
const checkBoundary = (v) => {
|
|
2802
3178
|
prev = current;
|
|
2803
3179
|
current = v;
|
|
2804
|
-
velocity = velocityPerSecond(v - prev,
|
|
3180
|
+
velocity = velocityPerSecond(v - prev, frameData.delta);
|
|
2805
3181
|
if ((heading === 1 && v > boundary) ||
|
|
2806
3182
|
(heading === -1 && v < boundary)) {
|
|
2807
3183
|
startSpring({ from: v, to: boundary, velocity });
|
|
@@ -2871,9 +3247,12 @@ function convertTransitionToAnimationOptions({ ease, times, ...transition }) {
|
|
|
2871
3247
|
* Get the delay for a value by checking Transition with decreasing specificity.
|
|
2872
3248
|
*/
|
|
2873
3249
|
function getDelayFromTransition(transition, key) {
|
|
2874
|
-
var _a, _b;
|
|
2875
3250
|
const valueTransition = getValueTransition(transition, key) || {};
|
|
2876
|
-
return
|
|
3251
|
+
return valueTransition.delay !== undefined
|
|
3252
|
+
? valueTransition.delay
|
|
3253
|
+
: transition.delay !== undefined
|
|
3254
|
+
? transition.delay
|
|
3255
|
+
: 0;
|
|
2877
3256
|
}
|
|
2878
3257
|
function hydrateKeyframes(options) {
|
|
2879
3258
|
if (Array.isArray(options.to) && options.to[0] === null) {
|
|
@@ -3092,7 +3471,7 @@ class MotionValue {
|
|
|
3092
3471
|
* This will be replaced by the build step with the latest version number.
|
|
3093
3472
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
3094
3473
|
*/
|
|
3095
|
-
this.version = "7.7.
|
|
3474
|
+
this.version = "7.7.2";
|
|
3096
3475
|
/**
|
|
3097
3476
|
* Duration, in milliseconds, since last updating frame.
|
|
3098
3477
|
*
|
|
@@ -3135,11 +3514,11 @@ class MotionValue {
|
|
|
3135
3514
|
this.prev = this.current;
|
|
3136
3515
|
this.current = v;
|
|
3137
3516
|
// Update timestamp
|
|
3138
|
-
const { delta, timestamp } =
|
|
3517
|
+
const { delta, timestamp } = frameData;
|
|
3139
3518
|
if (this.lastUpdated !== timestamp) {
|
|
3140
3519
|
this.timeDelta = delta;
|
|
3141
3520
|
this.lastUpdated = timestamp;
|
|
3142
|
-
|
|
3521
|
+
sync.postRender(this.scheduleVelocityCheck);
|
|
3143
3522
|
}
|
|
3144
3523
|
// Update update subscribers
|
|
3145
3524
|
if (this.prev !== this.current) {
|
|
@@ -3162,7 +3541,7 @@ class MotionValue {
|
|
|
3162
3541
|
*
|
|
3163
3542
|
* @internal
|
|
3164
3543
|
*/
|
|
3165
|
-
this.scheduleVelocityCheck = () =>
|
|
3544
|
+
this.scheduleVelocityCheck = () => sync.postRender(this.velocityCheck);
|
|
3166
3545
|
/**
|
|
3167
3546
|
* Updates `prev` with `current` if the value hasn't been updated this frame.
|
|
3168
3547
|
* This ensures velocity calculations return `0`.
|
|
@@ -3386,7 +3765,7 @@ const auto = {
|
|
|
3386
3765
|
/**
|
|
3387
3766
|
* A list of value types commonly used for dimensions
|
|
3388
3767
|
*/
|
|
3389
|
-
const dimensionValueTypes = [
|
|
3768
|
+
const dimensionValueTypes = [number, px, percent, degrees, vw, vh, auto];
|
|
3390
3769
|
/**
|
|
3391
3770
|
* Tests a dimensional value against the list of dimension ValueTypes
|
|
3392
3771
|
*/
|
|
@@ -3395,7 +3774,7 @@ const findDimensionValueType = (v) => dimensionValueTypes.find(testValueType(v))
|
|
|
3395
3774
|
/**
|
|
3396
3775
|
* A list of all ValueTypes
|
|
3397
3776
|
*/
|
|
3398
|
-
const valueTypes = [...dimensionValueTypes,
|
|
3777
|
+
const valueTypes = [...dimensionValueTypes, color, complex];
|
|
3399
3778
|
/**
|
|
3400
3779
|
* Tests a value against the list of ValueTypes
|
|
3401
3780
|
*/
|
|
@@ -3501,7 +3880,7 @@ function checkTargetForNewValues(visualElement, target, origin) {
|
|
|
3501
3880
|
// If this is a number read as a string, ie "0" or "200", convert it to a number
|
|
3502
3881
|
value = parseFloat(value);
|
|
3503
3882
|
}
|
|
3504
|
-
else if (!findValueType(value) &&
|
|
3883
|
+
else if (!findValueType(value) && complex.test(targetValue)) {
|
|
3505
3884
|
value = getAnimatableNone(key, targetValue);
|
|
3506
3885
|
}
|
|
3507
3886
|
visualElement.addValue(key, motionValue(value));
|
|
@@ -3716,7 +4095,6 @@ function createAnimationState(visualElement) {
|
|
|
3716
4095
|
* what to animate those to.
|
|
3717
4096
|
*/
|
|
3718
4097
|
function animateChanges(options, changedActiveType) {
|
|
3719
|
-
var _a;
|
|
3720
4098
|
const props = visualElement.getProps();
|
|
3721
4099
|
const context = visualElement.getVariantContext(true) || {};
|
|
3722
4100
|
/**
|
|
@@ -3749,7 +4127,7 @@ function createAnimationState(visualElement) {
|
|
|
3749
4127
|
for (let i = 0; i < numAnimationTypes; i++) {
|
|
3750
4128
|
const type = reversePriorityOrder[i];
|
|
3751
4129
|
const typeState = state[type];
|
|
3752
|
-
const prop =
|
|
4130
|
+
const prop = props[type] !== undefined ? props[type] : context[type];
|
|
3753
4131
|
const propIsVariant = isVariantLabel(prop);
|
|
3754
4132
|
/**
|
|
3755
4133
|
* If this type has *just* changed isActive status, set activeDelta
|
|
@@ -4062,7 +4440,7 @@ class PanSession {
|
|
|
4062
4440
|
if (!isPanStarted && !isDistancePastThreshold)
|
|
4063
4441
|
return;
|
|
4064
4442
|
const { point } = info;
|
|
4065
|
-
const { timestamp } =
|
|
4443
|
+
const { timestamp } = frameData;
|
|
4066
4444
|
this.history.push({ ...point, timestamp });
|
|
4067
4445
|
const { onStart, onMove } = this.handlers;
|
|
4068
4446
|
if (!isPanStarted) {
|
|
@@ -4080,7 +4458,7 @@ class PanSession {
|
|
|
4080
4458
|
return;
|
|
4081
4459
|
}
|
|
4082
4460
|
// Throttle mouse move event to once per frame
|
|
4083
|
-
|
|
4461
|
+
sync.update(this.updatePoint, true);
|
|
4084
4462
|
};
|
|
4085
4463
|
this.handlePointerUp = (event, info) => {
|
|
4086
4464
|
this.end();
|
|
@@ -4099,7 +4477,7 @@ class PanSession {
|
|
|
4099
4477
|
const info = extractEventInfo(event);
|
|
4100
4478
|
const initialInfo = transformPoint(info, this.transformPagePoint);
|
|
4101
4479
|
const { point } = initialInfo;
|
|
4102
|
-
const { timestamp } =
|
|
4480
|
+
const { timestamp } = frameData;
|
|
4103
4481
|
this.history = [{ ...point, timestamp }];
|
|
4104
4482
|
const { onSessionStart } = handlers;
|
|
4105
4483
|
onSessionStart &&
|
|
@@ -4111,7 +4489,7 @@ class PanSession {
|
|
|
4111
4489
|
}
|
|
4112
4490
|
end() {
|
|
4113
4491
|
this.removeListeners && this.removeListeners();
|
|
4114
|
-
|
|
4492
|
+
cancelSync.update(this.updatePoint);
|
|
4115
4493
|
}
|
|
4116
4494
|
}
|
|
4117
4495
|
function transformPoint(info, transformPagePoint) {
|
|
@@ -4321,10 +4699,9 @@ function resolveAxisElastic(dragElastic, minLabel, maxLabel) {
|
|
|
4321
4699
|
};
|
|
4322
4700
|
}
|
|
4323
4701
|
function resolvePointElastic(dragElastic, label) {
|
|
4324
|
-
var _a;
|
|
4325
4702
|
return typeof dragElastic === "number"
|
|
4326
4703
|
? dragElastic
|
|
4327
|
-
:
|
|
4704
|
+
: dragElastic[label] || 0;
|
|
4328
4705
|
}
|
|
4329
4706
|
|
|
4330
4707
|
const createAxisDelta = () => ({
|
|
@@ -4593,7 +4970,7 @@ class VisualElementDragControls {
|
|
|
4593
4970
|
/**
|
|
4594
4971
|
* If the MotionValue is a percentage value convert to px
|
|
4595
4972
|
*/
|
|
4596
|
-
if (
|
|
4973
|
+
if (percent.test(current)) {
|
|
4597
4974
|
const measuredAxis = (_b = (_a = this.visualElement.projection) === null || _a === void 0 ? void 0 : _a.layout) === null || _b === void 0 ? void 0 : _b.layoutBox[axis];
|
|
4598
4975
|
if (measuredAxis) {
|
|
4599
4976
|
const length = calcLength(measuredAxis);
|
|
@@ -4746,11 +5123,10 @@ class VisualElementDragControls {
|
|
|
4746
5123
|
const { drag, dragMomentum, dragElastic, dragTransition, dragSnapToOrigin, onDragTransitionEnd, } = this.getProps();
|
|
4747
5124
|
const constraints = this.constraints || {};
|
|
4748
5125
|
const momentumAnimations = eachAxis((axis) => {
|
|
4749
|
-
var _a;
|
|
4750
5126
|
if (!shouldDrag(axis, drag, this.currentDirection)) {
|
|
4751
5127
|
return;
|
|
4752
5128
|
}
|
|
4753
|
-
let transition = (
|
|
5129
|
+
let transition = (constraints === null || constraints === void 0 ? void 0 : constraints[axis]) || {};
|
|
4754
5130
|
if (dragSnapToOrigin)
|
|
4755
5131
|
transition = { min: 0, max: 0 };
|
|
4756
5132
|
/**
|
|
@@ -4794,12 +5170,12 @@ class VisualElementDragControls {
|
|
|
4794
5170
|
* - Otherwise, we apply the delta to the x/y motion values.
|
|
4795
5171
|
*/
|
|
4796
5172
|
getAxisMotionValue(axis) {
|
|
4797
|
-
var _a
|
|
5173
|
+
var _a;
|
|
4798
5174
|
const dragKey = "_drag" + axis.toUpperCase();
|
|
4799
5175
|
const externalMotionValue = this.visualElement.getProps()[dragKey];
|
|
4800
5176
|
return externalMotionValue
|
|
4801
5177
|
? externalMotionValue
|
|
4802
|
-
: this.visualElement.getValue(axis, (
|
|
5178
|
+
: this.visualElement.getValue(axis, ((_a = this.visualElement.getProps().initial) === null || _a === void 0 ? void 0 : _a[axis]) || 0);
|
|
4803
5179
|
}
|
|
4804
5180
|
snapToCursor(point) {
|
|
4805
5181
|
eachAxis((axis) => {
|
|
@@ -5123,7 +5499,7 @@ const setAndResetVelocity = (value, to) => {
|
|
|
5123
5499
|
value.set(to, false);
|
|
5124
5500
|
value.set(to);
|
|
5125
5501
|
};
|
|
5126
|
-
const isNumOrPxType = (v) => v ===
|
|
5502
|
+
const isNumOrPxType = (v) => v === number || v === px;
|
|
5127
5503
|
var BoundingBoxDimension;
|
|
5128
5504
|
(function (BoundingBoxDimension) {
|
|
5129
5505
|
BoundingBoxDimension["width"] = "width";
|
|
@@ -5259,7 +5635,7 @@ const checkAndConvertChangedValueTypes = (visualElement, target, origin = {}, tr
|
|
|
5259
5635
|
if (typeof to === "string") {
|
|
5260
5636
|
target[key] = parseFloat(to);
|
|
5261
5637
|
}
|
|
5262
|
-
else if (Array.isArray(to) && toType ===
|
|
5638
|
+
else if (Array.isArray(to) && toType === px) {
|
|
5263
5639
|
target[key] = to.map(parseFloat);
|
|
5264
5640
|
}
|
|
5265
5641
|
}
|
|
@@ -5377,7 +5753,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
5377
5753
|
* and warn against mismatches.
|
|
5378
5754
|
*/
|
|
5379
5755
|
if (process.env.NODE_ENV === "development") {
|
|
5380
|
-
warnOnce(nextValue.version === "7.7.
|
|
5756
|
+
warnOnce(nextValue.version === "7.7.2", `Attempting to mix Framer Motion versions ${nextValue.version} with 7.7.2 may not work as expected.`);
|
|
5381
5757
|
}
|
|
5382
5758
|
}
|
|
5383
5759
|
else if (isMotionValue(prevValue)) {
|
|
@@ -5494,7 +5870,7 @@ class VisualElement {
|
|
|
5494
5870
|
this.triggerBuild();
|
|
5495
5871
|
this.renderInstance(this.current, this.renderState, this.props.style, this.projection);
|
|
5496
5872
|
};
|
|
5497
|
-
this.scheduleRender = () =>
|
|
5873
|
+
this.scheduleRender = () => sync.render(this.render, false, true);
|
|
5498
5874
|
const { latestValues, renderState } = visualState;
|
|
5499
5875
|
this.latestValues = latestValues;
|
|
5500
5876
|
this.baseTarget = { ...latestValues };
|
|
@@ -5568,8 +5944,8 @@ class VisualElement {
|
|
|
5568
5944
|
unmount() {
|
|
5569
5945
|
var _a, _b, _c;
|
|
5570
5946
|
(_a = this.projection) === null || _a === void 0 ? void 0 : _a.unmount();
|
|
5571
|
-
|
|
5572
|
-
|
|
5947
|
+
cancelSync.update(this.notifyUpdate);
|
|
5948
|
+
cancelSync.render(this.render);
|
|
5573
5949
|
this.valueSubscriptions.forEach((remove) => remove());
|
|
5574
5950
|
(_b = this.removeFromVariantTree) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
5575
5951
|
(_c = this.parent) === null || _c === void 0 ? void 0 : _c.children.delete(this);
|
|
@@ -5583,7 +5959,7 @@ class VisualElement {
|
|
|
5583
5959
|
const removeOnChange = value.onChange((latestValue) => {
|
|
5584
5960
|
this.latestValues[key] = latestValue;
|
|
5585
5961
|
this.props.onUpdate &&
|
|
5586
|
-
|
|
5962
|
+
sync.update(this.notifyUpdate, false, true);
|
|
5587
5963
|
if (valueIsTransform && this.projection) {
|
|
5588
5964
|
this.projection.isTransformDirty = true;
|
|
5589
5965
|
}
|
|
@@ -6004,7 +6380,7 @@ const correctBorderRadius = {
|
|
|
6004
6380
|
* going to be stretched appropriately. Otherwise, if it's a pixel, convert it to a number.
|
|
6005
6381
|
*/
|
|
6006
6382
|
if (typeof latest === "string") {
|
|
6007
|
-
if (
|
|
6383
|
+
if (px.test(latest)) {
|
|
6008
6384
|
latest = parseFloat(latest);
|
|
6009
6385
|
}
|
|
6010
6386
|
else {
|
|
@@ -6036,11 +6412,11 @@ const correctBoxShadow = {
|
|
|
6036
6412
|
return varToken;
|
|
6037
6413
|
});
|
|
6038
6414
|
}
|
|
6039
|
-
const shadow =
|
|
6415
|
+
const shadow = complex.parse(latest);
|
|
6040
6416
|
// TODO: Doesn't support multiple shadows
|
|
6041
6417
|
if (shadow.length > 5)
|
|
6042
6418
|
return original;
|
|
6043
|
-
const template =
|
|
6419
|
+
const template = complex.createTransformer(latest);
|
|
6044
6420
|
const offset = typeof shadow[0] !== "number" ? 1 : 0;
|
|
6045
6421
|
// Calculate the overall context scale
|
|
6046
6422
|
const xScale = projectionDelta.x.scale * treeScale.x;
|
|
@@ -6131,7 +6507,7 @@ class MeasureLayoutWithContext extends React__default["default"].Component {
|
|
|
6131
6507
|
* it's in charge of the exit animation and therefore should
|
|
6132
6508
|
* be in charge of the safe to remove. Otherwise we call it here.
|
|
6133
6509
|
*/
|
|
6134
|
-
|
|
6510
|
+
sync.postRender(() => {
|
|
6135
6511
|
var _a;
|
|
6136
6512
|
if (!((_a = projection.getStack()) === null || _a === void 0 ? void 0 : _a.members.length)) {
|
|
6137
6513
|
this.safeToRemove();
|
|
@@ -6234,18 +6610,16 @@ function animate(from, to, transition = {}) {
|
|
|
6234
6610
|
const borders = ["TopLeft", "TopRight", "BottomLeft", "BottomRight"];
|
|
6235
6611
|
const numBorders = borders.length;
|
|
6236
6612
|
const asNumber = (value) => typeof value === "string" ? parseFloat(value) : value;
|
|
6237
|
-
const isPx = (value) => typeof value === "number" ||
|
|
6613
|
+
const isPx = (value) => typeof value === "number" || px.test(value);
|
|
6238
6614
|
function mixValues(target, follow, lead, progress, shouldCrossfadeOpacity, isOnlyMember) {
|
|
6239
|
-
var _a, _b, _c, _d;
|
|
6240
6615
|
if (shouldCrossfadeOpacity) {
|
|
6241
6616
|
target.opacity = mix(0,
|
|
6242
|
-
// (follow?.opacity as number) ?? 0,
|
|
6243
6617
|
// TODO Reinstate this if only child
|
|
6244
|
-
|
|
6245
|
-
target.opacityExit = mix(
|
|
6618
|
+
lead.opacity !== undefined ? lead.opacity : 1, easeCrossfadeIn(progress));
|
|
6619
|
+
target.opacityExit = mix(follow.opacity !== undefined ? follow.opacity : 1, 0, easeCrossfadeOut(progress));
|
|
6246
6620
|
}
|
|
6247
6621
|
else if (isOnlyMember) {
|
|
6248
|
-
target.opacity = mix(
|
|
6622
|
+
target.opacity = mix(follow.opacity !== undefined ? follow.opacity : 1, lead.opacity !== undefined ? lead.opacity : 1, progress);
|
|
6249
6623
|
}
|
|
6250
6624
|
/**
|
|
6251
6625
|
* Mix border radius
|
|
@@ -6263,7 +6637,7 @@ function mixValues(target, follow, lead, progress, shouldCrossfadeOpacity, isOnl
|
|
|
6263
6637
|
isPx(followRadius) === isPx(leadRadius);
|
|
6264
6638
|
if (canMix) {
|
|
6265
6639
|
target[borderLabel] = Math.max(mix(asNumber(followRadius), asNumber(leadRadius), progress), 0);
|
|
6266
|
-
if (
|
|
6640
|
+
if (percent.test(leadRadius) || percent.test(followRadius)) {
|
|
6267
6641
|
target[borderLabel] += "%";
|
|
6268
6642
|
}
|
|
6269
6643
|
}
|
|
@@ -6279,8 +6653,9 @@ function mixValues(target, follow, lead, progress, shouldCrossfadeOpacity, isOnl
|
|
|
6279
6653
|
}
|
|
6280
6654
|
}
|
|
6281
6655
|
function getRadius(values, radiusName) {
|
|
6282
|
-
|
|
6283
|
-
|
|
6656
|
+
return values[radiusName] !== undefined
|
|
6657
|
+
? values[radiusName]
|
|
6658
|
+
: values.borderRadius;
|
|
6284
6659
|
}
|
|
6285
6660
|
// /**
|
|
6286
6661
|
// * We only want to mix the background color if there's a follow element
|
|
@@ -6352,7 +6727,7 @@ function removePointDelta(point, translate, scale, originPoint, boxScale) {
|
|
|
6352
6727
|
* Remove a delta from an axis. This is essentially the steps of applyAxisDelta in reverse
|
|
6353
6728
|
*/
|
|
6354
6729
|
function removeAxisDelta(axis, translate = 0, scale = 1, origin = 0.5, boxScale, originAxis = axis, sourceAxis = axis) {
|
|
6355
|
-
if (
|
|
6730
|
+
if (percent.test(translate)) {
|
|
6356
6731
|
translate = parseFloat(translate);
|
|
6357
6732
|
const relativeProgress = mix(sourceAxis.min, sourceAxis.max, translate / 100);
|
|
6358
6733
|
translate = relativeProgress - sourceAxis.min;
|
|
@@ -6819,7 +7194,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6819
7194
|
(_a = this.getStack()) === null || _a === void 0 ? void 0 : _a.remove(this);
|
|
6820
7195
|
(_b = this.parent) === null || _b === void 0 ? void 0 : _b.children.delete(this);
|
|
6821
7196
|
this.instance = undefined;
|
|
6822
|
-
|
|
7197
|
+
cancelSync.preRender(this.updateProjection);
|
|
6823
7198
|
}
|
|
6824
7199
|
// only on the root
|
|
6825
7200
|
blockUpdate() {
|
|
@@ -6910,16 +7285,16 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6910
7285
|
this.nodes.forEach(notifyLayoutUpdate);
|
|
6911
7286
|
this.clearAllSnapshots();
|
|
6912
7287
|
// Flush any scheduled updates
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
7288
|
+
flushSync.update();
|
|
7289
|
+
flushSync.preRender();
|
|
7290
|
+
flushSync.render();
|
|
6916
7291
|
}
|
|
6917
7292
|
clearAllSnapshots() {
|
|
6918
7293
|
this.nodes.forEach(clearSnapshot);
|
|
6919
7294
|
this.sharedNodes.forEach(removeLeadSnapshots);
|
|
6920
7295
|
}
|
|
6921
7296
|
scheduleUpdateProjection() {
|
|
6922
|
-
|
|
7297
|
+
sync.preRender(this.updateProjection, false, true);
|
|
6923
7298
|
}
|
|
6924
7299
|
scheduleCheckAfterUnmount() {
|
|
6925
7300
|
/**
|
|
@@ -6927,7 +7302,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
6927
7302
|
* we manually call didUpdate to give a chance to the siblings to animate.
|
|
6928
7303
|
* Otherwise, cleanup all snapshots to prevents future nodes from reusing them.
|
|
6929
7304
|
*/
|
|
6930
|
-
|
|
7305
|
+
sync.postRender(() => {
|
|
6931
7306
|
if (this.isLayoutDirty) {
|
|
6932
7307
|
this.root.didUpdate();
|
|
6933
7308
|
}
|
|
@@ -7391,7 +7766,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
7391
7766
|
(_b = this.resumingFrom.currentAnimation) === null || _b === void 0 ? void 0 : _b.stop();
|
|
7392
7767
|
}
|
|
7393
7768
|
if (this.pendingAnimation) {
|
|
7394
|
-
|
|
7769
|
+
cancelSync.update(this.pendingAnimation);
|
|
7395
7770
|
this.pendingAnimation = undefined;
|
|
7396
7771
|
}
|
|
7397
7772
|
/**
|
|
@@ -7399,7 +7774,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
7399
7774
|
* where the target is the same as when the animation started, so we can
|
|
7400
7775
|
* calculate the relative positions correctly for instant transitions.
|
|
7401
7776
|
*/
|
|
7402
|
-
this.pendingAnimation =
|
|
7777
|
+
this.pendingAnimation = sync.update(() => {
|
|
7403
7778
|
globalProjectionState.hasAnimatedSinceResize = true;
|
|
7404
7779
|
this.currentAnimation = animate(0, animationTarget, {
|
|
7405
7780
|
...options,
|
|
@@ -7953,7 +8328,7 @@ function useForceUpdate() {
|
|
|
7953
8328
|
* Defer this to the end of the next animation frame in case there are multiple
|
|
7954
8329
|
* synchronous calls.
|
|
7955
8330
|
*/
|
|
7956
|
-
const deferredForceRender = React.useCallback(() =>
|
|
8331
|
+
const deferredForceRender = React.useCallback(() => sync.postRender(forceRender), [forceRender]);
|
|
7957
8332
|
return [deferredForceRender, forcedRenderCount];
|
|
7958
8333
|
}
|
|
7959
8334
|
|
|
@@ -8533,7 +8908,7 @@ function useCombineMotionValues(values, combineValues) {
|
|
|
8533
8908
|
* Subscribe to all motion values found within the template. Whenever any of them change,
|
|
8534
8909
|
* schedule an update.
|
|
8535
8910
|
*/
|
|
8536
|
-
useMultiOnChange(values, () =>
|
|
8911
|
+
useMultiOnChange(values, () => sync.update(updateValue, false, true), () => cancelSync.update(updateValue));
|
|
8537
8912
|
return value;
|
|
8538
8913
|
}
|
|
8539
8914
|
|
|
@@ -8771,8 +9146,8 @@ function useAnimationFrame(callback) {
|
|
|
8771
9146
|
initialTimestamp.current = timestamp;
|
|
8772
9147
|
callback(timestamp - initialTimestamp.current, delta);
|
|
8773
9148
|
};
|
|
8774
|
-
|
|
8775
|
-
return () =>
|
|
9149
|
+
sync.update(provideTimeSinceStart, true);
|
|
9150
|
+
return () => cancelSync.update(provideTimeSinceStart);
|
|
8776
9151
|
}, [callback]);
|
|
8777
9152
|
}
|
|
8778
9153
|
|
|
@@ -9176,7 +9551,7 @@ function useInstantTransition() {
|
|
|
9176
9551
|
/**
|
|
9177
9552
|
* Unblock after two animation frames, otherwise this will unblock too soon.
|
|
9178
9553
|
*/
|
|
9179
|
-
|
|
9554
|
+
sync.postRender(() => sync.postRender(() => (instantAnimationState.current = false)));
|
|
9180
9555
|
}, [forcedRenderCount]);
|
|
9181
9556
|
return (callback) => {
|
|
9182
9557
|
startInstantLayoutTransition(() => {
|