motion 11.16.3 → 11.16.6
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 +664 -663
- package/dist/cjs/mini.js +1 -1
- package/dist/cjs/react-client.js +531 -529
- package/dist/cjs/react-m.js +6 -6
- package/dist/cjs/react-mini.js +1 -1
- package/dist/es/framer-motion/dist/es/animation/interfaces/visual-element-target.mjs +2 -2
- package/dist/es/framer-motion/dist/es/animation/optimized-appear/store-id.mjs +1 -1
- package/dist/es/framer-motion/dist/es/animation/utils/default-transitions.mjs +1 -1
- package/dist/es/framer-motion/dist/es/motion/utils/is-forced-motion-value.mjs +1 -1
- package/dist/es/framer-motion/dist/es/render/VisualElement.mjs +12 -12
- package/dist/es/framer-motion/dist/es/render/dom/DOMKeyframesResolver.mjs +4 -3
- package/dist/es/framer-motion/dist/es/render/dom/scroll/offsets/index.mjs +6 -5
- package/dist/es/framer-motion/dist/es/render/dom/utils/unit-conversion.mjs +2 -14
- package/dist/es/framer-motion/dist/es/render/html/HTMLVisualElement.mjs +6 -6
- package/dist/es/framer-motion/dist/es/render/html/utils/build-styles.mjs +2 -2
- package/dist/es/framer-motion/dist/es/render/html/utils/build-transform.mjs +1 -1
- package/dist/es/framer-motion/dist/es/render/html/utils/keys-position.mjs +13 -0
- package/dist/es/framer-motion/dist/es/render/svg/SVGVisualElement.mjs +6 -6
- package/dist/es/framer-motion/dist/es/render/svg/utils/scrape-motion-values.mjs +1 -1
- package/dist/es/framer-motion/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/framer-motion/dist/es/utils/interpolate.mjs +4 -1
- package/dist/es/framer-motion/dist/es/value/index.mjs +1 -1
- package/dist/es/framer-motion/dist/es/value/use-will-change/get-will-change-name.mjs +1 -1
- package/dist/es/motion-dom/dist/es/animation/controls/BaseGroup.mjs +1 -1
- package/dist/es/motion-dom/dist/es/gestures/press/utils/is-keyboard-accessible.mjs +2 -1
- package/dist/motion.dev.js +664 -663
- package/dist/motion.js +1 -1
- package/package.json +3 -3
- /package/dist/es/framer-motion/dist/es/render/html/utils/{transform.mjs → keys-transform.mjs} +0 -0
package/dist/cjs/react-client.js
CHANGED
|
@@ -166,7 +166,7 @@ class BaseGroupPlaybackControls {
|
|
|
166
166
|
if (supportsScrollTimeline() && animation.attachTimeline) {
|
|
167
167
|
return animation.attachTimeline(timeline);
|
|
168
168
|
}
|
|
169
|
-
else {
|
|
169
|
+
else if (typeof fallback === "function") {
|
|
170
170
|
return fallback(animation);
|
|
171
171
|
}
|
|
172
172
|
});
|
|
@@ -461,7 +461,8 @@ const focusableElements = new Set([
|
|
|
461
461
|
"A",
|
|
462
462
|
]);
|
|
463
463
|
function isElementKeyboardAccessible(element) {
|
|
464
|
-
return focusableElements.has(element.tagName) ||
|
|
464
|
+
return (focusableElements.has(element.tagName) ||
|
|
465
|
+
element.tabIndex !== -1);
|
|
465
466
|
}
|
|
466
467
|
|
|
467
468
|
const isPressing = new WeakSet();
|
|
@@ -620,6 +621,16 @@ const transformPropOrder = [
|
|
|
620
621
|
*/
|
|
621
622
|
const transformProps = new Set(transformPropOrder);
|
|
622
623
|
|
|
624
|
+
const positionalKeys = new Set([
|
|
625
|
+
"width",
|
|
626
|
+
"height",
|
|
627
|
+
"top",
|
|
628
|
+
"left",
|
|
629
|
+
"right",
|
|
630
|
+
"bottom",
|
|
631
|
+
...transformPropOrder,
|
|
632
|
+
]);
|
|
633
|
+
|
|
623
634
|
const isCustomValue = (v) => {
|
|
624
635
|
return Boolean(v && typeof v === "object" && v.mix && v.toValue);
|
|
625
636
|
};
|
|
@@ -904,7 +915,7 @@ class MotionValue {
|
|
|
904
915
|
* This will be replaced by the build step with the latest version number.
|
|
905
916
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
906
917
|
*/
|
|
907
|
-
this.version = "11.16.
|
|
918
|
+
this.version = "11.16.6";
|
|
908
919
|
/**
|
|
909
920
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
910
921
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -1317,62 +1328,6 @@ function isNone(value) {
|
|
|
1317
1328
|
}
|
|
1318
1329
|
}
|
|
1319
1330
|
|
|
1320
|
-
/**
|
|
1321
|
-
* Check if value is a numerical string, ie a string that is purely a number eg "100" or "-100.1"
|
|
1322
|
-
*/
|
|
1323
|
-
const isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v);
|
|
1324
|
-
|
|
1325
|
-
const checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
|
|
1326
|
-
const isCSSVariableName =
|
|
1327
|
-
/*@__PURE__*/ checkStringStartsWith("--");
|
|
1328
|
-
const startsAsVariableToken =
|
|
1329
|
-
/*@__PURE__*/ checkStringStartsWith("var(--");
|
|
1330
|
-
const isCSSVariableToken = (value) => {
|
|
1331
|
-
const startsWithToken = startsAsVariableToken(value);
|
|
1332
|
-
if (!startsWithToken)
|
|
1333
|
-
return false;
|
|
1334
|
-
// Ensure any comments are stripped from the value as this can harm performance of the regex.
|
|
1335
|
-
return singleCssVariableRegex.test(value.split("/*")[0].trim());
|
|
1336
|
-
};
|
|
1337
|
-
const singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
|
|
1338
|
-
|
|
1339
|
-
/**
|
|
1340
|
-
* Parse Framer's special CSS variable format into a CSS token and a fallback.
|
|
1341
|
-
*
|
|
1342
|
-
* ```
|
|
1343
|
-
* `var(--foo, #fff)` => [`--foo`, '#fff']
|
|
1344
|
-
* ```
|
|
1345
|
-
*
|
|
1346
|
-
* @param current
|
|
1347
|
-
*/
|
|
1348
|
-
const splitCSSVariableRegex =
|
|
1349
|
-
// eslint-disable-next-line redos-detector/no-unsafe-regex -- false positive, as it can match a lot of words
|
|
1350
|
-
/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;
|
|
1351
|
-
function parseCSSVariable(current) {
|
|
1352
|
-
const match = splitCSSVariableRegex.exec(current);
|
|
1353
|
-
if (!match)
|
|
1354
|
-
return [,];
|
|
1355
|
-
const [, token1, token2, fallback] = match;
|
|
1356
|
-
return [`--${token1 !== null && token1 !== void 0 ? token1 : token2}`, fallback];
|
|
1357
|
-
}
|
|
1358
|
-
const maxDepth = 4;
|
|
1359
|
-
function getVariableValue(current, element, depth = 1) {
|
|
1360
|
-
invariant(depth <= maxDepth, `Max CSS variable fallback depth detected in property "${current}". This may indicate a circular fallback dependency.`);
|
|
1361
|
-
const [token, fallback] = parseCSSVariable(current);
|
|
1362
|
-
// No CSS variable detected
|
|
1363
|
-
if (!token)
|
|
1364
|
-
return;
|
|
1365
|
-
// Attempt to read this CSS variable off the element
|
|
1366
|
-
const resolved = window.getComputedStyle(element).getPropertyValue(token);
|
|
1367
|
-
if (resolved) {
|
|
1368
|
-
const trimmed = resolved.trim();
|
|
1369
|
-
return isNumericalString(trimmed) ? parseFloat(trimmed) : trimmed;
|
|
1370
|
-
}
|
|
1371
|
-
return isCSSVariableToken(fallback)
|
|
1372
|
-
? getVariableValue(fallback, element, depth + 1)
|
|
1373
|
-
: fallback;
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
1331
|
const clamp = (min, max, v) => {
|
|
1377
1332
|
if (v > max)
|
|
1378
1333
|
return max;
|
|
@@ -1395,6 +1350,97 @@ const scale = {
|
|
|
1395
1350
|
default: 1,
|
|
1396
1351
|
};
|
|
1397
1352
|
|
|
1353
|
+
// If this number is a decimal, make it just five decimal places
|
|
1354
|
+
// to avoid exponents
|
|
1355
|
+
const sanitize = (v) => Math.round(v * 100000) / 100000;
|
|
1356
|
+
|
|
1357
|
+
const floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu;
|
|
1358
|
+
|
|
1359
|
+
function isNullish(v) {
|
|
1360
|
+
return v == null;
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
const singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu;
|
|
1364
|
+
|
|
1365
|
+
/**
|
|
1366
|
+
* Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,
|
|
1367
|
+
* but false if a number or multiple colors
|
|
1368
|
+
*/
|
|
1369
|
+
const isColorString = (type, testProp) => (v) => {
|
|
1370
|
+
return Boolean((typeof v === "string" &&
|
|
1371
|
+
singleColorRegex.test(v) &&
|
|
1372
|
+
v.startsWith(type)) ||
|
|
1373
|
+
(testProp &&
|
|
1374
|
+
!isNullish(v) &&
|
|
1375
|
+
Object.prototype.hasOwnProperty.call(v, testProp)));
|
|
1376
|
+
};
|
|
1377
|
+
const splitColor = (aName, bName, cName) => (v) => {
|
|
1378
|
+
if (typeof v !== "string")
|
|
1379
|
+
return v;
|
|
1380
|
+
const [a, b, c, alpha] = v.match(floatRegex);
|
|
1381
|
+
return {
|
|
1382
|
+
[aName]: parseFloat(a),
|
|
1383
|
+
[bName]: parseFloat(b),
|
|
1384
|
+
[cName]: parseFloat(c),
|
|
1385
|
+
alpha: alpha !== undefined ? parseFloat(alpha) : 1,
|
|
1386
|
+
};
|
|
1387
|
+
};
|
|
1388
|
+
|
|
1389
|
+
const clampRgbUnit = (v) => clamp(0, 255, v);
|
|
1390
|
+
const rgbUnit = {
|
|
1391
|
+
...number,
|
|
1392
|
+
transform: (v) => Math.round(clampRgbUnit(v)),
|
|
1393
|
+
};
|
|
1394
|
+
const rgba = {
|
|
1395
|
+
test: /*@__PURE__*/ isColorString("rgb", "red"),
|
|
1396
|
+
parse: /*@__PURE__*/ splitColor("red", "green", "blue"),
|
|
1397
|
+
transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" +
|
|
1398
|
+
rgbUnit.transform(red) +
|
|
1399
|
+
", " +
|
|
1400
|
+
rgbUnit.transform(green) +
|
|
1401
|
+
", " +
|
|
1402
|
+
rgbUnit.transform(blue) +
|
|
1403
|
+
", " +
|
|
1404
|
+
sanitize(alpha.transform(alpha$1)) +
|
|
1405
|
+
")",
|
|
1406
|
+
};
|
|
1407
|
+
|
|
1408
|
+
function parseHex(v) {
|
|
1409
|
+
let r = "";
|
|
1410
|
+
let g = "";
|
|
1411
|
+
let b = "";
|
|
1412
|
+
let a = "";
|
|
1413
|
+
// If we have 6 characters, ie #FF0000
|
|
1414
|
+
if (v.length > 5) {
|
|
1415
|
+
r = v.substring(1, 3);
|
|
1416
|
+
g = v.substring(3, 5);
|
|
1417
|
+
b = v.substring(5, 7);
|
|
1418
|
+
a = v.substring(7, 9);
|
|
1419
|
+
// Or we have 3 characters, ie #F00
|
|
1420
|
+
}
|
|
1421
|
+
else {
|
|
1422
|
+
r = v.substring(1, 2);
|
|
1423
|
+
g = v.substring(2, 3);
|
|
1424
|
+
b = v.substring(3, 4);
|
|
1425
|
+
a = v.substring(4, 5);
|
|
1426
|
+
r += r;
|
|
1427
|
+
g += g;
|
|
1428
|
+
b += b;
|
|
1429
|
+
a += a;
|
|
1430
|
+
}
|
|
1431
|
+
return {
|
|
1432
|
+
red: parseInt(r, 16),
|
|
1433
|
+
green: parseInt(g, 16),
|
|
1434
|
+
blue: parseInt(b, 16),
|
|
1435
|
+
alpha: a ? parseInt(a, 16) / 255 : 1,
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
const hex = {
|
|
1439
|
+
test: /*@__PURE__*/ isColorString("#"),
|
|
1440
|
+
parse: parseHex,
|
|
1441
|
+
transform: rgba.transform,
|
|
1442
|
+
};
|
|
1443
|
+
|
|
1398
1444
|
const createUnitType = (unit) => ({
|
|
1399
1445
|
test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
|
|
1400
1446
|
parse: parseFloat,
|
|
@@ -1411,87 +1457,347 @@ const progressPercentage = {
|
|
|
1411
1457
|
transform: (v) => percent.transform(v * 100),
|
|
1412
1458
|
};
|
|
1413
1459
|
|
|
1414
|
-
const
|
|
1415
|
-
"
|
|
1416
|
-
"
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
else {
|
|
1436
|
-
const matrix = transform.match(/^matrix\((.+)\)$/u);
|
|
1437
|
-
if (matrix) {
|
|
1438
|
-
return getPosFromMatrix(matrix[1], pos2);
|
|
1460
|
+
const hsla = {
|
|
1461
|
+
test: /*@__PURE__*/ isColorString("hsl", "hue"),
|
|
1462
|
+
parse: /*@__PURE__*/ splitColor("hue", "saturation", "lightness"),
|
|
1463
|
+
transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
|
|
1464
|
+
return ("hsla(" +
|
|
1465
|
+
Math.round(hue) +
|
|
1466
|
+
", " +
|
|
1467
|
+
percent.transform(sanitize(saturation)) +
|
|
1468
|
+
", " +
|
|
1469
|
+
percent.transform(sanitize(lightness)) +
|
|
1470
|
+
", " +
|
|
1471
|
+
sanitize(alpha.transform(alpha$1)) +
|
|
1472
|
+
")");
|
|
1473
|
+
},
|
|
1474
|
+
};
|
|
1475
|
+
|
|
1476
|
+
const color = {
|
|
1477
|
+
test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
|
|
1478
|
+
parse: (v) => {
|
|
1479
|
+
if (rgba.test(v)) {
|
|
1480
|
+
return rgba.parse(v);
|
|
1439
1481
|
}
|
|
1440
|
-
else {
|
|
1441
|
-
return
|
|
1482
|
+
else if (hsla.test(v)) {
|
|
1483
|
+
return hsla.parse(v);
|
|
1442
1484
|
}
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
const transformKeys = new Set(["x", "y", "z"]);
|
|
1446
|
-
const nonTranslationalTransformKeys = transformPropOrder.filter((key) => !transformKeys.has(key));
|
|
1447
|
-
function removeNonTranslationalTransform(visualElement) {
|
|
1448
|
-
const removedTransforms = [];
|
|
1449
|
-
nonTranslationalTransformKeys.forEach((key) => {
|
|
1450
|
-
const value = visualElement.getValue(key);
|
|
1451
|
-
if (value !== undefined) {
|
|
1452
|
-
removedTransforms.push([key, value.get()]);
|
|
1453
|
-
value.set(key.startsWith("scale") ? 1 : 0);
|
|
1485
|
+
else {
|
|
1486
|
+
return hex.parse(v);
|
|
1454
1487
|
}
|
|
1455
|
-
}
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
left: (_bbox, { left }) => parseFloat(left),
|
|
1464
|
-
bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
|
|
1465
|
-
right: ({ x }, { left }) => parseFloat(left) + (x.max - x.min),
|
|
1466
|
-
// Transform
|
|
1467
|
-
x: getTranslateFromMatrix(4, 13),
|
|
1468
|
-
y: getTranslateFromMatrix(5, 14),
|
|
1488
|
+
},
|
|
1489
|
+
transform: (v) => {
|
|
1490
|
+
return typeof v === "string"
|
|
1491
|
+
? v
|
|
1492
|
+
: v.hasOwnProperty("red")
|
|
1493
|
+
? rgba.transform(v)
|
|
1494
|
+
: hsla.transform(v);
|
|
1495
|
+
},
|
|
1469
1496
|
};
|
|
1470
|
-
// Alias translate longform names
|
|
1471
|
-
positionalValues.translateX = positionalValues.x;
|
|
1472
|
-
positionalValues.translateY = positionalValues.y;
|
|
1473
1497
|
|
|
1474
|
-
|
|
1475
|
-
* Tests a provided value against a ValueType
|
|
1476
|
-
*/
|
|
1477
|
-
const testValueType = (v) => (type) => type.test(v);
|
|
1498
|
+
const colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;
|
|
1478
1499
|
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1500
|
+
function test(v) {
|
|
1501
|
+
var _a, _b;
|
|
1502
|
+
return (isNaN(v) &&
|
|
1503
|
+
typeof v === "string" &&
|
|
1504
|
+
(((_a = v.match(floatRegex)) === null || _a === void 0 ? void 0 : _a.length) || 0) +
|
|
1505
|
+
(((_b = v.match(colorRegex)) === null || _b === void 0 ? void 0 : _b.length) || 0) >
|
|
1506
|
+
0);
|
|
1507
|
+
}
|
|
1508
|
+
const NUMBER_TOKEN = "number";
|
|
1509
|
+
const COLOR_TOKEN = "color";
|
|
1510
|
+
const VAR_TOKEN = "var";
|
|
1511
|
+
const VAR_FUNCTION_TOKEN = "var(";
|
|
1512
|
+
const SPLIT_TOKEN = "${}";
|
|
1513
|
+
// this regex consists of the `singleCssVariableRegex|rgbHSLValueRegex|digitRegex`
|
|
1514
|
+
const complexRegex = /var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;
|
|
1515
|
+
function analyseComplexValue(value) {
|
|
1516
|
+
const originalValue = value.toString();
|
|
1517
|
+
const values = [];
|
|
1518
|
+
const indexes = {
|
|
1519
|
+
color: [],
|
|
1520
|
+
number: [],
|
|
1521
|
+
var: [],
|
|
1522
|
+
};
|
|
1523
|
+
const types = [];
|
|
1524
|
+
let i = 0;
|
|
1525
|
+
const tokenised = originalValue.replace(complexRegex, (parsedValue) => {
|
|
1526
|
+
if (color.test(parsedValue)) {
|
|
1527
|
+
indexes.color.push(i);
|
|
1528
|
+
types.push(COLOR_TOKEN);
|
|
1529
|
+
values.push(color.parse(parsedValue));
|
|
1530
|
+
}
|
|
1531
|
+
else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {
|
|
1532
|
+
indexes.var.push(i);
|
|
1533
|
+
types.push(VAR_TOKEN);
|
|
1534
|
+
values.push(parsedValue);
|
|
1535
|
+
}
|
|
1536
|
+
else {
|
|
1537
|
+
indexes.number.push(i);
|
|
1538
|
+
types.push(NUMBER_TOKEN);
|
|
1539
|
+
values.push(parseFloat(parsedValue));
|
|
1540
|
+
}
|
|
1541
|
+
++i;
|
|
1542
|
+
return SPLIT_TOKEN;
|
|
1543
|
+
});
|
|
1544
|
+
const split = tokenised.split(SPLIT_TOKEN);
|
|
1545
|
+
return { values, split, indexes, types };
|
|
1546
|
+
}
|
|
1547
|
+
function parseComplexValue(v) {
|
|
1548
|
+
return analyseComplexValue(v).values;
|
|
1549
|
+
}
|
|
1550
|
+
function createTransformer(source) {
|
|
1551
|
+
const { split, types } = analyseComplexValue(source);
|
|
1552
|
+
const numSections = split.length;
|
|
1553
|
+
return (v) => {
|
|
1554
|
+
let output = "";
|
|
1555
|
+
for (let i = 0; i < numSections; i++) {
|
|
1556
|
+
output += split[i];
|
|
1557
|
+
if (v[i] !== undefined) {
|
|
1558
|
+
const type = types[i];
|
|
1559
|
+
if (type === NUMBER_TOKEN) {
|
|
1560
|
+
output += sanitize(v[i]);
|
|
1561
|
+
}
|
|
1562
|
+
else if (type === COLOR_TOKEN) {
|
|
1563
|
+
output += color.transform(v[i]);
|
|
1564
|
+
}
|
|
1565
|
+
else {
|
|
1566
|
+
output += v[i];
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
return output;
|
|
1571
|
+
};
|
|
1572
|
+
}
|
|
1573
|
+
const convertNumbersToZero = (v) => typeof v === "number" ? 0 : v;
|
|
1574
|
+
function getAnimatableNone$1(v) {
|
|
1575
|
+
const parsed = parseComplexValue(v);
|
|
1576
|
+
const transformer = createTransformer(v);
|
|
1577
|
+
return transformer(parsed.map(convertNumbersToZero));
|
|
1578
|
+
}
|
|
1579
|
+
const complex = {
|
|
1580
|
+
test,
|
|
1581
|
+
parse: parseComplexValue,
|
|
1582
|
+
createTransformer,
|
|
1583
|
+
getAnimatableNone: getAnimatableNone$1,
|
|
1584
|
+
};
|
|
1585
|
+
|
|
1586
|
+
/**
|
|
1587
|
+
* Properties that should default to 1 or 100%
|
|
1588
|
+
*/
|
|
1589
|
+
const maxDefaults = new Set(["brightness", "contrast", "saturate", "opacity"]);
|
|
1590
|
+
function applyDefaultFilter(v) {
|
|
1591
|
+
const [name, value] = v.slice(0, -1).split("(");
|
|
1592
|
+
if (name === "drop-shadow")
|
|
1593
|
+
return v;
|
|
1594
|
+
const [number] = value.match(floatRegex) || [];
|
|
1595
|
+
if (!number)
|
|
1596
|
+
return v;
|
|
1597
|
+
const unit = value.replace(number, "");
|
|
1598
|
+
let defaultValue = maxDefaults.has(name) ? 1 : 0;
|
|
1599
|
+
if (number !== value)
|
|
1600
|
+
defaultValue *= 100;
|
|
1601
|
+
return name + "(" + defaultValue + unit + ")";
|
|
1602
|
+
}
|
|
1603
|
+
const functionRegex = /\b([a-z-]*)\(.*?\)/gu;
|
|
1604
|
+
const filter = {
|
|
1605
|
+
...complex,
|
|
1606
|
+
getAnimatableNone: (v) => {
|
|
1607
|
+
const functions = v.match(functionRegex);
|
|
1608
|
+
return functions ? functions.map(applyDefaultFilter).join(" ") : v;
|
|
1609
|
+
},
|
|
1610
|
+
};
|
|
1611
|
+
|
|
1612
|
+
const browserNumberValueTypes = {
|
|
1613
|
+
// Border props
|
|
1614
|
+
borderWidth: px,
|
|
1615
|
+
borderTopWidth: px,
|
|
1616
|
+
borderRightWidth: px,
|
|
1617
|
+
borderBottomWidth: px,
|
|
1618
|
+
borderLeftWidth: px,
|
|
1619
|
+
borderRadius: px,
|
|
1620
|
+
radius: px,
|
|
1621
|
+
borderTopLeftRadius: px,
|
|
1622
|
+
borderTopRightRadius: px,
|
|
1623
|
+
borderBottomRightRadius: px,
|
|
1624
|
+
borderBottomLeftRadius: px,
|
|
1625
|
+
// Positioning props
|
|
1626
|
+
width: px,
|
|
1627
|
+
maxWidth: px,
|
|
1628
|
+
height: px,
|
|
1629
|
+
maxHeight: px,
|
|
1630
|
+
top: px,
|
|
1631
|
+
right: px,
|
|
1632
|
+
bottom: px,
|
|
1633
|
+
left: px,
|
|
1634
|
+
// Spacing props
|
|
1635
|
+
padding: px,
|
|
1636
|
+
paddingTop: px,
|
|
1637
|
+
paddingRight: px,
|
|
1638
|
+
paddingBottom: px,
|
|
1639
|
+
paddingLeft: px,
|
|
1640
|
+
margin: px,
|
|
1641
|
+
marginTop: px,
|
|
1642
|
+
marginRight: px,
|
|
1643
|
+
marginBottom: px,
|
|
1644
|
+
marginLeft: px,
|
|
1645
|
+
// Misc
|
|
1646
|
+
backgroundPositionX: px,
|
|
1647
|
+
backgroundPositionY: px,
|
|
1648
|
+
};
|
|
1649
|
+
|
|
1650
|
+
const transformValueTypes = {
|
|
1651
|
+
rotate: degrees,
|
|
1652
|
+
rotateX: degrees,
|
|
1653
|
+
rotateY: degrees,
|
|
1654
|
+
rotateZ: degrees,
|
|
1655
|
+
scale,
|
|
1656
|
+
scaleX: scale,
|
|
1657
|
+
scaleY: scale,
|
|
1658
|
+
scaleZ: scale,
|
|
1659
|
+
skew: degrees,
|
|
1660
|
+
skewX: degrees,
|
|
1661
|
+
skewY: degrees,
|
|
1662
|
+
distance: px,
|
|
1663
|
+
translateX: px,
|
|
1664
|
+
translateY: px,
|
|
1665
|
+
translateZ: px,
|
|
1666
|
+
x: px,
|
|
1667
|
+
y: px,
|
|
1668
|
+
z: px,
|
|
1669
|
+
perspective: px,
|
|
1670
|
+
transformPerspective: px,
|
|
1671
|
+
opacity: alpha,
|
|
1672
|
+
originX: progressPercentage,
|
|
1673
|
+
originY: progressPercentage,
|
|
1674
|
+
originZ: px,
|
|
1675
|
+
};
|
|
1676
|
+
|
|
1677
|
+
const int = {
|
|
1678
|
+
...number,
|
|
1679
|
+
transform: Math.round,
|
|
1680
|
+
};
|
|
1681
|
+
|
|
1682
|
+
const numberValueTypes = {
|
|
1683
|
+
...browserNumberValueTypes,
|
|
1684
|
+
...transformValueTypes,
|
|
1685
|
+
zIndex: int,
|
|
1686
|
+
size: px,
|
|
1687
|
+
// SVG
|
|
1688
|
+
fillOpacity: alpha,
|
|
1689
|
+
strokeOpacity: alpha,
|
|
1690
|
+
numOctaves: int,
|
|
1691
|
+
};
|
|
1692
|
+
|
|
1693
|
+
/**
|
|
1694
|
+
* A map of default value types for common values
|
|
1695
|
+
*/
|
|
1696
|
+
const defaultValueTypes = {
|
|
1697
|
+
...numberValueTypes,
|
|
1698
|
+
// Color props
|
|
1699
|
+
color,
|
|
1700
|
+
backgroundColor: color,
|
|
1701
|
+
outlineColor: color,
|
|
1702
|
+
fill: color,
|
|
1703
|
+
stroke: color,
|
|
1704
|
+
// Border props
|
|
1705
|
+
borderColor: color,
|
|
1706
|
+
borderTopColor: color,
|
|
1707
|
+
borderRightColor: color,
|
|
1708
|
+
borderBottomColor: color,
|
|
1709
|
+
borderLeftColor: color,
|
|
1710
|
+
filter,
|
|
1711
|
+
WebkitFilter: filter,
|
|
1712
|
+
};
|
|
1713
|
+
/**
|
|
1714
|
+
* Gets the default ValueType for the provided value key
|
|
1715
|
+
*/
|
|
1716
|
+
const getDefaultValueType = (key) => defaultValueTypes[key];
|
|
1717
|
+
|
|
1718
|
+
function getAnimatableNone(key, value) {
|
|
1719
|
+
let defaultValueType = getDefaultValueType(key);
|
|
1720
|
+
if (defaultValueType !== filter)
|
|
1721
|
+
defaultValueType = complex;
|
|
1722
|
+
// If value is not recognised as animatable, ie "none", create an animatable version origin based on the target
|
|
1723
|
+
return defaultValueType.getAnimatableNone
|
|
1724
|
+
? defaultValueType.getAnimatableNone(value)
|
|
1725
|
+
: undefined;
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
/**
|
|
1729
|
+
* If we encounter keyframes like "none" or "0" and we also have keyframes like
|
|
1730
|
+
* "#fff" or "200px 200px" we want to find a keyframe to serve as a template for
|
|
1731
|
+
* the "none" keyframes. In this case "#fff" or "200px 200px" - then these get turned into
|
|
1732
|
+
* zero equivalents, i.e. "#fff0" or "0px 0px".
|
|
1733
|
+
*/
|
|
1734
|
+
const invalidTemplates = new Set(["auto", "none", "0"]);
|
|
1735
|
+
function makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name) {
|
|
1736
|
+
let i = 0;
|
|
1737
|
+
let animatableTemplate = undefined;
|
|
1738
|
+
while (i < unresolvedKeyframes.length && !animatableTemplate) {
|
|
1739
|
+
const keyframe = unresolvedKeyframes[i];
|
|
1740
|
+
if (typeof keyframe === "string" &&
|
|
1741
|
+
!invalidTemplates.has(keyframe) &&
|
|
1742
|
+
analyseComplexValue(keyframe).values.length) {
|
|
1743
|
+
animatableTemplate = unresolvedKeyframes[i];
|
|
1744
|
+
}
|
|
1745
|
+
i++;
|
|
1746
|
+
}
|
|
1747
|
+
if (animatableTemplate && name) {
|
|
1748
|
+
for (const noneIndex of noneKeyframeIndexes) {
|
|
1749
|
+
unresolvedKeyframes[noneIndex] = getAnimatableNone(name, animatableTemplate);
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
const isNumOrPxType = (v) => v === number || v === px;
|
|
1755
|
+
const getPosFromMatrix = (matrix, pos) => parseFloat(matrix.split(", ")[pos]);
|
|
1756
|
+
const getTranslateFromMatrix = (pos2, pos3) => (_bbox, { transform }) => {
|
|
1757
|
+
if (transform === "none" || !transform)
|
|
1758
|
+
return 0;
|
|
1759
|
+
const matrix3d = transform.match(/^matrix3d\((.+)\)$/u);
|
|
1760
|
+
if (matrix3d) {
|
|
1761
|
+
return getPosFromMatrix(matrix3d[1], pos3);
|
|
1762
|
+
}
|
|
1763
|
+
else {
|
|
1764
|
+
const matrix = transform.match(/^matrix\((.+)\)$/u);
|
|
1765
|
+
if (matrix) {
|
|
1766
|
+
return getPosFromMatrix(matrix[1], pos2);
|
|
1767
|
+
}
|
|
1768
|
+
else {
|
|
1769
|
+
return 0;
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
};
|
|
1773
|
+
const transformKeys = new Set(["x", "y", "z"]);
|
|
1774
|
+
const nonTranslationalTransformKeys = transformPropOrder.filter((key) => !transformKeys.has(key));
|
|
1775
|
+
function removeNonTranslationalTransform(visualElement) {
|
|
1776
|
+
const removedTransforms = [];
|
|
1777
|
+
nonTranslationalTransformKeys.forEach((key) => {
|
|
1778
|
+
const value = visualElement.getValue(key);
|
|
1779
|
+
if (value !== undefined) {
|
|
1780
|
+
removedTransforms.push([key, value.get()]);
|
|
1781
|
+
value.set(key.startsWith("scale") ? 1 : 0);
|
|
1782
|
+
}
|
|
1783
|
+
});
|
|
1784
|
+
return removedTransforms;
|
|
1785
|
+
}
|
|
1786
|
+
const positionalValues = {
|
|
1787
|
+
// Dimensions
|
|
1788
|
+
width: ({ x }, { paddingLeft = "0", paddingRight = "0" }) => x.max - x.min - parseFloat(paddingLeft) - parseFloat(paddingRight),
|
|
1789
|
+
height: ({ y }, { paddingTop = "0", paddingBottom = "0" }) => y.max - y.min - parseFloat(paddingTop) - parseFloat(paddingBottom),
|
|
1790
|
+
top: (_bbox, { top }) => parseFloat(top),
|
|
1791
|
+
left: (_bbox, { left }) => parseFloat(left),
|
|
1792
|
+
bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
|
|
1793
|
+
right: ({ x }, { left }) => parseFloat(left) + (x.max - x.min),
|
|
1794
|
+
// Transform
|
|
1795
|
+
x: getTranslateFromMatrix(4, 13),
|
|
1796
|
+
y: getTranslateFromMatrix(5, 14),
|
|
1485
1797
|
};
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
*/
|
|
1490
|
-
const dimensionValueTypes = [number, px, percent, degrees, vw, vh, auto];
|
|
1491
|
-
/**
|
|
1492
|
-
* Tests a dimensional value against the list of dimension ValueTypes
|
|
1493
|
-
*/
|
|
1494
|
-
const findDimensionValueType = (v) => dimensionValueTypes.find(testValueType(v));
|
|
1798
|
+
// Alias translate longform names
|
|
1799
|
+
positionalValues.translateX = positionalValues.x;
|
|
1800
|
+
positionalValues.translateY = positionalValues.y;
|
|
1495
1801
|
|
|
1496
1802
|
const toResolve = new Set();
|
|
1497
1803
|
let isScheduled = false;
|
|
@@ -1639,404 +1945,97 @@ class KeyframeResolver {
|
|
|
1639
1945
|
complete() {
|
|
1640
1946
|
this.isComplete = true;
|
|
1641
1947
|
this.onComplete(this.unresolvedKeyframes, this.finalKeyframe);
|
|
1642
|
-
toResolve.delete(this);
|
|
1643
|
-
}
|
|
1644
|
-
cancel() {
|
|
1645
|
-
if (!this.isComplete) {
|
|
1646
|
-
this.isScheduled = false;
|
|
1647
|
-
toResolve.delete(this);
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
1650
|
-
resume() {
|
|
1651
|
-
if (!this.isComplete)
|
|
1652
|
-
this.scheduleResolve();
|
|
1653
|
-
}
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
|
-
// If this number is a decimal, make it just five decimal places
|
|
1657
|
-
// to avoid exponents
|
|
1658
|
-
const sanitize = (v) => Math.round(v * 100000) / 100000;
|
|
1659
|
-
|
|
1660
|
-
const floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu;
|
|
1661
|
-
|
|
1662
|
-
function isNullish(v) {
|
|
1663
|
-
return v == null;
|
|
1664
|
-
}
|
|
1665
|
-
|
|
1666
|
-
const singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu;
|
|
1667
|
-
|
|
1668
|
-
/**
|
|
1669
|
-
* Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,
|
|
1670
|
-
* but false if a number or multiple colors
|
|
1671
|
-
*/
|
|
1672
|
-
const isColorString = (type, testProp) => (v) => {
|
|
1673
|
-
return Boolean((typeof v === "string" &&
|
|
1674
|
-
singleColorRegex.test(v) &&
|
|
1675
|
-
v.startsWith(type)) ||
|
|
1676
|
-
(testProp &&
|
|
1677
|
-
!isNullish(v) &&
|
|
1678
|
-
Object.prototype.hasOwnProperty.call(v, testProp)));
|
|
1679
|
-
};
|
|
1680
|
-
const splitColor = (aName, bName, cName) => (v) => {
|
|
1681
|
-
if (typeof v !== "string")
|
|
1682
|
-
return v;
|
|
1683
|
-
const [a, b, c, alpha] = v.match(floatRegex);
|
|
1684
|
-
return {
|
|
1685
|
-
[aName]: parseFloat(a),
|
|
1686
|
-
[bName]: parseFloat(b),
|
|
1687
|
-
[cName]: parseFloat(c),
|
|
1688
|
-
alpha: alpha !== undefined ? parseFloat(alpha) : 1,
|
|
1689
|
-
};
|
|
1690
|
-
};
|
|
1691
|
-
|
|
1692
|
-
const clampRgbUnit = (v) => clamp(0, 255, v);
|
|
1693
|
-
const rgbUnit = {
|
|
1694
|
-
...number,
|
|
1695
|
-
transform: (v) => Math.round(clampRgbUnit(v)),
|
|
1696
|
-
};
|
|
1697
|
-
const rgba = {
|
|
1698
|
-
test: /*@__PURE__*/ isColorString("rgb", "red"),
|
|
1699
|
-
parse: /*@__PURE__*/ splitColor("red", "green", "blue"),
|
|
1700
|
-
transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" +
|
|
1701
|
-
rgbUnit.transform(red) +
|
|
1702
|
-
", " +
|
|
1703
|
-
rgbUnit.transform(green) +
|
|
1704
|
-
", " +
|
|
1705
|
-
rgbUnit.transform(blue) +
|
|
1706
|
-
", " +
|
|
1707
|
-
sanitize(alpha.transform(alpha$1)) +
|
|
1708
|
-
")",
|
|
1709
|
-
};
|
|
1710
|
-
|
|
1711
|
-
function parseHex(v) {
|
|
1712
|
-
let r = "";
|
|
1713
|
-
let g = "";
|
|
1714
|
-
let b = "";
|
|
1715
|
-
let a = "";
|
|
1716
|
-
// If we have 6 characters, ie #FF0000
|
|
1717
|
-
if (v.length > 5) {
|
|
1718
|
-
r = v.substring(1, 3);
|
|
1719
|
-
g = v.substring(3, 5);
|
|
1720
|
-
b = v.substring(5, 7);
|
|
1721
|
-
a = v.substring(7, 9);
|
|
1722
|
-
// Or we have 3 characters, ie #F00
|
|
1723
|
-
}
|
|
1724
|
-
else {
|
|
1725
|
-
r = v.substring(1, 2);
|
|
1726
|
-
g = v.substring(2, 3);
|
|
1727
|
-
b = v.substring(3, 4);
|
|
1728
|
-
a = v.substring(4, 5);
|
|
1729
|
-
r += r;
|
|
1730
|
-
g += g;
|
|
1731
|
-
b += b;
|
|
1732
|
-
a += a;
|
|
1733
|
-
}
|
|
1734
|
-
return {
|
|
1735
|
-
red: parseInt(r, 16),
|
|
1736
|
-
green: parseInt(g, 16),
|
|
1737
|
-
blue: parseInt(b, 16),
|
|
1738
|
-
alpha: a ? parseInt(a, 16) / 255 : 1,
|
|
1739
|
-
};
|
|
1740
|
-
}
|
|
1741
|
-
const hex = {
|
|
1742
|
-
test: /*@__PURE__*/ isColorString("#"),
|
|
1743
|
-
parse: parseHex,
|
|
1744
|
-
transform: rgba.transform,
|
|
1745
|
-
};
|
|
1746
|
-
|
|
1747
|
-
const hsla = {
|
|
1748
|
-
test: /*@__PURE__*/ isColorString("hsl", "hue"),
|
|
1749
|
-
parse: /*@__PURE__*/ splitColor("hue", "saturation", "lightness"),
|
|
1750
|
-
transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
|
|
1751
|
-
return ("hsla(" +
|
|
1752
|
-
Math.round(hue) +
|
|
1753
|
-
", " +
|
|
1754
|
-
percent.transform(sanitize(saturation)) +
|
|
1755
|
-
", " +
|
|
1756
|
-
percent.transform(sanitize(lightness)) +
|
|
1757
|
-
", " +
|
|
1758
|
-
sanitize(alpha.transform(alpha$1)) +
|
|
1759
|
-
")");
|
|
1760
|
-
},
|
|
1761
|
-
};
|
|
1762
|
-
|
|
1763
|
-
const color = {
|
|
1764
|
-
test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
|
|
1765
|
-
parse: (v) => {
|
|
1766
|
-
if (rgba.test(v)) {
|
|
1767
|
-
return rgba.parse(v);
|
|
1768
|
-
}
|
|
1769
|
-
else if (hsla.test(v)) {
|
|
1770
|
-
return hsla.parse(v);
|
|
1771
|
-
}
|
|
1772
|
-
else {
|
|
1773
|
-
return hex.parse(v);
|
|
1774
|
-
}
|
|
1775
|
-
},
|
|
1776
|
-
transform: (v) => {
|
|
1777
|
-
return typeof v === "string"
|
|
1778
|
-
? v
|
|
1779
|
-
: v.hasOwnProperty("red")
|
|
1780
|
-
? rgba.transform(v)
|
|
1781
|
-
: hsla.transform(v);
|
|
1782
|
-
},
|
|
1783
|
-
};
|
|
1784
|
-
|
|
1785
|
-
const colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;
|
|
1786
|
-
|
|
1787
|
-
function test(v) {
|
|
1788
|
-
var _a, _b;
|
|
1789
|
-
return (isNaN(v) &&
|
|
1790
|
-
typeof v === "string" &&
|
|
1791
|
-
(((_a = v.match(floatRegex)) === null || _a === void 0 ? void 0 : _a.length) || 0) +
|
|
1792
|
-
(((_b = v.match(colorRegex)) === null || _b === void 0 ? void 0 : _b.length) || 0) >
|
|
1793
|
-
0);
|
|
1794
|
-
}
|
|
1795
|
-
const NUMBER_TOKEN = "number";
|
|
1796
|
-
const COLOR_TOKEN = "color";
|
|
1797
|
-
const VAR_TOKEN = "var";
|
|
1798
|
-
const VAR_FUNCTION_TOKEN = "var(";
|
|
1799
|
-
const SPLIT_TOKEN = "${}";
|
|
1800
|
-
// this regex consists of the `singleCssVariableRegex|rgbHSLValueRegex|digitRegex`
|
|
1801
|
-
const complexRegex = /var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;
|
|
1802
|
-
function analyseComplexValue(value) {
|
|
1803
|
-
const originalValue = value.toString();
|
|
1804
|
-
const values = [];
|
|
1805
|
-
const indexes = {
|
|
1806
|
-
color: [],
|
|
1807
|
-
number: [],
|
|
1808
|
-
var: [],
|
|
1809
|
-
};
|
|
1810
|
-
const types = [];
|
|
1811
|
-
let i = 0;
|
|
1812
|
-
const tokenised = originalValue.replace(complexRegex, (parsedValue) => {
|
|
1813
|
-
if (color.test(parsedValue)) {
|
|
1814
|
-
indexes.color.push(i);
|
|
1815
|
-
types.push(COLOR_TOKEN);
|
|
1816
|
-
values.push(color.parse(parsedValue));
|
|
1817
|
-
}
|
|
1818
|
-
else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {
|
|
1819
|
-
indexes.var.push(i);
|
|
1820
|
-
types.push(VAR_TOKEN);
|
|
1821
|
-
values.push(parsedValue);
|
|
1822
|
-
}
|
|
1823
|
-
else {
|
|
1824
|
-
indexes.number.push(i);
|
|
1825
|
-
types.push(NUMBER_TOKEN);
|
|
1826
|
-
values.push(parseFloat(parsedValue));
|
|
1827
|
-
}
|
|
1828
|
-
++i;
|
|
1829
|
-
return SPLIT_TOKEN;
|
|
1830
|
-
});
|
|
1831
|
-
const split = tokenised.split(SPLIT_TOKEN);
|
|
1832
|
-
return { values, split, indexes, types };
|
|
1833
|
-
}
|
|
1834
|
-
function parseComplexValue(v) {
|
|
1835
|
-
return analyseComplexValue(v).values;
|
|
1836
|
-
}
|
|
1837
|
-
function createTransformer(source) {
|
|
1838
|
-
const { split, types } = analyseComplexValue(source);
|
|
1839
|
-
const numSections = split.length;
|
|
1840
|
-
return (v) => {
|
|
1841
|
-
let output = "";
|
|
1842
|
-
for (let i = 0; i < numSections; i++) {
|
|
1843
|
-
output += split[i];
|
|
1844
|
-
if (v[i] !== undefined) {
|
|
1845
|
-
const type = types[i];
|
|
1846
|
-
if (type === NUMBER_TOKEN) {
|
|
1847
|
-
output += sanitize(v[i]);
|
|
1848
|
-
}
|
|
1849
|
-
else if (type === COLOR_TOKEN) {
|
|
1850
|
-
output += color.transform(v[i]);
|
|
1851
|
-
}
|
|
1852
|
-
else {
|
|
1853
|
-
output += v[i];
|
|
1854
|
-
}
|
|
1855
|
-
}
|
|
1856
|
-
}
|
|
1857
|
-
return output;
|
|
1858
|
-
};
|
|
1859
|
-
}
|
|
1860
|
-
const convertNumbersToZero = (v) => typeof v === "number" ? 0 : v;
|
|
1861
|
-
function getAnimatableNone$1(v) {
|
|
1862
|
-
const parsed = parseComplexValue(v);
|
|
1863
|
-
const transformer = createTransformer(v);
|
|
1864
|
-
return transformer(parsed.map(convertNumbersToZero));
|
|
1948
|
+
toResolve.delete(this);
|
|
1949
|
+
}
|
|
1950
|
+
cancel() {
|
|
1951
|
+
if (!this.isComplete) {
|
|
1952
|
+
this.isScheduled = false;
|
|
1953
|
+
toResolve.delete(this);
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
resume() {
|
|
1957
|
+
if (!this.isComplete)
|
|
1958
|
+
this.scheduleResolve();
|
|
1959
|
+
}
|
|
1865
1960
|
}
|
|
1866
|
-
const complex = {
|
|
1867
|
-
test,
|
|
1868
|
-
parse: parseComplexValue,
|
|
1869
|
-
createTransformer,
|
|
1870
|
-
getAnimatableNone: getAnimatableNone$1,
|
|
1871
|
-
};
|
|
1872
1961
|
|
|
1873
1962
|
/**
|
|
1874
|
-
*
|
|
1963
|
+
* Check if value is a numerical string, ie a string that is purely a number eg "100" or "-100.1"
|
|
1875
1964
|
*/
|
|
1876
|
-
const
|
|
1877
|
-
function applyDefaultFilter(v) {
|
|
1878
|
-
const [name, value] = v.slice(0, -1).split("(");
|
|
1879
|
-
if (name === "drop-shadow")
|
|
1880
|
-
return v;
|
|
1881
|
-
const [number] = value.match(floatRegex) || [];
|
|
1882
|
-
if (!number)
|
|
1883
|
-
return v;
|
|
1884
|
-
const unit = value.replace(number, "");
|
|
1885
|
-
let defaultValue = maxDefaults.has(name) ? 1 : 0;
|
|
1886
|
-
if (number !== value)
|
|
1887
|
-
defaultValue *= 100;
|
|
1888
|
-
return name + "(" + defaultValue + unit + ")";
|
|
1889
|
-
}
|
|
1890
|
-
const functionRegex = /\b([a-z-]*)\(.*?\)/gu;
|
|
1891
|
-
const filter = {
|
|
1892
|
-
...complex,
|
|
1893
|
-
getAnimatableNone: (v) => {
|
|
1894
|
-
const functions = v.match(functionRegex);
|
|
1895
|
-
return functions ? functions.map(applyDefaultFilter).join(" ") : v;
|
|
1896
|
-
},
|
|
1897
|
-
};
|
|
1898
|
-
|
|
1899
|
-
const browserNumberValueTypes = {
|
|
1900
|
-
// Border props
|
|
1901
|
-
borderWidth: px,
|
|
1902
|
-
borderTopWidth: px,
|
|
1903
|
-
borderRightWidth: px,
|
|
1904
|
-
borderBottomWidth: px,
|
|
1905
|
-
borderLeftWidth: px,
|
|
1906
|
-
borderRadius: px,
|
|
1907
|
-
radius: px,
|
|
1908
|
-
borderTopLeftRadius: px,
|
|
1909
|
-
borderTopRightRadius: px,
|
|
1910
|
-
borderBottomRightRadius: px,
|
|
1911
|
-
borderBottomLeftRadius: px,
|
|
1912
|
-
// Positioning props
|
|
1913
|
-
width: px,
|
|
1914
|
-
maxWidth: px,
|
|
1915
|
-
height: px,
|
|
1916
|
-
maxHeight: px,
|
|
1917
|
-
top: px,
|
|
1918
|
-
right: px,
|
|
1919
|
-
bottom: px,
|
|
1920
|
-
left: px,
|
|
1921
|
-
// Spacing props
|
|
1922
|
-
padding: px,
|
|
1923
|
-
paddingTop: px,
|
|
1924
|
-
paddingRight: px,
|
|
1925
|
-
paddingBottom: px,
|
|
1926
|
-
paddingLeft: px,
|
|
1927
|
-
margin: px,
|
|
1928
|
-
marginTop: px,
|
|
1929
|
-
marginRight: px,
|
|
1930
|
-
marginBottom: px,
|
|
1931
|
-
marginLeft: px,
|
|
1932
|
-
// Misc
|
|
1933
|
-
backgroundPositionX: px,
|
|
1934
|
-
backgroundPositionY: px,
|
|
1935
|
-
};
|
|
1965
|
+
const isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v);
|
|
1936
1966
|
|
|
1937
|
-
const
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
skewY: degrees,
|
|
1949
|
-
distance: px,
|
|
1950
|
-
translateX: px,
|
|
1951
|
-
translateY: px,
|
|
1952
|
-
translateZ: px,
|
|
1953
|
-
x: px,
|
|
1954
|
-
y: px,
|
|
1955
|
-
z: px,
|
|
1956
|
-
perspective: px,
|
|
1957
|
-
transformPerspective: px,
|
|
1958
|
-
opacity: alpha,
|
|
1959
|
-
originX: progressPercentage,
|
|
1960
|
-
originY: progressPercentage,
|
|
1961
|
-
originZ: px,
|
|
1967
|
+
const checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
|
|
1968
|
+
const isCSSVariableName =
|
|
1969
|
+
/*@__PURE__*/ checkStringStartsWith("--");
|
|
1970
|
+
const startsAsVariableToken =
|
|
1971
|
+
/*@__PURE__*/ checkStringStartsWith("var(--");
|
|
1972
|
+
const isCSSVariableToken = (value) => {
|
|
1973
|
+
const startsWithToken = startsAsVariableToken(value);
|
|
1974
|
+
if (!startsWithToken)
|
|
1975
|
+
return false;
|
|
1976
|
+
// Ensure any comments are stripped from the value as this can harm performance of the regex.
|
|
1977
|
+
return singleCssVariableRegex.test(value.split("/*")[0].trim());
|
|
1962
1978
|
};
|
|
1979
|
+
const singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
|
|
1963
1980
|
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1981
|
+
/**
|
|
1982
|
+
* Parse Framer's special CSS variable format into a CSS token and a fallback.
|
|
1983
|
+
*
|
|
1984
|
+
* ```
|
|
1985
|
+
* `var(--foo, #fff)` => [`--foo`, '#fff']
|
|
1986
|
+
* ```
|
|
1987
|
+
*
|
|
1988
|
+
* @param current
|
|
1989
|
+
*/
|
|
1990
|
+
const splitCSSVariableRegex =
|
|
1991
|
+
// eslint-disable-next-line redos-detector/no-unsafe-regex -- false positive, as it can match a lot of words
|
|
1992
|
+
/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;
|
|
1993
|
+
function parseCSSVariable(current) {
|
|
1994
|
+
const match = splitCSSVariableRegex.exec(current);
|
|
1995
|
+
if (!match)
|
|
1996
|
+
return [,];
|
|
1997
|
+
const [, token1, token2, fallback] = match;
|
|
1998
|
+
return [`--${token1 !== null && token1 !== void 0 ? token1 : token2}`, fallback];
|
|
1999
|
+
}
|
|
2000
|
+
const maxDepth = 4;
|
|
2001
|
+
function getVariableValue(current, element, depth = 1) {
|
|
2002
|
+
invariant(depth <= maxDepth, `Max CSS variable fallback depth detected in property "${current}". This may indicate a circular fallback dependency.`);
|
|
2003
|
+
const [token, fallback] = parseCSSVariable(current);
|
|
2004
|
+
// No CSS variable detected
|
|
2005
|
+
if (!token)
|
|
2006
|
+
return;
|
|
2007
|
+
// Attempt to read this CSS variable off the element
|
|
2008
|
+
const resolved = window.getComputedStyle(element).getPropertyValue(token);
|
|
2009
|
+
if (resolved) {
|
|
2010
|
+
const trimmed = resolved.trim();
|
|
2011
|
+
return isNumericalString(trimmed) ? parseFloat(trimmed) : trimmed;
|
|
2012
|
+
}
|
|
2013
|
+
return isCSSVariableToken(fallback)
|
|
2014
|
+
? getVariableValue(fallback, element, depth + 1)
|
|
2015
|
+
: fallback;
|
|
2016
|
+
}
|
|
1968
2017
|
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
size: px,
|
|
1974
|
-
// SVG
|
|
1975
|
-
fillOpacity: alpha,
|
|
1976
|
-
strokeOpacity: alpha,
|
|
1977
|
-
numOctaves: int,
|
|
1978
|
-
};
|
|
2018
|
+
/**
|
|
2019
|
+
* Tests a provided value against a ValueType
|
|
2020
|
+
*/
|
|
2021
|
+
const testValueType = (v) => (type) => type.test(v);
|
|
1979
2022
|
|
|
1980
2023
|
/**
|
|
1981
|
-
*
|
|
2024
|
+
* ValueType for "auto"
|
|
1982
2025
|
*/
|
|
1983
|
-
const
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
color,
|
|
1987
|
-
backgroundColor: color,
|
|
1988
|
-
outlineColor: color,
|
|
1989
|
-
fill: color,
|
|
1990
|
-
stroke: color,
|
|
1991
|
-
// Border props
|
|
1992
|
-
borderColor: color,
|
|
1993
|
-
borderTopColor: color,
|
|
1994
|
-
borderRightColor: color,
|
|
1995
|
-
borderBottomColor: color,
|
|
1996
|
-
borderLeftColor: color,
|
|
1997
|
-
filter,
|
|
1998
|
-
WebkitFilter: filter,
|
|
2026
|
+
const auto = {
|
|
2027
|
+
test: (v) => v === "auto",
|
|
2028
|
+
parse: (v) => v,
|
|
1999
2029
|
};
|
|
2030
|
+
|
|
2000
2031
|
/**
|
|
2001
|
-
*
|
|
2032
|
+
* A list of value types commonly used for dimensions
|
|
2002
2033
|
*/
|
|
2003
|
-
const
|
|
2004
|
-
|
|
2005
|
-
function getAnimatableNone(key, value) {
|
|
2006
|
-
let defaultValueType = getDefaultValueType(key);
|
|
2007
|
-
if (defaultValueType !== filter)
|
|
2008
|
-
defaultValueType = complex;
|
|
2009
|
-
// If value is not recognised as animatable, ie "none", create an animatable version origin based on the target
|
|
2010
|
-
return defaultValueType.getAnimatableNone
|
|
2011
|
-
? defaultValueType.getAnimatableNone(value)
|
|
2012
|
-
: undefined;
|
|
2013
|
-
}
|
|
2014
|
-
|
|
2034
|
+
const dimensionValueTypes = [number, px, percent, degrees, vw, vh, auto];
|
|
2015
2035
|
/**
|
|
2016
|
-
*
|
|
2017
|
-
* "#fff" or "200px 200px" we want to find a keyframe to serve as a template for
|
|
2018
|
-
* the "none" keyframes. In this case "#fff" or "200px 200px" - then these get turned into
|
|
2019
|
-
* zero equivalents, i.e. "#fff0" or "0px 0px".
|
|
2036
|
+
* Tests a dimensional value against the list of dimension ValueTypes
|
|
2020
2037
|
*/
|
|
2021
|
-
const
|
|
2022
|
-
function makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name) {
|
|
2023
|
-
let i = 0;
|
|
2024
|
-
let animatableTemplate = undefined;
|
|
2025
|
-
while (i < unresolvedKeyframes.length && !animatableTemplate) {
|
|
2026
|
-
const keyframe = unresolvedKeyframes[i];
|
|
2027
|
-
if (typeof keyframe === "string" &&
|
|
2028
|
-
!invalidTemplates.has(keyframe) &&
|
|
2029
|
-
analyseComplexValue(keyframe).values.length) {
|
|
2030
|
-
animatableTemplate = unresolvedKeyframes[i];
|
|
2031
|
-
}
|
|
2032
|
-
i++;
|
|
2033
|
-
}
|
|
2034
|
-
if (animatableTemplate && name) {
|
|
2035
|
-
for (const noneIndex of noneKeyframeIndexes) {
|
|
2036
|
-
unresolvedKeyframes[noneIndex] = getAnimatableNone(name, animatableTemplate);
|
|
2037
|
-
}
|
|
2038
|
-
}
|
|
2039
|
-
}
|
|
2038
|
+
const findDimensionValueType = (v) => dimensionValueTypes.find(testValueType(v));
|
|
2040
2039
|
|
|
2041
2040
|
class DOMKeyframesResolver extends KeyframeResolver {
|
|
2042
2041
|
constructor(unresolvedKeyframes, onComplete, name, motionValue, element) {
|
|
@@ -3001,8 +3000,9 @@ function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {})
|
|
|
3001
3000
|
*/
|
|
3002
3001
|
if (inputLength === 1)
|
|
3003
3002
|
return () => output[0];
|
|
3004
|
-
if (inputLength === 2 &&
|
|
3003
|
+
if (inputLength === 2 && output[0] === output[1])
|
|
3005
3004
|
return () => output[1];
|
|
3005
|
+
const isZeroDeltaRange = input[0] === input[1];
|
|
3006
3006
|
// If input runs highest -> lowest, reverse both arrays
|
|
3007
3007
|
if (input[0] > input[inputLength - 1]) {
|
|
3008
3008
|
input = [...input].reverse();
|
|
@@ -3011,6 +3011,8 @@ function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {})
|
|
|
3011
3011
|
const mixers = createMixers(output, ease, mixer);
|
|
3012
3012
|
const numMixers = mixers.length;
|
|
3013
3013
|
const interpolator = (v) => {
|
|
3014
|
+
if (isZeroDeltaRange && v < input[0])
|
|
3015
|
+
return output[0];
|
|
3014
3016
|
let i = 0;
|
|
3015
3017
|
if (numMixers > 1) {
|
|
3016
3018
|
for (; i < input.length - 2; i++) {
|
|
@@ -3994,7 +3996,7 @@ function animateTarget(visualElement, targetAndTransition, { delay = 0, transiti
|
|
|
3994
3996
|
}
|
|
3995
3997
|
}
|
|
3996
3998
|
addValueToWillChange(visualElement, key);
|
|
3997
|
-
value.start(animateMotionValue(key, value, valueTarget, visualElement.shouldReduceMotion &&
|
|
3999
|
+
value.start(animateMotionValue(key, value, valueTarget, visualElement.shouldReduceMotion && positionalKeys.has(key)
|
|
3998
4000
|
? { type: false }
|
|
3999
4001
|
: valueTransition, visualElement, isHandoff));
|
|
4000
4002
|
const animation = value.animation;
|
|
@@ -9160,6 +9162,17 @@ function initPrefersReducedMotion() {
|
|
|
9160
9162
|
}
|
|
9161
9163
|
}
|
|
9162
9164
|
|
|
9165
|
+
/**
|
|
9166
|
+
* A list of all ValueTypes
|
|
9167
|
+
*/
|
|
9168
|
+
const valueTypes = [...dimensionValueTypes, color, complex];
|
|
9169
|
+
/**
|
|
9170
|
+
* Tests a value against the list of ValueTypes
|
|
9171
|
+
*/
|
|
9172
|
+
const findValueType = (v) => valueTypes.find(testValueType(v));
|
|
9173
|
+
|
|
9174
|
+
const visualElementStore = new WeakMap();
|
|
9175
|
+
|
|
9163
9176
|
function updateMotionValuesFromProps(element, next, prev) {
|
|
9164
9177
|
for (const key in next) {
|
|
9165
9178
|
const nextValue = next[key];
|
|
@@ -9175,7 +9188,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
9175
9188
|
* and warn against mismatches.
|
|
9176
9189
|
*/
|
|
9177
9190
|
if (process.env.NODE_ENV === "development") {
|
|
9178
|
-
warnOnce(nextValue.version === "11.16.
|
|
9191
|
+
warnOnce(nextValue.version === "11.16.6", `Attempting to mix Motion versions ${nextValue.version} with 11.16.6 may not work as expected.`);
|
|
9179
9192
|
}
|
|
9180
9193
|
}
|
|
9181
9194
|
else if (isMotionValue(prevValue)) {
|
|
@@ -9214,17 +9227,6 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
9214
9227
|
return next;
|
|
9215
9228
|
}
|
|
9216
9229
|
|
|
9217
|
-
const visualElementStore = new WeakMap();
|
|
9218
|
-
|
|
9219
|
-
/**
|
|
9220
|
-
* A list of all ValueTypes
|
|
9221
|
-
*/
|
|
9222
|
-
const valueTypes = [...dimensionValueTypes, color, complex];
|
|
9223
|
-
/**
|
|
9224
|
-
* Tests a value against the list of ValueTypes
|
|
9225
|
-
*/
|
|
9226
|
-
const findValueType = (v) => valueTypes.find(testValueType(v));
|
|
9227
|
-
|
|
9228
9230
|
const propEventHandlers = [
|
|
9229
9231
|
"AnimationStart",
|
|
9230
9232
|
"AnimationComplete",
|