framer-motion 10.5.0 → 10.6.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/dom-entry.js +1 -1
- package/dist/cjs/index.js +11 -1
- package/dist/cjs/{wrap-bf172f81.js → wrap-992dcd37.js} +176 -89
- package/dist/dom-entry.d.ts +6 -3
- package/dist/es/animation/GroupPlaybackControls.mjs +22 -8
- package/dist/es/animation/animators/instant.mjs +10 -0
- package/dist/es/animation/animators/js/index.mjs +62 -17
- package/dist/es/animation/animators/waapi/create-accelerated-animation.mjs +22 -5
- package/dist/es/animation/interfaces/motion-value.mjs +1 -0
- package/dist/es/easing/ease.mjs +4 -5
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/value/index.mjs +1 -1
- package/dist/es/value/use-spring.mjs +12 -0
- package/dist/framer-motion.dev.js +186 -89
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +13 -3
- package/dist/projection.dev.js +148 -75
- package/dist/three-entry.d.ts +3 -0
- package/package.json +7 -7
package/dist/cjs/dom-entry.js
CHANGED
package/dist/cjs/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
|
-
var wrap = require('./wrap-
|
|
6
|
+
var wrap = require('./wrap-992dcd37.js');
|
|
7
7
|
|
|
8
8
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
9
|
|
|
@@ -5295,6 +5295,16 @@ function useSpring(source, config = {}) {
|
|
|
5295
5295
|
...config,
|
|
5296
5296
|
onUpdate: set,
|
|
5297
5297
|
});
|
|
5298
|
+
/**
|
|
5299
|
+
* If we're between frames, resync the animation to the frameloop.
|
|
5300
|
+
*/
|
|
5301
|
+
if (!wrap.frameData.isProcessing) {
|
|
5302
|
+
const delta = performance.now() - wrap.frameData.timestamp;
|
|
5303
|
+
if (delta < 30) {
|
|
5304
|
+
activeSpringAnimation.current.time =
|
|
5305
|
+
wrap.millisecondsToSeconds(delta);
|
|
5306
|
+
}
|
|
5307
|
+
}
|
|
5298
5308
|
return value.get();
|
|
5299
5309
|
}, stopAnimation);
|
|
5300
5310
|
}, [JSON.stringify(config)]);
|
|
@@ -818,17 +818,57 @@ function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }) {
|
|
|
818
818
|
return keyframes[index];
|
|
819
819
|
}
|
|
820
820
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
821
|
+
/*
|
|
822
|
+
Bezier function generator
|
|
823
|
+
This has been modified from Gaëtan Renaudeau's BezierEasing
|
|
824
|
+
https://github.com/gre/bezier-easing/blob/master/src/index.js
|
|
825
|
+
https://github.com/gre/bezier-easing/blob/master/LICENSE
|
|
826
|
+
|
|
827
|
+
I've removed the newtonRaphsonIterate algo because in benchmarking it
|
|
828
|
+
wasn't noticiably faster than binarySubdivision, indeed removing it
|
|
829
|
+
usually improved times, depending on the curve.
|
|
830
|
+
I also removed the lookup table, as for the added bundle size and loop we're
|
|
831
|
+
only cutting ~4 or so subdivision iterations. I bumped the max iterations up
|
|
832
|
+
to 12 to compensate and this still tended to be faster for no perceivable
|
|
833
|
+
loss in accuracy.
|
|
834
|
+
Usage
|
|
835
|
+
const easeOut = cubicBezier(.17,.67,.83,.67);
|
|
836
|
+
const x = easeOut(0.5); // returns 0.627...
|
|
837
|
+
*/
|
|
838
|
+
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
|
839
|
+
const calcBezier = (t, a1, a2) => (((1.0 - 3.0 * a2 + 3.0 * a1) * t + (3.0 * a2 - 6.0 * a1)) * t + 3.0 * a1) *
|
|
840
|
+
t;
|
|
841
|
+
const subdivisionPrecision = 0.0000001;
|
|
842
|
+
const subdivisionMaxIterations = 12;
|
|
843
|
+
function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
|
|
844
|
+
let currentX;
|
|
845
|
+
let currentT;
|
|
846
|
+
let i = 0;
|
|
847
|
+
do {
|
|
848
|
+
currentT = lowerBound + (upperBound - lowerBound) / 2.0;
|
|
849
|
+
currentX = calcBezier(currentT, mX1, mX2) - x;
|
|
850
|
+
if (currentX > 0.0) {
|
|
851
|
+
upperBound = currentT;
|
|
852
|
+
}
|
|
853
|
+
else {
|
|
854
|
+
lowerBound = currentT;
|
|
855
|
+
}
|
|
856
|
+
} while (Math.abs(currentX) > subdivisionPrecision &&
|
|
857
|
+
++i < subdivisionMaxIterations);
|
|
858
|
+
return currentT;
|
|
859
|
+
}
|
|
860
|
+
function cubicBezier(mX1, mY1, mX2, mY2) {
|
|
861
|
+
// If this is a linear gradient, return linear easing
|
|
862
|
+
if (mX1 === mY1 && mX2 === mY2)
|
|
863
|
+
return noop;
|
|
864
|
+
const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
|
|
865
|
+
// If animation is at start/end, return t without easing
|
|
866
|
+
return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
|
|
867
|
+
}
|
|
828
868
|
|
|
829
|
-
const easeIn = (
|
|
830
|
-
const easeOut =
|
|
831
|
-
const easeInOut =
|
|
869
|
+
const easeIn = cubicBezier(0.42, 0, 1, 1);
|
|
870
|
+
const easeOut = cubicBezier(0, 0, 0.58, 1);
|
|
871
|
+
const easeInOut = cubicBezier(0.42, 0, 0.58, 1);
|
|
832
872
|
|
|
833
873
|
/**
|
|
834
874
|
* Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,
|
|
@@ -1269,53 +1309,13 @@ function convertOffsetToTimes(offset, duration) {
|
|
|
1269
1309
|
return offset.map((o) => o * duration);
|
|
1270
1310
|
}
|
|
1271
1311
|
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
wasn't noticiably faster than binarySubdivision, indeed removing it
|
|
1280
|
-
usually improved times, depending on the curve.
|
|
1281
|
-
I also removed the lookup table, as for the added bundle size and loop we're
|
|
1282
|
-
only cutting ~4 or so subdivision iterations. I bumped the max iterations up
|
|
1283
|
-
to 12 to compensate and this still tended to be faster for no perceivable
|
|
1284
|
-
loss in accuracy.
|
|
1285
|
-
Usage
|
|
1286
|
-
const easeOut = cubicBezier(.17,.67,.83,.67);
|
|
1287
|
-
const x = easeOut(0.5); // returns 0.627...
|
|
1288
|
-
*/
|
|
1289
|
-
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
|
1290
|
-
const calcBezier = (t, a1, a2) => (((1.0 - 3.0 * a2 + 3.0 * a1) * t + (3.0 * a2 - 6.0 * a1)) * t + 3.0 * a1) *
|
|
1291
|
-
t;
|
|
1292
|
-
const subdivisionPrecision = 0.0000001;
|
|
1293
|
-
const subdivisionMaxIterations = 12;
|
|
1294
|
-
function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
|
|
1295
|
-
let currentX;
|
|
1296
|
-
let currentT;
|
|
1297
|
-
let i = 0;
|
|
1298
|
-
do {
|
|
1299
|
-
currentT = lowerBound + (upperBound - lowerBound) / 2.0;
|
|
1300
|
-
currentX = calcBezier(currentT, mX1, mX2) - x;
|
|
1301
|
-
if (currentX > 0.0) {
|
|
1302
|
-
upperBound = currentT;
|
|
1303
|
-
}
|
|
1304
|
-
else {
|
|
1305
|
-
lowerBound = currentT;
|
|
1306
|
-
}
|
|
1307
|
-
} while (Math.abs(currentX) > subdivisionPrecision &&
|
|
1308
|
-
++i < subdivisionMaxIterations);
|
|
1309
|
-
return currentT;
|
|
1310
|
-
}
|
|
1311
|
-
function cubicBezier(mX1, mY1, mX2, mY2) {
|
|
1312
|
-
// If this is a linear gradient, return linear easing
|
|
1313
|
-
if (mX1 === mY1 && mX2 === mY2)
|
|
1314
|
-
return noop;
|
|
1315
|
-
const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
|
|
1316
|
-
// If animation is at start/end, return t without easing
|
|
1317
|
-
return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
|
|
1318
|
-
}
|
|
1312
|
+
// Accepts an easing function and returns a new one that outputs mirrored values for
|
|
1313
|
+
// the second half of the animation. Turns easeIn into easeInOut.
|
|
1314
|
+
const mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
|
|
1315
|
+
|
|
1316
|
+
// Accepts an easing function and returns a new one that outputs reversed values.
|
|
1317
|
+
// Turns easeIn into easeOut.
|
|
1318
|
+
const reverseEasing = (easing) => (p) => 1 - easing(1 - p);
|
|
1319
1319
|
|
|
1320
1320
|
const circIn = (p) => 1 - Math.sin(Math.acos(p));
|
|
1321
1321
|
const circOut = reverseEasing(circIn);
|
|
@@ -1743,7 +1743,16 @@ function calculateDuration(generator) {
|
|
|
1743
1743
|
}
|
|
1744
1744
|
return duration;
|
|
1745
1745
|
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Animate a single value on the main thread.
|
|
1748
|
+
*
|
|
1749
|
+
* This function is written, where functionality overlaps,
|
|
1750
|
+
* to be largely spec-compliant with WAAPI to allow fungibility
|
|
1751
|
+
* between the two.
|
|
1752
|
+
*/
|
|
1746
1753
|
function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, keyframes: keyframes$1, type = "keyframes", repeat = 0, repeatDelay = 0, repeatType = "loop", onPlay, onStop, onComplete, onUpdate, ...options }) {
|
|
1754
|
+
let speed = 1;
|
|
1755
|
+
let hasStopped = false;
|
|
1747
1756
|
let resolveFinishedPromise;
|
|
1748
1757
|
let currentFinishedPromise;
|
|
1749
1758
|
/**
|
|
@@ -1752,6 +1761,7 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
|
|
|
1752
1761
|
* WAAPI-compatible behaviour.
|
|
1753
1762
|
*/
|
|
1754
1763
|
const updateFinishedPromise = () => {
|
|
1764
|
+
resolveFinishedPromise && resolveFinishedPromise();
|
|
1755
1765
|
currentFinishedPromise = new Promise((resolve) => {
|
|
1756
1766
|
resolveFinishedPromise = resolve;
|
|
1757
1767
|
});
|
|
@@ -1785,6 +1795,7 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
|
|
|
1785
1795
|
let playState = "idle";
|
|
1786
1796
|
let holdTime = null;
|
|
1787
1797
|
let startTime = null;
|
|
1798
|
+
let cancelTime = null;
|
|
1788
1799
|
/**
|
|
1789
1800
|
* If duration is undefined and we have repeat options,
|
|
1790
1801
|
* we need to calculate a duration from the generator.
|
|
@@ -1811,7 +1822,7 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
|
|
|
1811
1822
|
time = holdTime;
|
|
1812
1823
|
}
|
|
1813
1824
|
else {
|
|
1814
|
-
time = timestamp - startTime;
|
|
1825
|
+
time = (timestamp - startTime) * speed;
|
|
1815
1826
|
}
|
|
1816
1827
|
// Rebase on delay
|
|
1817
1828
|
time = Math.max(time - delay, 0);
|
|
@@ -1849,10 +1860,11 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
|
|
|
1849
1860
|
iterationProgress = 1;
|
|
1850
1861
|
}
|
|
1851
1862
|
iterationProgress === 1 && currentIteration--;
|
|
1863
|
+
currentIteration = Math.min(currentIteration, repeat + 1);
|
|
1852
1864
|
/**
|
|
1853
1865
|
* Reverse progress if we're not running in "normal" direction
|
|
1854
1866
|
*/
|
|
1855
|
-
const iterationIsOdd = currentIteration % 2;
|
|
1867
|
+
const iterationIsOdd = Boolean(currentIteration % 2);
|
|
1856
1868
|
if (iterationIsOdd) {
|
|
1857
1869
|
if (repeatType === "reverse") {
|
|
1858
1870
|
iterationProgress = 1 - iterationProgress;
|
|
@@ -1864,36 +1876,51 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
|
|
|
1864
1876
|
frameGenerator = mirroredGenerator;
|
|
1865
1877
|
}
|
|
1866
1878
|
}
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
: clamp(0, 1, iterationProgress);
|
|
1879
|
+
let p = clamp(0, 1, iterationProgress);
|
|
1880
|
+
if (time > totalDuration) {
|
|
1881
|
+
p = repeatType === "reverse" && iterationIsOdd ? 1 : 0;
|
|
1882
|
+
}
|
|
1872
1883
|
elapsed = p * resolvedDuration;
|
|
1873
1884
|
}
|
|
1874
1885
|
const state = frameGenerator.next(elapsed);
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
onUpdate(mapNumbersToKeyframes ? mapNumbersToKeyframes(value) : value);
|
|
1886
|
+
if (mapNumbersToKeyframes) {
|
|
1887
|
+
state.value = mapNumbersToKeyframes(state.value);
|
|
1878
1888
|
}
|
|
1889
|
+
let { done } = state;
|
|
1879
1890
|
if (calculatedDuration !== null) {
|
|
1880
1891
|
done = time >= totalDuration;
|
|
1881
1892
|
}
|
|
1882
1893
|
const isAnimationFinished = holdTime === null &&
|
|
1883
|
-
(playState === "finished" ||
|
|
1894
|
+
(playState === "finished" ||
|
|
1895
|
+
(playState === "running" && done) ||
|
|
1896
|
+
(speed < 0 && time <= 0));
|
|
1897
|
+
if (onUpdate) {
|
|
1898
|
+
onUpdate(state.value);
|
|
1899
|
+
}
|
|
1884
1900
|
if (isAnimationFinished) {
|
|
1885
1901
|
finish();
|
|
1886
1902
|
}
|
|
1887
1903
|
return state;
|
|
1888
1904
|
};
|
|
1889
|
-
const
|
|
1905
|
+
const stopAnimationDriver = () => {
|
|
1890
1906
|
animationDriver && animationDriver.stop();
|
|
1907
|
+
animationDriver = undefined;
|
|
1908
|
+
};
|
|
1909
|
+
const cancel = () => {
|
|
1910
|
+
playState = "idle";
|
|
1911
|
+
stopAnimationDriver();
|
|
1912
|
+
updateFinishedPromise();
|
|
1913
|
+
startTime = cancelTime = null;
|
|
1914
|
+
};
|
|
1915
|
+
const finish = () => {
|
|
1891
1916
|
playState = "finished";
|
|
1892
1917
|
onComplete && onComplete();
|
|
1893
|
-
|
|
1918
|
+
stopAnimationDriver();
|
|
1894
1919
|
updateFinishedPromise();
|
|
1895
1920
|
};
|
|
1896
1921
|
const play = () => {
|
|
1922
|
+
if (hasStopped)
|
|
1923
|
+
return;
|
|
1897
1924
|
if (!animationDriver)
|
|
1898
1925
|
animationDriver = driver(tick);
|
|
1899
1926
|
const now = animationDriver.now();
|
|
@@ -1907,6 +1934,7 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
|
|
|
1907
1934
|
// logic around finished animations
|
|
1908
1935
|
startTime = now;
|
|
1909
1936
|
}
|
|
1937
|
+
cancelTime = startTime;
|
|
1910
1938
|
holdTime = null;
|
|
1911
1939
|
animationDriver.start();
|
|
1912
1940
|
};
|
|
@@ -1923,13 +1951,22 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
|
|
|
1923
1951
|
set time(newTime) {
|
|
1924
1952
|
newTime = secondsToMilliseconds(newTime);
|
|
1925
1953
|
time = newTime;
|
|
1926
|
-
if (holdTime !== null || !animationDriver) {
|
|
1954
|
+
if (holdTime !== null || !animationDriver || speed === 0) {
|
|
1927
1955
|
holdTime = newTime;
|
|
1928
1956
|
}
|
|
1929
1957
|
else {
|
|
1930
|
-
startTime = animationDriver.now() - newTime;
|
|
1958
|
+
startTime = animationDriver.now() - newTime / speed;
|
|
1931
1959
|
}
|
|
1932
1960
|
},
|
|
1961
|
+
get speed() {
|
|
1962
|
+
return speed;
|
|
1963
|
+
},
|
|
1964
|
+
set speed(newSpeed) {
|
|
1965
|
+
if (newSpeed === speed || !animationDriver)
|
|
1966
|
+
return;
|
|
1967
|
+
speed = newSpeed;
|
|
1968
|
+
controls.time = millisecondsToSeconds(time);
|
|
1969
|
+
},
|
|
1933
1970
|
get state() {
|
|
1934
1971
|
return playState;
|
|
1935
1972
|
},
|
|
@@ -1939,12 +1976,20 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
|
|
|
1939
1976
|
holdTime = time;
|
|
1940
1977
|
},
|
|
1941
1978
|
stop: () => {
|
|
1979
|
+
hasStopped = true;
|
|
1942
1980
|
if (playState === "idle")
|
|
1943
1981
|
return;
|
|
1944
1982
|
playState = "idle";
|
|
1945
1983
|
onStop && onStop();
|
|
1946
|
-
|
|
1947
|
-
|
|
1984
|
+
cancel();
|
|
1985
|
+
},
|
|
1986
|
+
cancel: () => {
|
|
1987
|
+
if (cancelTime !== null)
|
|
1988
|
+
tick(cancelTime);
|
|
1989
|
+
cancel();
|
|
1990
|
+
},
|
|
1991
|
+
complete: () => {
|
|
1992
|
+
playState = "finished";
|
|
1948
1993
|
},
|
|
1949
1994
|
sample: (elapsed) => {
|
|
1950
1995
|
startTime = 0;
|
|
@@ -1990,6 +2035,7 @@ function createAcceleratedAnimation(value, valueName, { onUpdate, onComplete, ..
|
|
|
1990
2035
|
/**
|
|
1991
2036
|
* TODO: Unify with js/index
|
|
1992
2037
|
*/
|
|
2038
|
+
let hasStopped = false;
|
|
1993
2039
|
let resolveFinishedPromise;
|
|
1994
2040
|
let currentFinishedPromise;
|
|
1995
2041
|
/**
|
|
@@ -2043,6 +2089,11 @@ function createAcceleratedAnimation(value, valueName, { onUpdate, onComplete, ..
|
|
|
2043
2089
|
*/
|
|
2044
2090
|
ease: ease,
|
|
2045
2091
|
});
|
|
2092
|
+
const safeCancel = () => {
|
|
2093
|
+
sync.update(() => animation.cancel());
|
|
2094
|
+
resolveFinishedPromise();
|
|
2095
|
+
updateFinishedPromise();
|
|
2096
|
+
};
|
|
2046
2097
|
/**
|
|
2047
2098
|
* Prefer the `onfinish` prop as it's more widely supported than
|
|
2048
2099
|
* the `finished` promise.
|
|
@@ -2053,10 +2104,8 @@ function createAcceleratedAnimation(value, valueName, { onUpdate, onComplete, ..
|
|
|
2053
2104
|
*/
|
|
2054
2105
|
animation.onfinish = () => {
|
|
2055
2106
|
value.set(getFinalKeyframe(keyframes, options));
|
|
2056
|
-
sync.update(() => animation.cancel());
|
|
2057
2107
|
onComplete && onComplete();
|
|
2058
|
-
|
|
2059
|
-
updateFinishedPromise();
|
|
2108
|
+
safeCancel();
|
|
2060
2109
|
};
|
|
2061
2110
|
/**
|
|
2062
2111
|
* Animation interrupt callback.
|
|
@@ -2071,9 +2120,20 @@ function createAcceleratedAnimation(value, valueName, { onUpdate, onComplete, ..
|
|
|
2071
2120
|
set time(newTime) {
|
|
2072
2121
|
animation.currentTime = secondsToMilliseconds(newTime);
|
|
2073
2122
|
},
|
|
2074
|
-
|
|
2123
|
+
get speed() {
|
|
2124
|
+
return animation.playbackRate;
|
|
2125
|
+
},
|
|
2126
|
+
set speed(newSpeed) {
|
|
2127
|
+
animation.playbackRate = newSpeed;
|
|
2128
|
+
},
|
|
2129
|
+
play: () => {
|
|
2130
|
+
if (hasStopped)
|
|
2131
|
+
return;
|
|
2132
|
+
animation.play();
|
|
2133
|
+
},
|
|
2075
2134
|
pause: () => animation.pause(),
|
|
2076
2135
|
stop: () => {
|
|
2136
|
+
hasStopped = true;
|
|
2077
2137
|
if (animation.playState === "idle")
|
|
2078
2138
|
return;
|
|
2079
2139
|
/**
|
|
@@ -2092,8 +2152,10 @@ function createAcceleratedAnimation(value, valueName, { onUpdate, onComplete, ..
|
|
|
2092
2152
|
});
|
|
2093
2153
|
value.setWithVelocity(sampleAnimation.sample(currentTime - sampleDelta).value, sampleAnimation.sample(currentTime).value, sampleDelta);
|
|
2094
2154
|
}
|
|
2095
|
-
|
|
2155
|
+
safeCancel();
|
|
2096
2156
|
},
|
|
2157
|
+
complete: () => animation.finish(),
|
|
2158
|
+
cancel: safeCancel,
|
|
2097
2159
|
};
|
|
2098
2160
|
}
|
|
2099
2161
|
|
|
@@ -2101,8 +2163,16 @@ function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplet
|
|
|
2101
2163
|
const setValue = () => {
|
|
2102
2164
|
onUpdate && onUpdate(keyframes[keyframes.length - 1]);
|
|
2103
2165
|
onComplete && onComplete();
|
|
2166
|
+
/**
|
|
2167
|
+
* TODO: As this API grows it could make sense to always return
|
|
2168
|
+
* animateValue. This will be a bigger project as animateValue
|
|
2169
|
+
* is frame-locked whereas this function resolves instantly.
|
|
2170
|
+
* This is a behavioural change and also has ramifications regarding
|
|
2171
|
+
* assumptions within tests.
|
|
2172
|
+
*/
|
|
2104
2173
|
return {
|
|
2105
2174
|
time: 0,
|
|
2175
|
+
speed: 1,
|
|
2106
2176
|
play: (noop),
|
|
2107
2177
|
pause: (noop),
|
|
2108
2178
|
stop: (noop),
|
|
@@ -2110,6 +2180,8 @@ function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplet
|
|
|
2110
2180
|
resolve();
|
|
2111
2181
|
return Promise.resolve();
|
|
2112
2182
|
},
|
|
2183
|
+
cancel: (noop),
|
|
2184
|
+
complete: (noop),
|
|
2113
2185
|
};
|
|
2114
2186
|
};
|
|
2115
2187
|
return delayBy
|
|
@@ -2334,6 +2406,7 @@ const animateMotionValue = (valueName, value, target, transition = {}) => {
|
|
|
2334
2406
|
let options = {
|
|
2335
2407
|
keyframes,
|
|
2336
2408
|
velocity: value.getVelocity(),
|
|
2409
|
+
ease: "easeOut",
|
|
2337
2410
|
...valueTransition,
|
|
2338
2411
|
delay: -elapsed,
|
|
2339
2412
|
onUpdate: (v) => {
|
|
@@ -2496,7 +2569,7 @@ class MotionValue {
|
|
|
2496
2569
|
* This will be replaced by the build step with the latest version number.
|
|
2497
2570
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
2498
2571
|
*/
|
|
2499
|
-
this.version = "10.
|
|
2572
|
+
this.version = "10.6.1";
|
|
2500
2573
|
/**
|
|
2501
2574
|
* Duration, in milliseconds, since last updating frame.
|
|
2502
2575
|
*
|
|
@@ -3265,18 +3338,26 @@ class GroupPlaybackControls {
|
|
|
3265
3338
|
/**
|
|
3266
3339
|
* TODO: Filter out cancelled or stopped animations before returning
|
|
3267
3340
|
*/
|
|
3268
|
-
|
|
3269
|
-
return this.animations[0]
|
|
3341
|
+
getAll(propName) {
|
|
3342
|
+
return this.animations[0][propName];
|
|
3270
3343
|
}
|
|
3271
|
-
|
|
3272
|
-
* time assignment could reasonably run every frame, so
|
|
3273
|
-
* we iterate using a normal loop to avoid function creation.
|
|
3274
|
-
*/
|
|
3275
|
-
set time(time) {
|
|
3344
|
+
setAll(propName, newValue) {
|
|
3276
3345
|
for (let i = 0; i < this.animations.length; i++) {
|
|
3277
|
-
this.animations[i]
|
|
3346
|
+
this.animations[i][propName] = newValue;
|
|
3278
3347
|
}
|
|
3279
3348
|
}
|
|
3349
|
+
get time() {
|
|
3350
|
+
return this.getAll("time");
|
|
3351
|
+
}
|
|
3352
|
+
set time(time) {
|
|
3353
|
+
this.setAll("time", time);
|
|
3354
|
+
}
|
|
3355
|
+
get speed() {
|
|
3356
|
+
return this.getAll("speed");
|
|
3357
|
+
}
|
|
3358
|
+
set speed(speed) {
|
|
3359
|
+
this.setAll("speed", speed);
|
|
3360
|
+
}
|
|
3280
3361
|
runAll(methodName) {
|
|
3281
3362
|
this.animations.forEach((controls) => controls[methodName]());
|
|
3282
3363
|
}
|
|
@@ -3289,6 +3370,12 @@ class GroupPlaybackControls {
|
|
|
3289
3370
|
stop() {
|
|
3290
3371
|
this.runAll("stop");
|
|
3291
3372
|
}
|
|
3373
|
+
cancel() {
|
|
3374
|
+
this.runAll("cancel");
|
|
3375
|
+
}
|
|
3376
|
+
complete() {
|
|
3377
|
+
this.runAll("complete");
|
|
3378
|
+
}
|
|
3292
3379
|
}
|
|
3293
3380
|
|
|
3294
3381
|
function isDOMKeyframes(keyframes) {
|
|
@@ -3641,7 +3728,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
3641
3728
|
* and warn against mismatches.
|
|
3642
3729
|
*/
|
|
3643
3730
|
if (process.env.NODE_ENV === "development") {
|
|
3644
|
-
warnOnce(nextValue.version === "10.
|
|
3731
|
+
warnOnce(nextValue.version === "10.6.1", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.6.1 may not work as expected.`);
|
|
3645
3732
|
}
|
|
3646
3733
|
}
|
|
3647
3734
|
else if (isMotionValue(prevValue)) {
|
package/dist/dom-entry.d.ts
CHANGED
|
@@ -818,9 +818,12 @@ declare type ElementOrSelector = Element | Element[] | NodeListOf<Element> | str
|
|
|
818
818
|
*/
|
|
819
819
|
interface AnimationPlaybackControls {
|
|
820
820
|
time: number;
|
|
821
|
+
speed: number;
|
|
821
822
|
stop: () => void;
|
|
822
823
|
play: () => void;
|
|
823
824
|
pause: () => void;
|
|
825
|
+
complete: () => void;
|
|
826
|
+
cancel: () => void;
|
|
824
827
|
then: (onResolve: VoidFunction, onReject?: VoidFunction) => Promise<void>;
|
|
825
828
|
}
|
|
826
829
|
interface CSSStyleDeclarationWithTransform extends Omit<CSSStyleDeclaration, "direction" | "transition"> {
|
|
@@ -1078,9 +1081,9 @@ declare const circIn: EasingFunction;
|
|
|
1078
1081
|
declare const circOut: EasingFunction;
|
|
1079
1082
|
declare const circInOut: EasingFunction;
|
|
1080
1083
|
|
|
1081
|
-
declare const easeIn: (
|
|
1082
|
-
declare const easeOut:
|
|
1083
|
-
declare const easeInOut:
|
|
1084
|
+
declare const easeIn: (t: number) => number;
|
|
1085
|
+
declare const easeOut: (t: number) => number;
|
|
1086
|
+
declare const easeInOut: (t: number) => number;
|
|
1084
1087
|
|
|
1085
1088
|
declare function cubicBezier(mX1: number, mY1: number, mX2: number, mY2: number): (t: number) => number;
|
|
1086
1089
|
|
|
@@ -8,18 +8,26 @@ class GroupPlaybackControls {
|
|
|
8
8
|
/**
|
|
9
9
|
* TODO: Filter out cancelled or stopped animations before returning
|
|
10
10
|
*/
|
|
11
|
-
|
|
12
|
-
return this.animations[0]
|
|
11
|
+
getAll(propName) {
|
|
12
|
+
return this.animations[0][propName];
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
* time assignment could reasonably run every frame, so
|
|
16
|
-
* we iterate using a normal loop to avoid function creation.
|
|
17
|
-
*/
|
|
18
|
-
set time(time) {
|
|
14
|
+
setAll(propName, newValue) {
|
|
19
15
|
for (let i = 0; i < this.animations.length; i++) {
|
|
20
|
-
this.animations[i]
|
|
16
|
+
this.animations[i][propName] = newValue;
|
|
21
17
|
}
|
|
22
18
|
}
|
|
19
|
+
get time() {
|
|
20
|
+
return this.getAll("time");
|
|
21
|
+
}
|
|
22
|
+
set time(time) {
|
|
23
|
+
this.setAll("time", time);
|
|
24
|
+
}
|
|
25
|
+
get speed() {
|
|
26
|
+
return this.getAll("speed");
|
|
27
|
+
}
|
|
28
|
+
set speed(speed) {
|
|
29
|
+
this.setAll("speed", speed);
|
|
30
|
+
}
|
|
23
31
|
runAll(methodName) {
|
|
24
32
|
this.animations.forEach((controls) => controls[methodName]());
|
|
25
33
|
}
|
|
@@ -32,6 +40,12 @@ class GroupPlaybackControls {
|
|
|
32
40
|
stop() {
|
|
33
41
|
this.runAll("stop");
|
|
34
42
|
}
|
|
43
|
+
cancel() {
|
|
44
|
+
this.runAll("cancel");
|
|
45
|
+
}
|
|
46
|
+
complete() {
|
|
47
|
+
this.runAll("complete");
|
|
48
|
+
}
|
|
35
49
|
}
|
|
36
50
|
|
|
37
51
|
export { GroupPlaybackControls };
|
|
@@ -5,8 +5,16 @@ function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplet
|
|
|
5
5
|
const setValue = () => {
|
|
6
6
|
onUpdate && onUpdate(keyframes[keyframes.length - 1]);
|
|
7
7
|
onComplete && onComplete();
|
|
8
|
+
/**
|
|
9
|
+
* TODO: As this API grows it could make sense to always return
|
|
10
|
+
* animateValue. This will be a bigger project as animateValue
|
|
11
|
+
* is frame-locked whereas this function resolves instantly.
|
|
12
|
+
* This is a behavioural change and also has ramifications regarding
|
|
13
|
+
* assumptions within tests.
|
|
14
|
+
*/
|
|
8
15
|
return {
|
|
9
16
|
time: 0,
|
|
17
|
+
speed: 1,
|
|
10
18
|
play: (noop),
|
|
11
19
|
pause: (noop),
|
|
12
20
|
stop: (noop),
|
|
@@ -14,6 +22,8 @@ function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplet
|
|
|
14
22
|
resolve();
|
|
15
23
|
return Promise.resolve();
|
|
16
24
|
},
|
|
25
|
+
cancel: (noop),
|
|
26
|
+
complete: (noop),
|
|
17
27
|
};
|
|
18
28
|
};
|
|
19
29
|
return delayBy
|