framer-motion 7.7.0 → 7.7.1
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 +529 -155
- package/dist/es/animation/legacy-popmotion/index.mjs +1 -1
- package/dist/es/animation/legacy-popmotion/inertia.mjs +2 -2
- package/dist/es/animation/utils/is-animatable.mjs +1 -1
- 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 +1 -1
- package/dist/es/motion/features/layout/MeasureLayout.mjs +1 -1
- package/dist/es/projection/animation/mix-values.mjs +1 -1
- 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/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 +284 -230
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/projection.dev.js +5451 -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
|
@@ -558,207 +558,52 @@
|
|
|
558
558
|
: value;
|
|
559
559
|
};
|
|
560
560
|
|
|
561
|
-
const clamp$
|
|
562
|
-
const sanitize = (v) => (v % 1 ? Number(v.toFixed(5)) : v);
|
|
563
|
-
const floatRegex = /(-)?([\d]*\.?[\d])+/g;
|
|
564
|
-
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;
|
|
565
|
-
const singleColorRegex = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2}(-?[\d\.]+%?)\s*[\,\/]?\s*[\d\.]*%?\))$/i;
|
|
566
|
-
function isString$1(v) {
|
|
567
|
-
return typeof v === 'string';
|
|
568
|
-
}
|
|
561
|
+
const clamp$1 = (min, max, v) => Math.min(Math.max(v, min), max);
|
|
569
562
|
|
|
570
563
|
const number = {
|
|
571
|
-
test: (v) => typeof v ===
|
|
564
|
+
test: (v) => typeof v === "number",
|
|
572
565
|
parse: parseFloat,
|
|
573
566
|
transform: (v) => v,
|
|
574
567
|
};
|
|
575
|
-
const alpha =
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
const createUnitType = (unit) => ({
|
|
579
|
-
test: (v) => isString$1(v) && v.endsWith(unit) && v.split(' ').length === 1,
|
|
580
|
-
parse: parseFloat,
|
|
581
|
-
transform: (v) => `${v}${unit}`,
|
|
582
|
-
});
|
|
583
|
-
const degrees = createUnitType('deg');
|
|
584
|
-
const percent = createUnitType('%');
|
|
585
|
-
const px = createUnitType('px');
|
|
586
|
-
const vh = createUnitType('vh');
|
|
587
|
-
const vw = createUnitType('vw');
|
|
588
|
-
const progressPercentage = Object.assign(Object.assign({}, percent), { parse: (v) => percent.parse(v) / 100, transform: (v) => percent.transform(v * 100) });
|
|
589
|
-
|
|
590
|
-
const isColorString = (type, testProp) => (v) => {
|
|
591
|
-
return Boolean((isString$1(v) && singleColorRegex.test(v) && v.startsWith(type)) ||
|
|
592
|
-
(testProp && Object.prototype.hasOwnProperty.call(v, testProp)));
|
|
593
|
-
};
|
|
594
|
-
const splitColor = (aName, bName, cName) => (v) => {
|
|
595
|
-
if (!isString$1(v))
|
|
596
|
-
return v;
|
|
597
|
-
const [a, b, c, alpha] = v.match(floatRegex);
|
|
598
|
-
return {
|
|
599
|
-
[aName]: parseFloat(a),
|
|
600
|
-
[bName]: parseFloat(b),
|
|
601
|
-
[cName]: parseFloat(c),
|
|
602
|
-
alpha: alpha !== undefined ? parseFloat(alpha) : 1,
|
|
603
|
-
};
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
const hsla = {
|
|
607
|
-
test: isColorString('hsl', 'hue'),
|
|
608
|
-
parse: splitColor('hue', 'saturation', 'lightness'),
|
|
609
|
-
transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
|
|
610
|
-
return ('hsla(' +
|
|
611
|
-
Math.round(hue) +
|
|
612
|
-
', ' +
|
|
613
|
-
percent.transform(sanitize(saturation)) +
|
|
614
|
-
', ' +
|
|
615
|
-
percent.transform(sanitize(lightness)) +
|
|
616
|
-
', ' +
|
|
617
|
-
sanitize(alpha.transform(alpha$1)) +
|
|
618
|
-
')');
|
|
619
|
-
},
|
|
568
|
+
const alpha = {
|
|
569
|
+
...number,
|
|
570
|
+
transform: (v) => clamp$1(0, 1, v),
|
|
620
571
|
};
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
const rgba = {
|
|
625
|
-
test: isColorString('rgb', 'red'),
|
|
626
|
-
parse: splitColor('red', 'green', 'blue'),
|
|
627
|
-
transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => 'rgba(' +
|
|
628
|
-
rgbUnit.transform(red) +
|
|
629
|
-
', ' +
|
|
630
|
-
rgbUnit.transform(green) +
|
|
631
|
-
', ' +
|
|
632
|
-
rgbUnit.transform(blue) +
|
|
633
|
-
', ' +
|
|
634
|
-
sanitize(alpha.transform(alpha$1)) +
|
|
635
|
-
')',
|
|
572
|
+
const scale = {
|
|
573
|
+
...number,
|
|
574
|
+
default: 1,
|
|
636
575
|
};
|
|
637
576
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
r = v.substr(1, 1);
|
|
651
|
-
g = v.substr(2, 1);
|
|
652
|
-
b = v.substr(3, 1);
|
|
653
|
-
a = v.substr(4, 1);
|
|
654
|
-
r += r;
|
|
655
|
-
g += g;
|
|
656
|
-
b += b;
|
|
657
|
-
a += a;
|
|
658
|
-
}
|
|
659
|
-
return {
|
|
660
|
-
red: parseInt(r, 16),
|
|
661
|
-
green: parseInt(g, 16),
|
|
662
|
-
blue: parseInt(b, 16),
|
|
663
|
-
alpha: a ? parseInt(a, 16) / 255 : 1,
|
|
664
|
-
};
|
|
577
|
+
/**
|
|
578
|
+
* TODO: When we move from string as a source of truth to data models
|
|
579
|
+
* everything in this folder should probably be referred to as models vs types
|
|
580
|
+
*/
|
|
581
|
+
// If this number is a decimal, make it just five decimal places
|
|
582
|
+
// to avoid exponents
|
|
583
|
+
const sanitize = (v) => Math.round(v * 100000) / 100000;
|
|
584
|
+
const floatRegex = /(-)?([\d]*\.?[\d])+/g;
|
|
585
|
+
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;
|
|
586
|
+
const singleColorRegex = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2}(-?[\d\.]+%?)\s*[\,\/]?\s*[\d\.]*%?\))$/i;
|
|
587
|
+
function isString$1(v) {
|
|
588
|
+
return typeof v === "string";
|
|
665
589
|
}
|
|
666
|
-
const hex = {
|
|
667
|
-
test: isColorString('#'),
|
|
668
|
-
parse: parseHex,
|
|
669
|
-
transform: rgba.transform,
|
|
670
|
-
};
|
|
671
590
|
|
|
672
|
-
const
|
|
673
|
-
test: (v) =>
|
|
674
|
-
parse:
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
transform: (v) =>
|
|
686
|
-
return isString$1(v)
|
|
687
|
-
? v
|
|
688
|
-
: v.hasOwnProperty('red')
|
|
689
|
-
? rgba.transform(v)
|
|
690
|
-
: hsla.transform(v);
|
|
691
|
-
},
|
|
591
|
+
const createUnitType = (unit) => ({
|
|
592
|
+
test: (v) => isString$1(v) && v.endsWith(unit) && v.split(" ").length === 1,
|
|
593
|
+
parse: parseFloat,
|
|
594
|
+
transform: (v) => `${v}${unit}`,
|
|
595
|
+
});
|
|
596
|
+
const degrees = createUnitType("deg");
|
|
597
|
+
const percent = createUnitType("%");
|
|
598
|
+
const px = createUnitType("px");
|
|
599
|
+
const vh = createUnitType("vh");
|
|
600
|
+
const vw = createUnitType("vw");
|
|
601
|
+
const progressPercentage = {
|
|
602
|
+
...percent,
|
|
603
|
+
parse: (v) => percent.parse(v) / 100,
|
|
604
|
+
transform: (v) => percent.transform(v * 100),
|
|
692
605
|
};
|
|
693
606
|
|
|
694
|
-
const colorToken = '${c}';
|
|
695
|
-
const numberToken = '${n}';
|
|
696
|
-
function test(v) {
|
|
697
|
-
var _a, _b, _c, _d;
|
|
698
|
-
return (isNaN(v) &&
|
|
699
|
-
isString$1(v) &&
|
|
700
|
-
((_b = (_a = v.match(floatRegex)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) + ((_d = (_c = v.match(colorRegex)) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) > 0);
|
|
701
|
-
}
|
|
702
|
-
function analyse$1(v) {
|
|
703
|
-
if (typeof v === 'number')
|
|
704
|
-
v = `${v}`;
|
|
705
|
-
const values = [];
|
|
706
|
-
let numColors = 0;
|
|
707
|
-
const colors = v.match(colorRegex);
|
|
708
|
-
if (colors) {
|
|
709
|
-
numColors = colors.length;
|
|
710
|
-
v = v.replace(colorRegex, colorToken);
|
|
711
|
-
values.push(...colors.map(color.parse));
|
|
712
|
-
}
|
|
713
|
-
const numbers = v.match(floatRegex);
|
|
714
|
-
if (numbers) {
|
|
715
|
-
v = v.replace(floatRegex, numberToken);
|
|
716
|
-
values.push(...numbers.map(number.parse));
|
|
717
|
-
}
|
|
718
|
-
return { values, numColors, tokenised: v };
|
|
719
|
-
}
|
|
720
|
-
function parse(v) {
|
|
721
|
-
return analyse$1(v).values;
|
|
722
|
-
}
|
|
723
|
-
function createTransformer(v) {
|
|
724
|
-
const { values, numColors, tokenised } = analyse$1(v);
|
|
725
|
-
const numValues = values.length;
|
|
726
|
-
return (v) => {
|
|
727
|
-
let output = tokenised;
|
|
728
|
-
for (let i = 0; i < numValues; i++) {
|
|
729
|
-
output = output.replace(i < numColors ? colorToken : numberToken, i < numColors ? color.transform(v[i]) : sanitize(v[i]));
|
|
730
|
-
}
|
|
731
|
-
return output;
|
|
732
|
-
};
|
|
733
|
-
}
|
|
734
|
-
const convertNumbersToZero = (v) => typeof v === 'number' ? 0 : v;
|
|
735
|
-
function getAnimatableNone$1(v) {
|
|
736
|
-
const parsed = parse(v);
|
|
737
|
-
const transformer = createTransformer(v);
|
|
738
|
-
return transformer(parsed.map(convertNumbersToZero));
|
|
739
|
-
}
|
|
740
|
-
const complex = { test, parse, createTransformer, getAnimatableNone: getAnimatableNone$1 };
|
|
741
|
-
|
|
742
|
-
const maxDefaults = new Set(['brightness', 'contrast', 'saturate', 'opacity']);
|
|
743
|
-
function applyDefaultFilter(v) {
|
|
744
|
-
let [name, value] = v.slice(0, -1).split('(');
|
|
745
|
-
if (name === 'drop-shadow')
|
|
746
|
-
return v;
|
|
747
|
-
const [number] = value.match(floatRegex) || [];
|
|
748
|
-
if (!number)
|
|
749
|
-
return v;
|
|
750
|
-
const unit = value.replace(number, '');
|
|
751
|
-
let defaultValue = maxDefaults.has(name) ? 1 : 0;
|
|
752
|
-
if (number !== value)
|
|
753
|
-
defaultValue *= 100;
|
|
754
|
-
return name + '(' + defaultValue + unit + ')';
|
|
755
|
-
}
|
|
756
|
-
const functionRegex = /([a-z-]*)\(.*?\)/g;
|
|
757
|
-
const filter = Object.assign(Object.assign({}, complex), { getAnimatableNone: (v) => {
|
|
758
|
-
const functions = v.match(functionRegex);
|
|
759
|
-
return functions ? functions.map(applyDefaultFilter).join(' ') : v;
|
|
760
|
-
} });
|
|
761
|
-
|
|
762
607
|
const int = {
|
|
763
608
|
...number,
|
|
764
609
|
transform: Math.round,
|
|
@@ -2154,6 +1999,175 @@
|
|
|
2154
1999
|
return Array.isArray(ease) && typeof ease[0] !== "number";
|
|
2155
2000
|
};
|
|
2156
2001
|
|
|
2002
|
+
/**
|
|
2003
|
+
* Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,
|
|
2004
|
+
* but false if a number or multiple colors
|
|
2005
|
+
*/
|
|
2006
|
+
const isColorString = (type, testProp) => (v) => {
|
|
2007
|
+
return Boolean((isString$1(v) && singleColorRegex.test(v) && v.startsWith(type)) ||
|
|
2008
|
+
(testProp && Object.prototype.hasOwnProperty.call(v, testProp)));
|
|
2009
|
+
};
|
|
2010
|
+
const splitColor = (aName, bName, cName) => (v) => {
|
|
2011
|
+
if (!isString$1(v))
|
|
2012
|
+
return v;
|
|
2013
|
+
const [a, b, c, alpha] = v.match(floatRegex);
|
|
2014
|
+
return {
|
|
2015
|
+
[aName]: parseFloat(a),
|
|
2016
|
+
[bName]: parseFloat(b),
|
|
2017
|
+
[cName]: parseFloat(c),
|
|
2018
|
+
alpha: alpha !== undefined ? parseFloat(alpha) : 1,
|
|
2019
|
+
};
|
|
2020
|
+
};
|
|
2021
|
+
|
|
2022
|
+
const clampRgbUnit = (v) => clamp$1(0, 255, v);
|
|
2023
|
+
const rgbUnit = {
|
|
2024
|
+
...number,
|
|
2025
|
+
transform: (v) => Math.round(clampRgbUnit(v)),
|
|
2026
|
+
};
|
|
2027
|
+
const rgba = {
|
|
2028
|
+
test: isColorString("rgb", "red"),
|
|
2029
|
+
parse: splitColor("red", "green", "blue"),
|
|
2030
|
+
transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" +
|
|
2031
|
+
rgbUnit.transform(red) +
|
|
2032
|
+
", " +
|
|
2033
|
+
rgbUnit.transform(green) +
|
|
2034
|
+
", " +
|
|
2035
|
+
rgbUnit.transform(blue) +
|
|
2036
|
+
", " +
|
|
2037
|
+
sanitize(alpha.transform(alpha$1)) +
|
|
2038
|
+
")",
|
|
2039
|
+
};
|
|
2040
|
+
|
|
2041
|
+
function parseHex(v) {
|
|
2042
|
+
let r = "";
|
|
2043
|
+
let g = "";
|
|
2044
|
+
let b = "";
|
|
2045
|
+
let a = "";
|
|
2046
|
+
// If we have 6 characters, ie #FF0000
|
|
2047
|
+
if (v.length > 5) {
|
|
2048
|
+
r = v.substring(1, 3);
|
|
2049
|
+
g = v.substring(3, 5);
|
|
2050
|
+
b = v.substring(5, 7);
|
|
2051
|
+
a = v.substring(7, 9);
|
|
2052
|
+
// Or we have 3 characters, ie #F00
|
|
2053
|
+
}
|
|
2054
|
+
else {
|
|
2055
|
+
r = v.substring(1, 2);
|
|
2056
|
+
g = v.substring(2, 3);
|
|
2057
|
+
b = v.substring(3, 4);
|
|
2058
|
+
a = v.substring(4, 5);
|
|
2059
|
+
r += r;
|
|
2060
|
+
g += g;
|
|
2061
|
+
b += b;
|
|
2062
|
+
a += a;
|
|
2063
|
+
}
|
|
2064
|
+
return {
|
|
2065
|
+
red: parseInt(r, 16),
|
|
2066
|
+
green: parseInt(g, 16),
|
|
2067
|
+
blue: parseInt(b, 16),
|
|
2068
|
+
alpha: a ? parseInt(a, 16) / 255 : 1,
|
|
2069
|
+
};
|
|
2070
|
+
}
|
|
2071
|
+
const hex = {
|
|
2072
|
+
test: isColorString("#"),
|
|
2073
|
+
parse: parseHex,
|
|
2074
|
+
transform: rgba.transform,
|
|
2075
|
+
};
|
|
2076
|
+
|
|
2077
|
+
const hsla = {
|
|
2078
|
+
test: isColorString("hsl", "hue"),
|
|
2079
|
+
parse: splitColor("hue", "saturation", "lightness"),
|
|
2080
|
+
transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
|
|
2081
|
+
return ("hsla(" +
|
|
2082
|
+
Math.round(hue) +
|
|
2083
|
+
", " +
|
|
2084
|
+
percent.transform(sanitize(saturation)) +
|
|
2085
|
+
", " +
|
|
2086
|
+
percent.transform(sanitize(lightness)) +
|
|
2087
|
+
", " +
|
|
2088
|
+
sanitize(alpha.transform(alpha$1)) +
|
|
2089
|
+
")");
|
|
2090
|
+
},
|
|
2091
|
+
};
|
|
2092
|
+
|
|
2093
|
+
const color = {
|
|
2094
|
+
test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
|
|
2095
|
+
parse: (v) => {
|
|
2096
|
+
if (rgba.test(v)) {
|
|
2097
|
+
return rgba.parse(v);
|
|
2098
|
+
}
|
|
2099
|
+
else if (hsla.test(v)) {
|
|
2100
|
+
return hsla.parse(v);
|
|
2101
|
+
}
|
|
2102
|
+
else {
|
|
2103
|
+
return hex.parse(v);
|
|
2104
|
+
}
|
|
2105
|
+
},
|
|
2106
|
+
transform: (v) => {
|
|
2107
|
+
return isString$1(v)
|
|
2108
|
+
? v
|
|
2109
|
+
: v.hasOwnProperty("red")
|
|
2110
|
+
? rgba.transform(v)
|
|
2111
|
+
: hsla.transform(v);
|
|
2112
|
+
},
|
|
2113
|
+
};
|
|
2114
|
+
|
|
2115
|
+
const colorToken = "${c}";
|
|
2116
|
+
const numberToken = "${n}";
|
|
2117
|
+
function test(v) {
|
|
2118
|
+
var _a, _b, _c, _d;
|
|
2119
|
+
return (isNaN(v) &&
|
|
2120
|
+
isString$1(v) &&
|
|
2121
|
+
((_b = (_a = v.match(floatRegex)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) +
|
|
2122
|
+
((_d = (_c = v.match(colorRegex)) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) >
|
|
2123
|
+
0);
|
|
2124
|
+
}
|
|
2125
|
+
function analyseComplexValue(v) {
|
|
2126
|
+
if (typeof v === "number")
|
|
2127
|
+
v = `${v}`;
|
|
2128
|
+
const values = [];
|
|
2129
|
+
let numColors = 0;
|
|
2130
|
+
let numNumbers = 0;
|
|
2131
|
+
const colors = v.match(colorRegex);
|
|
2132
|
+
if (colors) {
|
|
2133
|
+
numColors = colors.length;
|
|
2134
|
+
// Strip colors from input so they're not picked up by number regex.
|
|
2135
|
+
// There's a better way to combine these regex searches, but its beyond my regex skills
|
|
2136
|
+
v = v.replace(colorRegex, colorToken);
|
|
2137
|
+
values.push(...colors.map(color.parse));
|
|
2138
|
+
}
|
|
2139
|
+
const numbers = v.match(floatRegex);
|
|
2140
|
+
if (numbers) {
|
|
2141
|
+
numNumbers = numbers.length;
|
|
2142
|
+
v = v.replace(floatRegex, numberToken);
|
|
2143
|
+
values.push(...numbers.map(number.parse));
|
|
2144
|
+
}
|
|
2145
|
+
return { values, numColors, numNumbers, tokenised: v };
|
|
2146
|
+
}
|
|
2147
|
+
function parse(v) {
|
|
2148
|
+
return analyseComplexValue(v).values;
|
|
2149
|
+
}
|
|
2150
|
+
function createTransformer(source) {
|
|
2151
|
+
const { values, numColors, tokenised } = analyseComplexValue(source);
|
|
2152
|
+
const numValues = values.length;
|
|
2153
|
+
return (v) => {
|
|
2154
|
+
let output = tokenised;
|
|
2155
|
+
for (let i = 0; i < numValues; i++) {
|
|
2156
|
+
output = output.replace(i < numColors ? colorToken : numberToken, i < numColors
|
|
2157
|
+
? color.transform(v[i])
|
|
2158
|
+
: sanitize(v[i]));
|
|
2159
|
+
}
|
|
2160
|
+
return output;
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2163
|
+
const convertNumbersToZero = (v) => typeof v === "number" ? 0 : v;
|
|
2164
|
+
function getAnimatableNone$1(v) {
|
|
2165
|
+
const parsed = parse(v);
|
|
2166
|
+
const transformer = createTransformer(v);
|
|
2167
|
+
return transformer(parsed.map(convertNumbersToZero));
|
|
2168
|
+
}
|
|
2169
|
+
const complex = { test, parse, createTransformer, getAnimatableNone: getAnimatableNone$1 };
|
|
2170
|
+
|
|
2157
2171
|
/**
|
|
2158
2172
|
* Check if a value is animatable. Examples:
|
|
2159
2173
|
*
|
|
@@ -2231,6 +2245,32 @@
|
|
|
2231
2245
|
return { to, ...transitionFactory(to) };
|
|
2232
2246
|
};
|
|
2233
2247
|
|
|
2248
|
+
/**
|
|
2249
|
+
* Properties that should default to 1 or 100%
|
|
2250
|
+
*/
|
|
2251
|
+
const maxDefaults = new Set(["brightness", "contrast", "saturate", "opacity"]);
|
|
2252
|
+
function applyDefaultFilter(v) {
|
|
2253
|
+
const [name, value] = v.slice(0, -1).split("(");
|
|
2254
|
+
if (name === "drop-shadow")
|
|
2255
|
+
return v;
|
|
2256
|
+
const [number] = value.match(floatRegex) || [];
|
|
2257
|
+
if (!number)
|
|
2258
|
+
return v;
|
|
2259
|
+
const unit = value.replace(number, "");
|
|
2260
|
+
let defaultValue = maxDefaults.has(name) ? 1 : 0;
|
|
2261
|
+
if (number !== value)
|
|
2262
|
+
defaultValue *= 100;
|
|
2263
|
+
return name + "(" + defaultValue + unit + ")";
|
|
2264
|
+
}
|
|
2265
|
+
const functionRegex = /([a-z-]*)\(.*?\)/g;
|
|
2266
|
+
const filter = {
|
|
2267
|
+
...complex,
|
|
2268
|
+
getAnimatableNone: (v) => {
|
|
2269
|
+
const functions = v.match(functionRegex);
|
|
2270
|
+
return functions ? functions.map(applyDefaultFilter).join(" ") : v;
|
|
2271
|
+
},
|
|
2272
|
+
};
|
|
2273
|
+
|
|
2234
2274
|
/**
|
|
2235
2275
|
* A map of default value types for common values
|
|
2236
2276
|
*/
|
|
@@ -2269,6 +2309,9 @@
|
|
|
2269
2309
|
current: false,
|
|
2270
2310
|
};
|
|
2271
2311
|
|
|
2312
|
+
/*
|
|
2313
|
+
Detect and load appropriate clock setting for the execution environment
|
|
2314
|
+
*/
|
|
2272
2315
|
const defaultTimestep = (1 / 60) * 1000;
|
|
2273
2316
|
const getCurrentTime = typeof performance !== "undefined"
|
|
2274
2317
|
? () => performance.now()
|
|
@@ -2278,39 +2321,71 @@
|
|
|
2278
2321
|
: (callback) => setTimeout(() => callback(getCurrentTime()), defaultTimestep);
|
|
2279
2322
|
|
|
2280
2323
|
function createRenderStep(runNextFrame) {
|
|
2324
|
+
/**
|
|
2325
|
+
* We create and reuse two arrays, one to queue jobs for the current frame
|
|
2326
|
+
* and one for the next. We reuse to avoid triggering GC after x frames.
|
|
2327
|
+
*/
|
|
2281
2328
|
let toRun = [];
|
|
2282
2329
|
let toRunNextFrame = [];
|
|
2330
|
+
/**
|
|
2331
|
+
*
|
|
2332
|
+
*/
|
|
2283
2333
|
let numToRun = 0;
|
|
2334
|
+
/**
|
|
2335
|
+
* Track whether we're currently processing jobs in this step. This way
|
|
2336
|
+
* we can decide whether to schedule new jobs for this frame or next.
|
|
2337
|
+
*/
|
|
2284
2338
|
let isProcessing = false;
|
|
2285
2339
|
let flushNextFrame = false;
|
|
2340
|
+
/**
|
|
2341
|
+
* A set of processes which were marked keepAlive when scheduled.
|
|
2342
|
+
*/
|
|
2286
2343
|
const toKeepAlive = new WeakSet();
|
|
2287
2344
|
const step = {
|
|
2345
|
+
/**
|
|
2346
|
+
* Schedule a process to run on the next frame.
|
|
2347
|
+
*/
|
|
2288
2348
|
schedule: (callback, keepAlive = false, immediate = false) => {
|
|
2289
2349
|
const addToCurrentFrame = immediate && isProcessing;
|
|
2290
2350
|
const buffer = addToCurrentFrame ? toRun : toRunNextFrame;
|
|
2291
2351
|
if (keepAlive)
|
|
2292
2352
|
toKeepAlive.add(callback);
|
|
2353
|
+
// If the buffer doesn't already contain this callback, add it
|
|
2293
2354
|
if (buffer.indexOf(callback) === -1) {
|
|
2294
2355
|
buffer.push(callback);
|
|
2356
|
+
// If we're adding it to the currently running buffer, update its measured size
|
|
2295
2357
|
if (addToCurrentFrame && isProcessing)
|
|
2296
2358
|
numToRun = toRun.length;
|
|
2297
2359
|
}
|
|
2298
2360
|
return callback;
|
|
2299
2361
|
},
|
|
2362
|
+
/**
|
|
2363
|
+
* Cancel the provided callback from running on the next frame.
|
|
2364
|
+
*/
|
|
2300
2365
|
cancel: (callback) => {
|
|
2301
2366
|
const index = toRunNextFrame.indexOf(callback);
|
|
2302
2367
|
if (index !== -1)
|
|
2303
2368
|
toRunNextFrame.splice(index, 1);
|
|
2304
2369
|
toKeepAlive.delete(callback);
|
|
2305
2370
|
},
|
|
2371
|
+
/**
|
|
2372
|
+
* Execute all schedule callbacks.
|
|
2373
|
+
*/
|
|
2306
2374
|
process: (frameData) => {
|
|
2375
|
+
/**
|
|
2376
|
+
* If we're already processing we've probably been triggered by a flushSync
|
|
2377
|
+
* inside an existing process. Instead of executing, mark flushNextFrame
|
|
2378
|
+
* as true and ensure we flush the following frame at the end of this one.
|
|
2379
|
+
*/
|
|
2307
2380
|
if (isProcessing) {
|
|
2308
2381
|
flushNextFrame = true;
|
|
2309
2382
|
return;
|
|
2310
2383
|
}
|
|
2311
2384
|
isProcessing = true;
|
|
2312
2385
|
[toRun, toRunNextFrame] = [toRunNextFrame, toRun];
|
|
2386
|
+
// Clear the next frame list
|
|
2313
2387
|
toRunNextFrame.length = 0;
|
|
2388
|
+
// Execute this frame
|
|
2314
2389
|
numToRun = toRun.length;
|
|
2315
2390
|
if (numToRun) {
|
|
2316
2391
|
for (let i = 0; i < numToRun; i++) {
|
|
@@ -2332,14 +2407,15 @@
|
|
|
2332
2407
|
return step;
|
|
2333
2408
|
}
|
|
2334
2409
|
|
|
2410
|
+
const frameData = {
|
|
2411
|
+
delta: 0,
|
|
2412
|
+
timestamp: 0,
|
|
2413
|
+
};
|
|
2414
|
+
|
|
2335
2415
|
const maxElapsed$1 = 40;
|
|
2336
2416
|
let useDefaultElapsed = true;
|
|
2337
2417
|
let runNextFrame = false;
|
|
2338
2418
|
let isProcessing = false;
|
|
2339
|
-
const frame = {
|
|
2340
|
-
delta: 0,
|
|
2341
|
-
timestamp: 0,
|
|
2342
|
-
};
|
|
2343
2419
|
const stepsOrder = [
|
|
2344
2420
|
"read",
|
|
2345
2421
|
"update",
|
|
@@ -2365,16 +2441,16 @@
|
|
|
2365
2441
|
return acc;
|
|
2366
2442
|
}, {});
|
|
2367
2443
|
const flushSync = stepsOrder.reduce((acc, key) => {
|
|
2368
|
-
acc[key] = () => steps[key].process(
|
|
2444
|
+
acc[key] = () => steps[key].process(frameData);
|
|
2369
2445
|
return acc;
|
|
2370
2446
|
}, {});
|
|
2371
|
-
const processStep = (stepId) => steps[stepId].process(
|
|
2447
|
+
const processStep = (stepId) => steps[stepId].process(frameData);
|
|
2372
2448
|
const processFrame = (timestamp) => {
|
|
2373
2449
|
runNextFrame = false;
|
|
2374
|
-
|
|
2450
|
+
frameData.delta = useDefaultElapsed
|
|
2375
2451
|
? defaultTimestep
|
|
2376
|
-
: Math.max(Math.min(timestamp -
|
|
2377
|
-
|
|
2452
|
+
: Math.max(Math.min(timestamp - frameData.timestamp, maxElapsed$1), 1);
|
|
2453
|
+
frameData.timestamp = timestamp;
|
|
2378
2454
|
isProcessing = true;
|
|
2379
2455
|
stepsOrder.forEach(processStep);
|
|
2380
2456
|
isProcessing = false;
|
|
@@ -2389,7 +2465,6 @@
|
|
|
2389
2465
|
if (!isProcessing)
|
|
2390
2466
|
onNextFrame(processFrame);
|
|
2391
2467
|
};
|
|
2392
|
-
const getFrameData = () => frame;
|
|
2393
2468
|
|
|
2394
2469
|
function delay(callback, timeout) {
|
|
2395
2470
|
const start = performance.now();
|
|
@@ -2404,8 +2479,6 @@
|
|
|
2404
2479
|
return () => cancelSync.read(checkElapsed);
|
|
2405
2480
|
}
|
|
2406
2481
|
|
|
2407
|
-
const clamp$1 = (min, max, v) => Math.min(Math.max(v, min), max);
|
|
2408
|
-
|
|
2409
2482
|
/*
|
|
2410
2483
|
Value in range from progress
|
|
2411
2484
|
|
|
@@ -2484,6 +2557,7 @@
|
|
|
2484
2557
|
invariant(Boolean(type), `'${color}' is not an animatable color. Use the equivalent color code instead.`);
|
|
2485
2558
|
let model = type.parse(color);
|
|
2486
2559
|
if (type === hsla) {
|
|
2560
|
+
// TODO Remove this cast - needed since Framer Motion's stricter typing
|
|
2487
2561
|
model = hslaToRgba(model);
|
|
2488
2562
|
}
|
|
2489
2563
|
return model;
|
|
@@ -2538,34 +2612,14 @@
|
|
|
2538
2612
|
return output;
|
|
2539
2613
|
};
|
|
2540
2614
|
};
|
|
2541
|
-
/**
|
|
2542
|
-
* TODO: Combine with function within complex when style-value-types moved inside Framer Motion
|
|
2543
|
-
*/
|
|
2544
|
-
function analyse(value) {
|
|
2545
|
-
const parsed = complex.parse(value);
|
|
2546
|
-
const numValues = parsed.length;
|
|
2547
|
-
let numNumbers = 0;
|
|
2548
|
-
let numColors = 0;
|
|
2549
|
-
for (let i = 0; i < numValues; i++) {
|
|
2550
|
-
// Parsed complex values return with colors first, so if we've seen any number
|
|
2551
|
-
// we're already past that part of the array and don't need to continue running typeof
|
|
2552
|
-
if (numNumbers || typeof parsed[i] === "number") {
|
|
2553
|
-
numNumbers++;
|
|
2554
|
-
}
|
|
2555
|
-
else {
|
|
2556
|
-
numColors++;
|
|
2557
|
-
}
|
|
2558
|
-
}
|
|
2559
|
-
return { parsed, numNumbers, numColors };
|
|
2560
|
-
}
|
|
2561
2615
|
const mixComplex = (origin, target) => {
|
|
2562
2616
|
const template = complex.createTransformer(target);
|
|
2563
|
-
const originStats =
|
|
2564
|
-
const targetStats =
|
|
2617
|
+
const originStats = analyseComplexValue(origin);
|
|
2618
|
+
const targetStats = analyseComplexValue(target);
|
|
2565
2619
|
const canInterpolate = originStats.numColors === targetStats.numColors &&
|
|
2566
2620
|
originStats.numNumbers >= targetStats.numNumbers;
|
|
2567
2621
|
if (canInterpolate) {
|
|
2568
|
-
return pipe(mixArray(originStats.
|
|
2622
|
+
return pipe(mixArray(originStats.values, targetStats.values), template);
|
|
2569
2623
|
}
|
|
2570
2624
|
else {
|
|
2571
2625
|
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.`);
|
|
@@ -3134,7 +3188,7 @@
|
|
|
3134
3188
|
const checkBoundary = (v) => {
|
|
3135
3189
|
prev = current;
|
|
3136
3190
|
current = v;
|
|
3137
|
-
velocity = velocityPerSecond$1(v - prev,
|
|
3191
|
+
velocity = velocityPerSecond$1(v - prev, frameData.delta);
|
|
3138
3192
|
if ((heading === 1 && v > boundary) ||
|
|
3139
3193
|
(heading === -1 && v < boundary)) {
|
|
3140
3194
|
startSpring({ from: v, to: boundary, velocity });
|
|
@@ -3425,7 +3479,7 @@
|
|
|
3425
3479
|
* This will be replaced by the build step with the latest version number.
|
|
3426
3480
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
3427
3481
|
*/
|
|
3428
|
-
this.version = "7.7.
|
|
3482
|
+
this.version = "7.7.1";
|
|
3429
3483
|
/**
|
|
3430
3484
|
* Duration, in milliseconds, since last updating frame.
|
|
3431
3485
|
*
|
|
@@ -3468,7 +3522,7 @@
|
|
|
3468
3522
|
this.prev = this.current;
|
|
3469
3523
|
this.current = v;
|
|
3470
3524
|
// Update timestamp
|
|
3471
|
-
const { delta, timestamp } =
|
|
3525
|
+
const { delta, timestamp } = frameData;
|
|
3472
3526
|
if (this.lastUpdated !== timestamp) {
|
|
3473
3527
|
this.timeDelta = delta;
|
|
3474
3528
|
this.lastUpdated = timestamp;
|
|
@@ -4395,7 +4449,7 @@
|
|
|
4395
4449
|
if (!isPanStarted && !isDistancePastThreshold)
|
|
4396
4450
|
return;
|
|
4397
4451
|
const { point } = info;
|
|
4398
|
-
const { timestamp } =
|
|
4452
|
+
const { timestamp } = frameData;
|
|
4399
4453
|
this.history.push({ ...point, timestamp });
|
|
4400
4454
|
const { onStart, onMove } = this.handlers;
|
|
4401
4455
|
if (!isPanStarted) {
|
|
@@ -4432,7 +4486,7 @@
|
|
|
4432
4486
|
const info = extractEventInfo(event);
|
|
4433
4487
|
const initialInfo = transformPoint(info, this.transformPagePoint);
|
|
4434
4488
|
const { point } = initialInfo;
|
|
4435
|
-
const { timestamp } =
|
|
4489
|
+
const { timestamp } = frameData;
|
|
4436
4490
|
this.history = [{ ...point, timestamp }];
|
|
4437
4491
|
const { onSessionStart } = handlers;
|
|
4438
4492
|
onSessionStart &&
|
|
@@ -5710,7 +5764,7 @@
|
|
|
5710
5764
|
* and warn against mismatches.
|
|
5711
5765
|
*/
|
|
5712
5766
|
{
|
|
5713
|
-
warnOnce(nextValue.version === "7.7.
|
|
5767
|
+
warnOnce(nextValue.version === "7.7.1", `Attempting to mix Framer Motion versions ${nextValue.version} with 7.7.1 may not work as expected.`);
|
|
5714
5768
|
}
|
|
5715
5769
|
}
|
|
5716
5770
|
else if (isMotionValue(prevValue)) {
|