framer-motion 11.6.0 → 11.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/client-entry.js +145 -80
- package/dist/cjs/dom-entry.js +146 -81
- package/dist/cjs/index.js +146 -81
- package/dist/client-entry.d.ts +29 -12
- package/dist/dom-entry.d.ts +18 -1
- package/dist/dom.js +1 -1
- package/dist/es/animation/animators/AcceleratedAnimation.mjs +26 -2
- package/dist/es/animation/animators/MainThreadAnimation.mjs +4 -1
- package/dist/es/animation/animators/utils/can-animate.mjs +3 -1
- package/dist/es/animation/animators/waapi/easing.mjs +24 -9
- package/dist/es/animation/animators/waapi/index.mjs +1 -1
- package/dist/es/animation/animators/waapi/utils/linear.mjs +15 -0
- package/dist/es/animation/animators/waapi/utils/memo-supports.mjs +9 -0
- package/dist/es/animation/animators/waapi/utils/supports-flags.mjs +9 -0
- package/dist/es/animation/generators/utils/is-generator.mjs +5 -0
- package/dist/es/animation/sequence/create.mjs +2 -1
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/value/index.mjs +1 -1
- package/dist/framer-motion.dev.js +146 -81
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +28 -33
- package/dist/m-entry.d.ts +29 -12
- package/dist/three-entry.d.ts +30 -13
- package/package.json +6 -6
package/dist/cjs/client-entry.js
CHANGED
|
@@ -340,6 +340,72 @@ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
|
|
|
340
340
|
|
|
341
341
|
const { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps, } = createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
|
|
342
342
|
|
|
343
|
+
/*
|
|
344
|
+
Bezier function generator
|
|
345
|
+
This has been modified from Gaëtan Renaudeau's BezierEasing
|
|
346
|
+
https://github.com/gre/bezier-easing/blob/master/src/index.js
|
|
347
|
+
https://github.com/gre/bezier-easing/blob/master/LICENSE
|
|
348
|
+
|
|
349
|
+
I've removed the newtonRaphsonIterate algo because in benchmarking it
|
|
350
|
+
wasn't noticiably faster than binarySubdivision, indeed removing it
|
|
351
|
+
usually improved times, depending on the curve.
|
|
352
|
+
I also removed the lookup table, as for the added bundle size and loop we're
|
|
353
|
+
only cutting ~4 or so subdivision iterations. I bumped the max iterations up
|
|
354
|
+
to 12 to compensate and this still tended to be faster for no perceivable
|
|
355
|
+
loss in accuracy.
|
|
356
|
+
Usage
|
|
357
|
+
const easeOut = cubicBezier(.17,.67,.83,.67);
|
|
358
|
+
const x = easeOut(0.5); // returns 0.627...
|
|
359
|
+
*/
|
|
360
|
+
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
|
361
|
+
const calcBezier = (t, a1, a2) => (((1.0 - 3.0 * a2 + 3.0 * a1) * t + (3.0 * a2 - 6.0 * a1)) * t + 3.0 * a1) *
|
|
362
|
+
t;
|
|
363
|
+
const subdivisionPrecision = 0.0000001;
|
|
364
|
+
const subdivisionMaxIterations = 12;
|
|
365
|
+
function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
|
|
366
|
+
let currentX;
|
|
367
|
+
let currentT;
|
|
368
|
+
let i = 0;
|
|
369
|
+
do {
|
|
370
|
+
currentT = lowerBound + (upperBound - lowerBound) / 2.0;
|
|
371
|
+
currentX = calcBezier(currentT, mX1, mX2) - x;
|
|
372
|
+
if (currentX > 0.0) {
|
|
373
|
+
upperBound = currentT;
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
lowerBound = currentT;
|
|
377
|
+
}
|
|
378
|
+
} while (Math.abs(currentX) > subdivisionPrecision &&
|
|
379
|
+
++i < subdivisionMaxIterations);
|
|
380
|
+
return currentT;
|
|
381
|
+
}
|
|
382
|
+
function cubicBezier(mX1, mY1, mX2, mY2) {
|
|
383
|
+
// If this is a linear gradient, return linear easing
|
|
384
|
+
if (mX1 === mY1 && mX2 === mY2)
|
|
385
|
+
return noop;
|
|
386
|
+
const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
|
|
387
|
+
// If animation is at start/end, return t without easing
|
|
388
|
+
return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Accepts an easing function and returns a new one that outputs mirrored values for
|
|
392
|
+
// the second half of the animation. Turns easeIn into easeInOut.
|
|
393
|
+
const mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
|
|
394
|
+
|
|
395
|
+
// Accepts an easing function and returns a new one that outputs reversed values.
|
|
396
|
+
// Turns easeIn into easeOut.
|
|
397
|
+
const reverseEasing = (easing) => (p) => 1 - easing(1 - p);
|
|
398
|
+
|
|
399
|
+
const backOut = /*@__PURE__*/ cubicBezier(0.33, 1.53, 0.69, 0.99);
|
|
400
|
+
const backIn = /*@__PURE__*/ reverseEasing(backOut);
|
|
401
|
+
const backInOut = /*@__PURE__*/ mirrorEasing(backIn);
|
|
402
|
+
|
|
403
|
+
const anticipate = (p) => (p *= 2) < 1 ? 0.5 * backIn(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
|
|
404
|
+
|
|
405
|
+
const circIn = (p) => 1 - Math.sin(Math.acos(p));
|
|
406
|
+
const circOut = reverseEasing(circIn);
|
|
407
|
+
const circInOut = mirrorEasing(circIn);
|
|
408
|
+
|
|
343
409
|
/**
|
|
344
410
|
* Check if the value is a zero value string like "0px" or "0%"
|
|
345
411
|
*/
|
|
@@ -1215,6 +1281,10 @@ function memo(callback) {
|
|
|
1215
1281
|
};
|
|
1216
1282
|
}
|
|
1217
1283
|
|
|
1284
|
+
function isGenerator(type) {
|
|
1285
|
+
return typeof type === "function";
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1218
1288
|
let now;
|
|
1219
1289
|
function clearTime() {
|
|
1220
1290
|
now = undefined;
|
|
@@ -1302,7 +1372,8 @@ function canAnimate(keyframes, name, type, velocity) {
|
|
|
1302
1372
|
if (!isOriginAnimatable || !isTargetAnimatable) {
|
|
1303
1373
|
return false;
|
|
1304
1374
|
}
|
|
1305
|
-
return hasKeyframesChanged(keyframes) ||
|
|
1375
|
+
return (hasKeyframesChanged(keyframes) ||
|
|
1376
|
+
((type === "spring" || isGenerator(type)) && velocity));
|
|
1306
1377
|
}
|
|
1307
1378
|
|
|
1308
1379
|
/**
|
|
@@ -1718,54 +1789,6 @@ function inertia({ keyframes, velocity = 0.0, power = 0.8, timeConstant = 325, b
|
|
|
1718
1789
|
};
|
|
1719
1790
|
}
|
|
1720
1791
|
|
|
1721
|
-
/*
|
|
1722
|
-
Bezier function generator
|
|
1723
|
-
This has been modified from Gaëtan Renaudeau's BezierEasing
|
|
1724
|
-
https://github.com/gre/bezier-easing/blob/master/src/index.js
|
|
1725
|
-
https://github.com/gre/bezier-easing/blob/master/LICENSE
|
|
1726
|
-
|
|
1727
|
-
I've removed the newtonRaphsonIterate algo because in benchmarking it
|
|
1728
|
-
wasn't noticiably faster than binarySubdivision, indeed removing it
|
|
1729
|
-
usually improved times, depending on the curve.
|
|
1730
|
-
I also removed the lookup table, as for the added bundle size and loop we're
|
|
1731
|
-
only cutting ~4 or so subdivision iterations. I bumped the max iterations up
|
|
1732
|
-
to 12 to compensate and this still tended to be faster for no perceivable
|
|
1733
|
-
loss in accuracy.
|
|
1734
|
-
Usage
|
|
1735
|
-
const easeOut = cubicBezier(.17,.67,.83,.67);
|
|
1736
|
-
const x = easeOut(0.5); // returns 0.627...
|
|
1737
|
-
*/
|
|
1738
|
-
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
|
1739
|
-
const calcBezier = (t, a1, a2) => (((1.0 - 3.0 * a2 + 3.0 * a1) * t + (3.0 * a2 - 6.0 * a1)) * t + 3.0 * a1) *
|
|
1740
|
-
t;
|
|
1741
|
-
const subdivisionPrecision = 0.0000001;
|
|
1742
|
-
const subdivisionMaxIterations = 12;
|
|
1743
|
-
function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
|
|
1744
|
-
let currentX;
|
|
1745
|
-
let currentT;
|
|
1746
|
-
let i = 0;
|
|
1747
|
-
do {
|
|
1748
|
-
currentT = lowerBound + (upperBound - lowerBound) / 2.0;
|
|
1749
|
-
currentX = calcBezier(currentT, mX1, mX2) - x;
|
|
1750
|
-
if (currentX > 0.0) {
|
|
1751
|
-
upperBound = currentT;
|
|
1752
|
-
}
|
|
1753
|
-
else {
|
|
1754
|
-
lowerBound = currentT;
|
|
1755
|
-
}
|
|
1756
|
-
} while (Math.abs(currentX) > subdivisionPrecision &&
|
|
1757
|
-
++i < subdivisionMaxIterations);
|
|
1758
|
-
return currentT;
|
|
1759
|
-
}
|
|
1760
|
-
function cubicBezier(mX1, mY1, mX2, mY2) {
|
|
1761
|
-
// If this is a linear gradient, return linear easing
|
|
1762
|
-
if (mX1 === mY1 && mX2 === mY2)
|
|
1763
|
-
return noop;
|
|
1764
|
-
const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
|
|
1765
|
-
// If animation is at start/end, return t without easing
|
|
1766
|
-
return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
|
|
1767
|
-
}
|
|
1768
|
-
|
|
1769
1792
|
const easeIn = /*@__PURE__*/ cubicBezier(0.42, 0, 1, 1);
|
|
1770
1793
|
const easeOut = /*@__PURE__*/ cubicBezier(0, 0, 0.58, 1);
|
|
1771
1794
|
const easeInOut = /*@__PURE__*/ cubicBezier(0.42, 0, 0.58, 1);
|
|
@@ -1774,24 +1797,6 @@ const isEasingArray = (ease) => {
|
|
|
1774
1797
|
return Array.isArray(ease) && typeof ease[0] !== "number";
|
|
1775
1798
|
};
|
|
1776
1799
|
|
|
1777
|
-
// Accepts an easing function and returns a new one that outputs mirrored values for
|
|
1778
|
-
// the second half of the animation. Turns easeIn into easeInOut.
|
|
1779
|
-
const mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
|
|
1780
|
-
|
|
1781
|
-
// Accepts an easing function and returns a new one that outputs reversed values.
|
|
1782
|
-
// Turns easeIn into easeOut.
|
|
1783
|
-
const reverseEasing = (easing) => (p) => 1 - easing(1 - p);
|
|
1784
|
-
|
|
1785
|
-
const circIn = (p) => 1 - Math.sin(Math.acos(p));
|
|
1786
|
-
const circOut = reverseEasing(circIn);
|
|
1787
|
-
const circInOut = mirrorEasing(circIn);
|
|
1788
|
-
|
|
1789
|
-
const backOut = /*@__PURE__*/ cubicBezier(0.33, 1.53, 0.69, 0.99);
|
|
1790
|
-
const backIn = /*@__PURE__*/ reverseEasing(backOut);
|
|
1791
|
-
const backInOut = /*@__PURE__*/ mirrorEasing(backIn);
|
|
1792
|
-
|
|
1793
|
-
const anticipate = (p) => (p *= 2) < 1 ? 0.5 * backIn(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
|
|
1794
|
-
|
|
1795
1800
|
const easingLookup = {
|
|
1796
1801
|
linear: noop,
|
|
1797
1802
|
easeIn,
|
|
@@ -2284,7 +2289,9 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
2284
2289
|
}
|
|
2285
2290
|
initPlayback(keyframes$1) {
|
|
2286
2291
|
const { type = "keyframes", repeat = 0, repeatDelay = 0, repeatType, velocity = 0, } = this.options;
|
|
2287
|
-
const generatorFactory =
|
|
2292
|
+
const generatorFactory = isGenerator(type)
|
|
2293
|
+
? type
|
|
2294
|
+
: generators[type] || keyframes;
|
|
2288
2295
|
/**
|
|
2289
2296
|
* If our generator doesn't support mixing numbers, we need to replace keyframes with
|
|
2290
2297
|
* [0, 100] and then make a function that maps that to the actual keyframes.
|
|
@@ -2597,9 +2604,47 @@ const acceleratedValues = new Set([
|
|
|
2597
2604
|
|
|
2598
2605
|
const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
|
|
2599
2606
|
|
|
2607
|
+
// Create a linear easing point for every 10 ms
|
|
2608
|
+
const resolution = 10;
|
|
2609
|
+
const generateLinearEasing = (easing, duration // as milliseconds
|
|
2610
|
+
) => {
|
|
2611
|
+
let points = "";
|
|
2612
|
+
const numPoints = Math.max(Math.round(duration / resolution), 2);
|
|
2613
|
+
for (let i = 0; i < numPoints; i++) {
|
|
2614
|
+
points += easing(progress(0, numPoints - 1, i)) + ", ";
|
|
2615
|
+
}
|
|
2616
|
+
return `linear(${points.substring(0, points.length - 2)})`;
|
|
2617
|
+
};
|
|
2618
|
+
|
|
2619
|
+
/**
|
|
2620
|
+
* Add the ability for test suites to manually set support flags
|
|
2621
|
+
* to better test more environments.
|
|
2622
|
+
*/
|
|
2623
|
+
const supportsFlags = {
|
|
2624
|
+
linearEasing: undefined,
|
|
2625
|
+
};
|
|
2626
|
+
|
|
2627
|
+
function memoSupports(callback, supportsFlag) {
|
|
2628
|
+
const memoized = memo(callback);
|
|
2629
|
+
return () => { var _a; return (_a = supportsFlags[supportsFlag]) !== null && _a !== void 0 ? _a : memoized(); };
|
|
2630
|
+
}
|
|
2631
|
+
|
|
2632
|
+
const supportsLinearEasing = /*@__PURE__*/ memoSupports(() => {
|
|
2633
|
+
try {
|
|
2634
|
+
document
|
|
2635
|
+
.createElement("div")
|
|
2636
|
+
.animate({ opacity: 0 }, { easing: "linear(0, 1)" });
|
|
2637
|
+
}
|
|
2638
|
+
catch (e) {
|
|
2639
|
+
return false;
|
|
2640
|
+
}
|
|
2641
|
+
return true;
|
|
2642
|
+
}, "linearEasing");
|
|
2600
2643
|
function isWaapiSupportedEasing(easing) {
|
|
2601
|
-
return Boolean(
|
|
2602
|
-
|
|
2644
|
+
return Boolean((typeof easing === "function" && supportsLinearEasing()) ||
|
|
2645
|
+
!easing ||
|
|
2646
|
+
(typeof easing === "string" &&
|
|
2647
|
+
(easing in supportedWaapiEasing || supportsLinearEasing())) ||
|
|
2603
2648
|
isBezierDefinition(easing) ||
|
|
2604
2649
|
(Array.isArray(easing) && easing.every(isWaapiSupportedEasing)));
|
|
2605
2650
|
}
|
|
@@ -2615,19 +2660,19 @@ const supportedWaapiEasing = {
|
|
|
2615
2660
|
backIn: /*@__PURE__*/ cubicBezierAsString([0.31, 0.01, 0.66, -0.59]),
|
|
2616
2661
|
backOut: /*@__PURE__*/ cubicBezierAsString([0.33, 1.53, 0.69, 0.99]),
|
|
2617
2662
|
};
|
|
2618
|
-
function
|
|
2619
|
-
return (mapEasingToNativeEasing(easing) ||
|
|
2620
|
-
supportedWaapiEasing.easeOut);
|
|
2621
|
-
}
|
|
2622
|
-
function mapEasingToNativeEasing(easing) {
|
|
2663
|
+
function mapEasingToNativeEasing(easing, duration) {
|
|
2623
2664
|
if (!easing) {
|
|
2624
2665
|
return undefined;
|
|
2625
2666
|
}
|
|
2667
|
+
else if (typeof easing === "function" && supportsLinearEasing()) {
|
|
2668
|
+
return generateLinearEasing(easing, duration);
|
|
2669
|
+
}
|
|
2626
2670
|
else if (isBezierDefinition(easing)) {
|
|
2627
2671
|
return cubicBezierAsString(easing);
|
|
2628
2672
|
}
|
|
2629
2673
|
else if (Array.isArray(easing)) {
|
|
2630
|
-
return easing.map(
|
|
2674
|
+
return easing.map((segmentEasing) => mapEasingToNativeEasing(segmentEasing, duration) ||
|
|
2675
|
+
supportedWaapiEasing.easeOut);
|
|
2631
2676
|
}
|
|
2632
2677
|
else {
|
|
2633
2678
|
return supportedWaapiEasing[easing];
|
|
@@ -2638,7 +2683,7 @@ function animateStyle(element, valueName, keyframes, { delay = 0, duration = 300
|
|
|
2638
2683
|
const keyframeOptions = { [valueName]: keyframes };
|
|
2639
2684
|
if (times)
|
|
2640
2685
|
keyframeOptions.offset = times;
|
|
2641
|
-
const easing = mapEasingToNativeEasing(ease);
|
|
2686
|
+
const easing = mapEasingToNativeEasing(ease, duration);
|
|
2642
2687
|
/**
|
|
2643
2688
|
* If this is an easing array, apply to keyframes, not animation as a whole
|
|
2644
2689
|
*/
|
|
@@ -2672,7 +2717,9 @@ const maxDuration = 20000;
|
|
|
2672
2717
|
* handing off.
|
|
2673
2718
|
*/
|
|
2674
2719
|
function requiresPregeneratedKeyframes(options) {
|
|
2675
|
-
return options.type
|
|
2720
|
+
return (isGenerator(options.type) ||
|
|
2721
|
+
options.type === "spring" ||
|
|
2722
|
+
!isWaapiSupportedEasing(options.ease));
|
|
2676
2723
|
}
|
|
2677
2724
|
function pregenerateKeyframes(keyframes, options) {
|
|
2678
2725
|
/**
|
|
@@ -2706,6 +2753,14 @@ function pregenerateKeyframes(keyframes, options) {
|
|
|
2706
2753
|
ease: "linear",
|
|
2707
2754
|
};
|
|
2708
2755
|
}
|
|
2756
|
+
const unsupportedEasingFunctions = {
|
|
2757
|
+
anticipate,
|
|
2758
|
+
backInOut,
|
|
2759
|
+
circInOut,
|
|
2760
|
+
};
|
|
2761
|
+
function isUnsupportedEase(key) {
|
|
2762
|
+
return key in unsupportedEasingFunctions;
|
|
2763
|
+
}
|
|
2709
2764
|
class AcceleratedAnimation extends BaseAnimation {
|
|
2710
2765
|
constructor(options) {
|
|
2711
2766
|
super(options);
|
|
@@ -2723,6 +2778,16 @@ class AcceleratedAnimation extends BaseAnimation {
|
|
|
2723
2778
|
if (!((_a = motionValue.owner) === null || _a === void 0 ? void 0 : _a.current)) {
|
|
2724
2779
|
return false;
|
|
2725
2780
|
}
|
|
2781
|
+
/**
|
|
2782
|
+
* If the user has provided an easing function name that isn't supported
|
|
2783
|
+
* by WAAPI (like "anticipate"), we need to provide the corressponding
|
|
2784
|
+
* function. This will later get converted to a linear() easing function.
|
|
2785
|
+
*/
|
|
2786
|
+
if (typeof ease === "string" &&
|
|
2787
|
+
supportsLinearEasing() &&
|
|
2788
|
+
isUnsupportedEase(ease)) {
|
|
2789
|
+
ease = unsupportedEasingFunctions[ease];
|
|
2790
|
+
}
|
|
2726
2791
|
/**
|
|
2727
2792
|
* If this animation needs pre-generated keyframes then generate.
|
|
2728
2793
|
*/
|
|
@@ -3218,7 +3283,7 @@ class MotionValue {
|
|
|
3218
3283
|
* This will be replaced by the build step with the latest version number.
|
|
3219
3284
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
3220
3285
|
*/
|
|
3221
|
-
this.version = "11.
|
|
3286
|
+
this.version = "11.8.0";
|
|
3222
3287
|
/**
|
|
3223
3288
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
3224
3289
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -5841,7 +5906,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
5841
5906
|
* and warn against mismatches.
|
|
5842
5907
|
*/
|
|
5843
5908
|
if (process.env.NODE_ENV === "development") {
|
|
5844
|
-
warnOnce(nextValue.version === "11.
|
|
5909
|
+
warnOnce(nextValue.version === "11.8.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.8.0 may not work as expected.`);
|
|
5845
5910
|
}
|
|
5846
5911
|
}
|
|
5847
5912
|
else if (isMotionValue(prevValue)) {
|
package/dist/cjs/dom-entry.js
CHANGED
|
@@ -279,7 +279,7 @@ class MotionValue {
|
|
|
279
279
|
* This will be replaced by the build step with the latest version number.
|
|
280
280
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
281
281
|
*/
|
|
282
|
-
this.version = "11.
|
|
282
|
+
this.version = "11.8.0";
|
|
283
283
|
/**
|
|
284
284
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
285
285
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -807,6 +807,72 @@ function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyfr
|
|
|
807
807
|
: finalKeyframe;
|
|
808
808
|
}
|
|
809
809
|
|
|
810
|
+
/*
|
|
811
|
+
Bezier function generator
|
|
812
|
+
This has been modified from Gaëtan Renaudeau's BezierEasing
|
|
813
|
+
https://github.com/gre/bezier-easing/blob/master/src/index.js
|
|
814
|
+
https://github.com/gre/bezier-easing/blob/master/LICENSE
|
|
815
|
+
|
|
816
|
+
I've removed the newtonRaphsonIterate algo because in benchmarking it
|
|
817
|
+
wasn't noticiably faster than binarySubdivision, indeed removing it
|
|
818
|
+
usually improved times, depending on the curve.
|
|
819
|
+
I also removed the lookup table, as for the added bundle size and loop we're
|
|
820
|
+
only cutting ~4 or so subdivision iterations. I bumped the max iterations up
|
|
821
|
+
to 12 to compensate and this still tended to be faster for no perceivable
|
|
822
|
+
loss in accuracy.
|
|
823
|
+
Usage
|
|
824
|
+
const easeOut = cubicBezier(.17,.67,.83,.67);
|
|
825
|
+
const x = easeOut(0.5); // returns 0.627...
|
|
826
|
+
*/
|
|
827
|
+
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
|
828
|
+
const calcBezier = (t, a1, a2) => (((1.0 - 3.0 * a2 + 3.0 * a1) * t + (3.0 * a2 - 6.0 * a1)) * t + 3.0 * a1) *
|
|
829
|
+
t;
|
|
830
|
+
const subdivisionPrecision = 0.0000001;
|
|
831
|
+
const subdivisionMaxIterations = 12;
|
|
832
|
+
function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
|
|
833
|
+
let currentX;
|
|
834
|
+
let currentT;
|
|
835
|
+
let i = 0;
|
|
836
|
+
do {
|
|
837
|
+
currentT = lowerBound + (upperBound - lowerBound) / 2.0;
|
|
838
|
+
currentX = calcBezier(currentT, mX1, mX2) - x;
|
|
839
|
+
if (currentX > 0.0) {
|
|
840
|
+
upperBound = currentT;
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
lowerBound = currentT;
|
|
844
|
+
}
|
|
845
|
+
} while (Math.abs(currentX) > subdivisionPrecision &&
|
|
846
|
+
++i < subdivisionMaxIterations);
|
|
847
|
+
return currentT;
|
|
848
|
+
}
|
|
849
|
+
function cubicBezier(mX1, mY1, mX2, mY2) {
|
|
850
|
+
// If this is a linear gradient, return linear easing
|
|
851
|
+
if (mX1 === mY1 && mX2 === mY2)
|
|
852
|
+
return noop;
|
|
853
|
+
const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
|
|
854
|
+
// If animation is at start/end, return t without easing
|
|
855
|
+
return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// Accepts an easing function and returns a new one that outputs mirrored values for
|
|
859
|
+
// the second half of the animation. Turns easeIn into easeInOut.
|
|
860
|
+
const mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
|
|
861
|
+
|
|
862
|
+
// Accepts an easing function and returns a new one that outputs reversed values.
|
|
863
|
+
// Turns easeIn into easeOut.
|
|
864
|
+
const reverseEasing = (easing) => (p) => 1 - easing(1 - p);
|
|
865
|
+
|
|
866
|
+
const backOut = /*@__PURE__*/ cubicBezier(0.33, 1.53, 0.69, 0.99);
|
|
867
|
+
const backIn = /*@__PURE__*/ reverseEasing(backOut);
|
|
868
|
+
const backInOut = /*@__PURE__*/ mirrorEasing(backIn);
|
|
869
|
+
|
|
870
|
+
const anticipate = (p) => (p *= 2) < 1 ? 0.5 * backIn(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
|
|
871
|
+
|
|
872
|
+
const circIn = (p) => 1 - Math.sin(Math.acos(p));
|
|
873
|
+
const circOut = reverseEasing(circIn);
|
|
874
|
+
const circInOut = mirrorEasing(circIn);
|
|
875
|
+
|
|
810
876
|
/**
|
|
811
877
|
* Check if the value is a zero value string like "0px" or "0%"
|
|
812
878
|
*/
|
|
@@ -1658,6 +1724,10 @@ class DOMKeyframesResolver extends KeyframeResolver {
|
|
|
1658
1724
|
}
|
|
1659
1725
|
}
|
|
1660
1726
|
|
|
1727
|
+
function isGenerator(type) {
|
|
1728
|
+
return typeof type === "function";
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1661
1731
|
/**
|
|
1662
1732
|
* Check if a value is animatable. Examples:
|
|
1663
1733
|
*
|
|
@@ -1718,7 +1788,8 @@ function canAnimate(keyframes, name, type, velocity) {
|
|
|
1718
1788
|
if (!isOriginAnimatable || !isTargetAnimatable) {
|
|
1719
1789
|
return false;
|
|
1720
1790
|
}
|
|
1721
|
-
return hasKeyframesChanged(keyframes) ||
|
|
1791
|
+
return (hasKeyframesChanged(keyframes) ||
|
|
1792
|
+
((type === "spring" || isGenerator(type)) && velocity));
|
|
1722
1793
|
}
|
|
1723
1794
|
|
|
1724
1795
|
/**
|
|
@@ -2124,54 +2195,6 @@ function inertia({ keyframes, velocity = 0.0, power = 0.8, timeConstant = 325, b
|
|
|
2124
2195
|
};
|
|
2125
2196
|
}
|
|
2126
2197
|
|
|
2127
|
-
/*
|
|
2128
|
-
Bezier function generator
|
|
2129
|
-
This has been modified from Gaëtan Renaudeau's BezierEasing
|
|
2130
|
-
https://github.com/gre/bezier-easing/blob/master/src/index.js
|
|
2131
|
-
https://github.com/gre/bezier-easing/blob/master/LICENSE
|
|
2132
|
-
|
|
2133
|
-
I've removed the newtonRaphsonIterate algo because in benchmarking it
|
|
2134
|
-
wasn't noticiably faster than binarySubdivision, indeed removing it
|
|
2135
|
-
usually improved times, depending on the curve.
|
|
2136
|
-
I also removed the lookup table, as for the added bundle size and loop we're
|
|
2137
|
-
only cutting ~4 or so subdivision iterations. I bumped the max iterations up
|
|
2138
|
-
to 12 to compensate and this still tended to be faster for no perceivable
|
|
2139
|
-
loss in accuracy.
|
|
2140
|
-
Usage
|
|
2141
|
-
const easeOut = cubicBezier(.17,.67,.83,.67);
|
|
2142
|
-
const x = easeOut(0.5); // returns 0.627...
|
|
2143
|
-
*/
|
|
2144
|
-
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
|
2145
|
-
const calcBezier = (t, a1, a2) => (((1.0 - 3.0 * a2 + 3.0 * a1) * t + (3.0 * a2 - 6.0 * a1)) * t + 3.0 * a1) *
|
|
2146
|
-
t;
|
|
2147
|
-
const subdivisionPrecision = 0.0000001;
|
|
2148
|
-
const subdivisionMaxIterations = 12;
|
|
2149
|
-
function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
|
|
2150
|
-
let currentX;
|
|
2151
|
-
let currentT;
|
|
2152
|
-
let i = 0;
|
|
2153
|
-
do {
|
|
2154
|
-
currentT = lowerBound + (upperBound - lowerBound) / 2.0;
|
|
2155
|
-
currentX = calcBezier(currentT, mX1, mX2) - x;
|
|
2156
|
-
if (currentX > 0.0) {
|
|
2157
|
-
upperBound = currentT;
|
|
2158
|
-
}
|
|
2159
|
-
else {
|
|
2160
|
-
lowerBound = currentT;
|
|
2161
|
-
}
|
|
2162
|
-
} while (Math.abs(currentX) > subdivisionPrecision &&
|
|
2163
|
-
++i < subdivisionMaxIterations);
|
|
2164
|
-
return currentT;
|
|
2165
|
-
}
|
|
2166
|
-
function cubicBezier(mX1, mY1, mX2, mY2) {
|
|
2167
|
-
// If this is a linear gradient, return linear easing
|
|
2168
|
-
if (mX1 === mY1 && mX2 === mY2)
|
|
2169
|
-
return noop;
|
|
2170
|
-
const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
|
|
2171
|
-
// If animation is at start/end, return t without easing
|
|
2172
|
-
return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
|
|
2173
|
-
}
|
|
2174
|
-
|
|
2175
2198
|
const easeIn = /*@__PURE__*/ cubicBezier(0.42, 0, 1, 1);
|
|
2176
2199
|
const easeOut = /*@__PURE__*/ cubicBezier(0, 0, 0.58, 1);
|
|
2177
2200
|
const easeInOut = /*@__PURE__*/ cubicBezier(0.42, 0, 0.58, 1);
|
|
@@ -2180,24 +2203,6 @@ const isEasingArray = (ease) => {
|
|
|
2180
2203
|
return Array.isArray(ease) && typeof ease[0] !== "number";
|
|
2181
2204
|
};
|
|
2182
2205
|
|
|
2183
|
-
// Accepts an easing function and returns a new one that outputs mirrored values for
|
|
2184
|
-
// the second half of the animation. Turns easeIn into easeInOut.
|
|
2185
|
-
const mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
|
|
2186
|
-
|
|
2187
|
-
// Accepts an easing function and returns a new one that outputs reversed values.
|
|
2188
|
-
// Turns easeIn into easeOut.
|
|
2189
|
-
const reverseEasing = (easing) => (p) => 1 - easing(1 - p);
|
|
2190
|
-
|
|
2191
|
-
const circIn = (p) => 1 - Math.sin(Math.acos(p));
|
|
2192
|
-
const circOut = reverseEasing(circIn);
|
|
2193
|
-
const circInOut = mirrorEasing(circIn);
|
|
2194
|
-
|
|
2195
|
-
const backOut = /*@__PURE__*/ cubicBezier(0.33, 1.53, 0.69, 0.99);
|
|
2196
|
-
const backIn = /*@__PURE__*/ reverseEasing(backOut);
|
|
2197
|
-
const backInOut = /*@__PURE__*/ mirrorEasing(backIn);
|
|
2198
|
-
|
|
2199
|
-
const anticipate = (p) => (p *= 2) < 1 ? 0.5 * backIn(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
|
|
2200
|
-
|
|
2201
2206
|
const easingLookup = {
|
|
2202
2207
|
linear: noop,
|
|
2203
2208
|
easeIn,
|
|
@@ -2690,7 +2695,9 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
2690
2695
|
}
|
|
2691
2696
|
initPlayback(keyframes$1) {
|
|
2692
2697
|
const { type = "keyframes", repeat = 0, repeatDelay = 0, repeatType, velocity = 0, } = this.options;
|
|
2693
|
-
const generatorFactory =
|
|
2698
|
+
const generatorFactory = isGenerator(type)
|
|
2699
|
+
? type
|
|
2700
|
+
: generators[type] || keyframes;
|
|
2694
2701
|
/**
|
|
2695
2702
|
* If our generator doesn't support mixing numbers, we need to replace keyframes with
|
|
2696
2703
|
* [0, 100] and then make a function that maps that to the actual keyframes.
|
|
@@ -3003,9 +3010,47 @@ const acceleratedValues = new Set([
|
|
|
3003
3010
|
|
|
3004
3011
|
const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
|
|
3005
3012
|
|
|
3013
|
+
// Create a linear easing point for every 10 ms
|
|
3014
|
+
const resolution = 10;
|
|
3015
|
+
const generateLinearEasing = (easing, duration // as milliseconds
|
|
3016
|
+
) => {
|
|
3017
|
+
let points = "";
|
|
3018
|
+
const numPoints = Math.max(Math.round(duration / resolution), 2);
|
|
3019
|
+
for (let i = 0; i < numPoints; i++) {
|
|
3020
|
+
points += easing(progress(0, numPoints - 1, i)) + ", ";
|
|
3021
|
+
}
|
|
3022
|
+
return `linear(${points.substring(0, points.length - 2)})`;
|
|
3023
|
+
};
|
|
3024
|
+
|
|
3025
|
+
/**
|
|
3026
|
+
* Add the ability for test suites to manually set support flags
|
|
3027
|
+
* to better test more environments.
|
|
3028
|
+
*/
|
|
3029
|
+
const supportsFlags = {
|
|
3030
|
+
linearEasing: undefined,
|
|
3031
|
+
};
|
|
3032
|
+
|
|
3033
|
+
function memoSupports(callback, supportsFlag) {
|
|
3034
|
+
const memoized = memo(callback);
|
|
3035
|
+
return () => { var _a; return (_a = supportsFlags[supportsFlag]) !== null && _a !== void 0 ? _a : memoized(); };
|
|
3036
|
+
}
|
|
3037
|
+
|
|
3038
|
+
const supportsLinearEasing = /*@__PURE__*/ memoSupports(() => {
|
|
3039
|
+
try {
|
|
3040
|
+
document
|
|
3041
|
+
.createElement("div")
|
|
3042
|
+
.animate({ opacity: 0 }, { easing: "linear(0, 1)" });
|
|
3043
|
+
}
|
|
3044
|
+
catch (e) {
|
|
3045
|
+
return false;
|
|
3046
|
+
}
|
|
3047
|
+
return true;
|
|
3048
|
+
}, "linearEasing");
|
|
3006
3049
|
function isWaapiSupportedEasing(easing) {
|
|
3007
|
-
return Boolean(
|
|
3008
|
-
|
|
3050
|
+
return Boolean((typeof easing === "function" && supportsLinearEasing()) ||
|
|
3051
|
+
!easing ||
|
|
3052
|
+
(typeof easing === "string" &&
|
|
3053
|
+
(easing in supportedWaapiEasing || supportsLinearEasing())) ||
|
|
3009
3054
|
isBezierDefinition(easing) ||
|
|
3010
3055
|
(Array.isArray(easing) && easing.every(isWaapiSupportedEasing)));
|
|
3011
3056
|
}
|
|
@@ -3021,19 +3066,19 @@ const supportedWaapiEasing = {
|
|
|
3021
3066
|
backIn: /*@__PURE__*/ cubicBezierAsString([0.31, 0.01, 0.66, -0.59]),
|
|
3022
3067
|
backOut: /*@__PURE__*/ cubicBezierAsString([0.33, 1.53, 0.69, 0.99]),
|
|
3023
3068
|
};
|
|
3024
|
-
function
|
|
3025
|
-
return (mapEasingToNativeEasing(easing) ||
|
|
3026
|
-
supportedWaapiEasing.easeOut);
|
|
3027
|
-
}
|
|
3028
|
-
function mapEasingToNativeEasing(easing) {
|
|
3069
|
+
function mapEasingToNativeEasing(easing, duration) {
|
|
3029
3070
|
if (!easing) {
|
|
3030
3071
|
return undefined;
|
|
3031
3072
|
}
|
|
3073
|
+
else if (typeof easing === "function" && supportsLinearEasing()) {
|
|
3074
|
+
return generateLinearEasing(easing, duration);
|
|
3075
|
+
}
|
|
3032
3076
|
else if (isBezierDefinition(easing)) {
|
|
3033
3077
|
return cubicBezierAsString(easing);
|
|
3034
3078
|
}
|
|
3035
3079
|
else if (Array.isArray(easing)) {
|
|
3036
|
-
return easing.map(
|
|
3080
|
+
return easing.map((segmentEasing) => mapEasingToNativeEasing(segmentEasing, duration) ||
|
|
3081
|
+
supportedWaapiEasing.easeOut);
|
|
3037
3082
|
}
|
|
3038
3083
|
else {
|
|
3039
3084
|
return supportedWaapiEasing[easing];
|
|
@@ -3044,7 +3089,7 @@ function animateStyle(element, valueName, keyframes, { delay = 0, duration = 300
|
|
|
3044
3089
|
const keyframeOptions = { [valueName]: keyframes };
|
|
3045
3090
|
if (times)
|
|
3046
3091
|
keyframeOptions.offset = times;
|
|
3047
|
-
const easing = mapEasingToNativeEasing(ease);
|
|
3092
|
+
const easing = mapEasingToNativeEasing(ease, duration);
|
|
3048
3093
|
/**
|
|
3049
3094
|
* If this is an easing array, apply to keyframes, not animation as a whole
|
|
3050
3095
|
*/
|
|
@@ -3078,7 +3123,9 @@ const maxDuration = 20000;
|
|
|
3078
3123
|
* handing off.
|
|
3079
3124
|
*/
|
|
3080
3125
|
function requiresPregeneratedKeyframes(options) {
|
|
3081
|
-
return options.type
|
|
3126
|
+
return (isGenerator(options.type) ||
|
|
3127
|
+
options.type === "spring" ||
|
|
3128
|
+
!isWaapiSupportedEasing(options.ease));
|
|
3082
3129
|
}
|
|
3083
3130
|
function pregenerateKeyframes(keyframes, options) {
|
|
3084
3131
|
/**
|
|
@@ -3112,6 +3159,14 @@ function pregenerateKeyframes(keyframes, options) {
|
|
|
3112
3159
|
ease: "linear",
|
|
3113
3160
|
};
|
|
3114
3161
|
}
|
|
3162
|
+
const unsupportedEasingFunctions = {
|
|
3163
|
+
anticipate,
|
|
3164
|
+
backInOut,
|
|
3165
|
+
circInOut,
|
|
3166
|
+
};
|
|
3167
|
+
function isUnsupportedEase(key) {
|
|
3168
|
+
return key in unsupportedEasingFunctions;
|
|
3169
|
+
}
|
|
3115
3170
|
class AcceleratedAnimation extends BaseAnimation {
|
|
3116
3171
|
constructor(options) {
|
|
3117
3172
|
super(options);
|
|
@@ -3129,6 +3184,16 @@ class AcceleratedAnimation extends BaseAnimation {
|
|
|
3129
3184
|
if (!((_a = motionValue.owner) === null || _a === void 0 ? void 0 : _a.current)) {
|
|
3130
3185
|
return false;
|
|
3131
3186
|
}
|
|
3187
|
+
/**
|
|
3188
|
+
* If the user has provided an easing function name that isn't supported
|
|
3189
|
+
* by WAAPI (like "anticipate"), we need to provide the corressponding
|
|
3190
|
+
* function. This will later get converted to a linear() easing function.
|
|
3191
|
+
*/
|
|
3192
|
+
if (typeof ease === "string" &&
|
|
3193
|
+
supportsLinearEasing() &&
|
|
3194
|
+
isUnsupportedEase(ease)) {
|
|
3195
|
+
ease = unsupportedEasingFunctions[ease];
|
|
3196
|
+
}
|
|
3132
3197
|
/**
|
|
3133
3198
|
* If this animation needs pre-generated keyframes then generate.
|
|
3134
3199
|
*/
|
|
@@ -3757,7 +3822,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
3757
3822
|
* and warn against mismatches.
|
|
3758
3823
|
*/
|
|
3759
3824
|
if (process.env.NODE_ENV === "development") {
|
|
3760
|
-
warnOnce(nextValue.version === "11.
|
|
3825
|
+
warnOnce(nextValue.version === "11.8.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 11.8.0 may not work as expected.`);
|
|
3761
3826
|
}
|
|
3762
3827
|
}
|
|
3763
3828
|
else if (isMotionValue(prevValue)) {
|
|
@@ -4859,7 +4924,7 @@ function createAnimationsFromSequence(sequence, { defaultTransition = {}, ...seq
|
|
|
4859
4924
|
* If this animation should and can use a spring, generate a spring easing function.
|
|
4860
4925
|
*/
|
|
4861
4926
|
const numKeyframes = valueKeyframesAsList.length;
|
|
4862
|
-
if (numKeyframes <= 2 && type === "spring") {
|
|
4927
|
+
if ((numKeyframes <= 2 && type === "spring") || isGenerator(type)) {
|
|
4863
4928
|
/**
|
|
4864
4929
|
* As we're creating an easing function from a spring,
|
|
4865
4930
|
* ideally we want to generate it using the real distance
|