motion 11.11.17 → 11.12.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/.turbo/turbo-build.log +15 -17
- package/README.md +16 -3
- package/dist/cjs/index.js +128 -74
- package/dist/cjs/mini.js +3 -3
- package/dist/cjs/react-client.js +127 -74
- package/dist/cjs/react-mini.js +3 -3
- package/dist/es/framer-motion/dist/es/animation/animators/waapi/NativeAnimation.mjs +1 -0
- package/dist/es/framer-motion/dist/es/animation/animators/waapi/utils/linear.mjs +2 -3
- package/dist/es/framer-motion/dist/es/animation/generators/spring/defaults.mjs +27 -0
- package/dist/es/framer-motion/dist/es/animation/generators/spring/find.mjs +8 -11
- package/dist/es/framer-motion/dist/es/animation/generators/spring/index.mjs +53 -17
- package/dist/es/framer-motion/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/framer-motion/dist/es/value/index.mjs +1 -1
- package/dist/motion.dev.js +128 -74
- package/dist/motion.js +1 -1
- package/package.json +3 -3
package/dist/cjs/react-client.js
CHANGED
|
@@ -1479,6 +1479,34 @@ class BaseAnimation {
|
|
|
1479
1479
|
}
|
|
1480
1480
|
}
|
|
1481
1481
|
|
|
1482
|
+
/*
|
|
1483
|
+
Progress within given range
|
|
1484
|
+
|
|
1485
|
+
Given a lower limit and an upper limit, we return the progress
|
|
1486
|
+
(expressed as a number 0-1) represented by the given value, and
|
|
1487
|
+
limit that progress to within 0-1.
|
|
1488
|
+
|
|
1489
|
+
@param [number]: Lower limit
|
|
1490
|
+
@param [number]: Upper limit
|
|
1491
|
+
@param [number]: Value to find progress within given range
|
|
1492
|
+
@return [number]: Progress of value within range as expressed 0-1
|
|
1493
|
+
*/
|
|
1494
|
+
const progress = (from, to, value) => {
|
|
1495
|
+
const toFromDifference = to - from;
|
|
1496
|
+
return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
|
|
1497
|
+
};
|
|
1498
|
+
|
|
1499
|
+
const generateLinearEasing = (easing, duration, // as milliseconds
|
|
1500
|
+
resolution = 10 // as milliseconds
|
|
1501
|
+
) => {
|
|
1502
|
+
let points = "";
|
|
1503
|
+
const numPoints = Math.max(Math.round(duration / resolution), 2);
|
|
1504
|
+
for (let i = 0; i < numPoints; i++) {
|
|
1505
|
+
points += easing(progress(0, numPoints - 1, i)) + ", ";
|
|
1506
|
+
}
|
|
1507
|
+
return `linear(${points.substring(0, points.length - 2)})`;
|
|
1508
|
+
};
|
|
1509
|
+
|
|
1482
1510
|
/*
|
|
1483
1511
|
Convert velocity into velocity per second
|
|
1484
1512
|
|
|
@@ -1495,21 +1523,43 @@ function calcGeneratorVelocity(resolveValue, t, current) {
|
|
|
1495
1523
|
return velocityPerSecond(current - resolveValue(prevT), t - prevT);
|
|
1496
1524
|
}
|
|
1497
1525
|
|
|
1526
|
+
const springDefaults = {
|
|
1527
|
+
// Default spring physics
|
|
1528
|
+
stiffness: 100,
|
|
1529
|
+
damping: 10,
|
|
1530
|
+
mass: 1.0,
|
|
1531
|
+
velocity: 0.0,
|
|
1532
|
+
// Default duration/bounce-based options
|
|
1533
|
+
duration: 800, // in ms
|
|
1534
|
+
bounce: 0.3,
|
|
1535
|
+
visualDuration: 0.3, // in seconds
|
|
1536
|
+
// Rest thresholds
|
|
1537
|
+
restSpeed: {
|
|
1538
|
+
granular: 0.01,
|
|
1539
|
+
default: 2,
|
|
1540
|
+
},
|
|
1541
|
+
restDelta: {
|
|
1542
|
+
granular: 0.005,
|
|
1543
|
+
default: 0.5,
|
|
1544
|
+
},
|
|
1545
|
+
// Limits
|
|
1546
|
+
minDuration: 0.01, // in seconds
|
|
1547
|
+
maxDuration: 10.0, // in seconds
|
|
1548
|
+
minDamping: 0.05,
|
|
1549
|
+
maxDamping: 1,
|
|
1550
|
+
};
|
|
1551
|
+
|
|
1498
1552
|
const safeMin = 0.001;
|
|
1499
|
-
|
|
1500
|
-
const maxDuration$1 = 10.0;
|
|
1501
|
-
const minDamping = 0.05;
|
|
1502
|
-
const maxDamping = 1;
|
|
1503
|
-
function findSpring({ duration = 800, bounce = 0.25, velocity = 0, mass = 1, }) {
|
|
1553
|
+
function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass, }) {
|
|
1504
1554
|
let envelope;
|
|
1505
1555
|
let derivative;
|
|
1506
|
-
warning(duration <= secondsToMilliseconds(maxDuration
|
|
1556
|
+
warning(duration <= secondsToMilliseconds(springDefaults.maxDuration), "Spring duration must be 10 seconds or less");
|
|
1507
1557
|
let dampingRatio = 1 - bounce;
|
|
1508
1558
|
/**
|
|
1509
1559
|
* Restrict dampingRatio and duration to within acceptable ranges.
|
|
1510
1560
|
*/
|
|
1511
|
-
dampingRatio = clamp(minDamping, maxDamping, dampingRatio);
|
|
1512
|
-
duration = clamp(minDuration, maxDuration
|
|
1561
|
+
dampingRatio = clamp(springDefaults.minDamping, springDefaults.maxDamping, dampingRatio);
|
|
1562
|
+
duration = clamp(springDefaults.minDuration, springDefaults.maxDuration, millisecondsToSeconds(duration));
|
|
1513
1563
|
if (dampingRatio < 1) {
|
|
1514
1564
|
/**
|
|
1515
1565
|
* Underdamped spring
|
|
@@ -1553,8 +1603,8 @@ function findSpring({ duration = 800, bounce = 0.25, velocity = 0, mass = 1, })
|
|
|
1553
1603
|
duration = secondsToMilliseconds(duration);
|
|
1554
1604
|
if (isNaN(undampedFreq)) {
|
|
1555
1605
|
return {
|
|
1556
|
-
stiffness:
|
|
1557
|
-
damping:
|
|
1606
|
+
stiffness: springDefaults.stiffness,
|
|
1607
|
+
damping: springDefaults.damping,
|
|
1558
1608
|
duration,
|
|
1559
1609
|
};
|
|
1560
1610
|
}
|
|
@@ -1579,6 +1629,22 @@ function calcAngularFreq(undampedFreq, dampingRatio) {
|
|
|
1579
1629
|
return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
|
|
1580
1630
|
}
|
|
1581
1631
|
|
|
1632
|
+
/**
|
|
1633
|
+
* Implement a practical max duration for keyframe generation
|
|
1634
|
+
* to prevent infinite loops
|
|
1635
|
+
*/
|
|
1636
|
+
const maxGeneratorDuration = 20000;
|
|
1637
|
+
function calcGeneratorDuration(generator) {
|
|
1638
|
+
let duration = 0;
|
|
1639
|
+
const timeStep = 50;
|
|
1640
|
+
let state = generator.next(duration);
|
|
1641
|
+
while (!state.done && duration < maxGeneratorDuration) {
|
|
1642
|
+
duration += timeStep;
|
|
1643
|
+
state = generator.next(duration);
|
|
1644
|
+
}
|
|
1645
|
+
return duration >= maxGeneratorDuration ? Infinity : duration;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1582
1648
|
const durationKeys = ["duration", "bounce"];
|
|
1583
1649
|
const physicsKeys = ["stiffness", "damping", "mass"];
|
|
1584
1650
|
function isSpringType(options, keys) {
|
|
@@ -1586,29 +1652,51 @@ function isSpringType(options, keys) {
|
|
|
1586
1652
|
}
|
|
1587
1653
|
function getSpringOptions(options) {
|
|
1588
1654
|
let springOptions = {
|
|
1589
|
-
velocity:
|
|
1590
|
-
stiffness:
|
|
1591
|
-
damping:
|
|
1592
|
-
mass:
|
|
1655
|
+
velocity: springDefaults.velocity,
|
|
1656
|
+
stiffness: springDefaults.stiffness,
|
|
1657
|
+
damping: springDefaults.damping,
|
|
1658
|
+
mass: springDefaults.mass,
|
|
1593
1659
|
isResolvedFromDuration: false,
|
|
1594
1660
|
...options,
|
|
1595
1661
|
};
|
|
1596
1662
|
// stiffness/damping/mass overrides duration/bounce
|
|
1597
1663
|
if (!isSpringType(options, physicsKeys) &&
|
|
1598
1664
|
isSpringType(options, durationKeys)) {
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1665
|
+
if (options.visualDuration) {
|
|
1666
|
+
const visualDuration = options.visualDuration;
|
|
1667
|
+
const root = (2 * Math.PI) / (visualDuration * 1.2);
|
|
1668
|
+
const stiffness = root * root;
|
|
1669
|
+
const damping = 2 * clamp(0.05, 1, 1 - options.bounce) * Math.sqrt(stiffness);
|
|
1670
|
+
springOptions = {
|
|
1671
|
+
...springOptions,
|
|
1672
|
+
mass: springDefaults.mass,
|
|
1673
|
+
stiffness,
|
|
1674
|
+
damping,
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1677
|
+
else {
|
|
1678
|
+
const derived = findSpring(options);
|
|
1679
|
+
springOptions = {
|
|
1680
|
+
...springOptions,
|
|
1681
|
+
...derived,
|
|
1682
|
+
mass: springDefaults.mass,
|
|
1683
|
+
};
|
|
1684
|
+
springOptions.isResolvedFromDuration = true;
|
|
1685
|
+
}
|
|
1606
1686
|
}
|
|
1607
1687
|
return springOptions;
|
|
1608
1688
|
}
|
|
1609
|
-
function spring(
|
|
1610
|
-
const
|
|
1611
|
-
|
|
1689
|
+
function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce = springDefaults.bounce) {
|
|
1690
|
+
const options = typeof optionsOrVisualDuration !== "object"
|
|
1691
|
+
? {
|
|
1692
|
+
visualDuration: optionsOrVisualDuration,
|
|
1693
|
+
keyframes: [0, 1],
|
|
1694
|
+
bounce,
|
|
1695
|
+
}
|
|
1696
|
+
: optionsOrVisualDuration;
|
|
1697
|
+
let { restSpeed, restDelta } = options;
|
|
1698
|
+
const origin = options.keyframes[0];
|
|
1699
|
+
const target = options.keyframes[options.keyframes.length - 1];
|
|
1612
1700
|
/**
|
|
1613
1701
|
* This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
|
|
1614
1702
|
* to reduce GC during animation.
|
|
@@ -1630,8 +1718,12 @@ function spring({ keyframes, restDelta, restSpeed, ...options }) {
|
|
|
1630
1718
|
* ratio between feeling good and finishing as soon as changes are imperceptible.
|
|
1631
1719
|
*/
|
|
1632
1720
|
const isGranularScale = Math.abs(initialDelta) < 5;
|
|
1633
|
-
restSpeed || (restSpeed = isGranularScale
|
|
1634
|
-
|
|
1721
|
+
restSpeed || (restSpeed = isGranularScale
|
|
1722
|
+
? springDefaults.restSpeed.granular
|
|
1723
|
+
: springDefaults.restSpeed.default);
|
|
1724
|
+
restDelta || (restDelta = isGranularScale
|
|
1725
|
+
? springDefaults.restDelta.granular
|
|
1726
|
+
: springDefaults.restDelta.default);
|
|
1635
1727
|
let resolveSpring;
|
|
1636
1728
|
if (dampingRatio < 1) {
|
|
1637
1729
|
const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
|
|
@@ -1672,7 +1764,7 @@ function spring({ keyframes, restDelta, restSpeed, ...options }) {
|
|
|
1672
1764
|
dampedAngularFreq);
|
|
1673
1765
|
};
|
|
1674
1766
|
}
|
|
1675
|
-
|
|
1767
|
+
const generator = {
|
|
1676
1768
|
calculatedDuration: isResolvedFromDuration ? duration || null : null,
|
|
1677
1769
|
next: (t) => {
|
|
1678
1770
|
const current = resolveSpring(t);
|
|
@@ -1700,7 +1792,13 @@ function spring({ keyframes, restDelta, restSpeed, ...options }) {
|
|
|
1700
1792
|
state.value = state.done ? target : current;
|
|
1701
1793
|
return state;
|
|
1702
1794
|
},
|
|
1795
|
+
toString: () => {
|
|
1796
|
+
const calculatedDuration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
|
|
1797
|
+
const easing = generateLinearEasing((progress) => generator.next(calculatedDuration * progress).value, calculatedDuration, 30);
|
|
1798
|
+
return calculatedDuration + "ms " + easing;
|
|
1799
|
+
},
|
|
1703
1800
|
};
|
|
1801
|
+
return generator;
|
|
1704
1802
|
}
|
|
1705
1803
|
|
|
1706
1804
|
function inertia({ keyframes, velocity = 0.0, power = 0.8, timeConstant = 325, bounceDamping = 10, bounceStiffness = 500, modifyTarget, min, max, restDelta = 0.5, restSpeed, }) {
|
|
@@ -1834,23 +1932,6 @@ const easingDefinitionToFunction = (definition) => {
|
|
|
1834
1932
|
const combineFunctions = (a, b) => (v) => b(a(v));
|
|
1835
1933
|
const pipe = (...transformers) => transformers.reduce(combineFunctions);
|
|
1836
1934
|
|
|
1837
|
-
/*
|
|
1838
|
-
Progress within given range
|
|
1839
|
-
|
|
1840
|
-
Given a lower limit and an upper limit, we return the progress
|
|
1841
|
-
(expressed as a number 0-1) represented by the given value, and
|
|
1842
|
-
limit that progress to within 0-1.
|
|
1843
|
-
|
|
1844
|
-
@param [number]: Lower limit
|
|
1845
|
-
@param [number]: Upper limit
|
|
1846
|
-
@param [number]: Value to find progress within given range
|
|
1847
|
-
@return [number]: Progress of value within range as expressed 0-1
|
|
1848
|
-
*/
|
|
1849
|
-
const progress = (from, to, value) => {
|
|
1850
|
-
const toFromDifference = to - from;
|
|
1851
|
-
return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
|
|
1852
|
-
};
|
|
1853
|
-
|
|
1854
1935
|
/*
|
|
1855
1936
|
Value in range from progress
|
|
1856
1937
|
|
|
@@ -2195,22 +2276,6 @@ function keyframes({ duration = 300, keyframes: keyframeValues, times, ease = "e
|
|
|
2195
2276
|
};
|
|
2196
2277
|
}
|
|
2197
2278
|
|
|
2198
|
-
/**
|
|
2199
|
-
* Implement a practical max duration for keyframe generation
|
|
2200
|
-
* to prevent infinite loops
|
|
2201
|
-
*/
|
|
2202
|
-
const maxGeneratorDuration = 20000;
|
|
2203
|
-
function calcGeneratorDuration(generator) {
|
|
2204
|
-
let duration = 0;
|
|
2205
|
-
const timeStep = 50;
|
|
2206
|
-
let state = generator.next(duration);
|
|
2207
|
-
while (!state.done && duration < maxGeneratorDuration) {
|
|
2208
|
-
duration += timeStep;
|
|
2209
|
-
state = generator.next(duration);
|
|
2210
|
-
}
|
|
2211
|
-
return duration >= maxGeneratorDuration ? Infinity : duration;
|
|
2212
|
-
}
|
|
2213
|
-
|
|
2214
2279
|
const frameloopDriver = (update) => {
|
|
2215
2280
|
const passTimestamp = ({ timestamp }) => update(timestamp);
|
|
2216
2281
|
return {
|
|
@@ -2608,18 +2673,6 @@ const acceleratedValues = new Set([
|
|
|
2608
2673
|
// "background-color"
|
|
2609
2674
|
]);
|
|
2610
2675
|
|
|
2611
|
-
// Create a linear easing point for every 10 ms
|
|
2612
|
-
const resolution = 10;
|
|
2613
|
-
const generateLinearEasing = (easing, duration // as milliseconds
|
|
2614
|
-
) => {
|
|
2615
|
-
let points = "";
|
|
2616
|
-
const numPoints = Math.max(Math.round(duration / resolution), 2);
|
|
2617
|
-
for (let i = 0; i < numPoints; i++) {
|
|
2618
|
-
points += easing(progress(0, numPoints - 1, i)) + ", ";
|
|
2619
|
-
}
|
|
2620
|
-
return `linear(${points.substring(0, points.length - 2)})`;
|
|
2621
|
-
};
|
|
2622
|
-
|
|
2623
2676
|
function memo(callback) {
|
|
2624
2677
|
let result;
|
|
2625
2678
|
return () => {
|
|
@@ -3295,7 +3348,7 @@ class MotionValue {
|
|
|
3295
3348
|
* This will be replaced by the build step with the latest version number.
|
|
3296
3349
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
3297
3350
|
*/
|
|
3298
|
-
this.version = "11.
|
|
3351
|
+
this.version = "11.12.0";
|
|
3299
3352
|
/**
|
|
3300
3353
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
3301
3354
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -9038,7 +9091,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
9038
9091
|
* and warn against mismatches.
|
|
9039
9092
|
*/
|
|
9040
9093
|
if (process.env.NODE_ENV === "development") {
|
|
9041
|
-
warnOnce(nextValue.version === "11.
|
|
9094
|
+
warnOnce(nextValue.version === "11.12.0", `Attempting to mix Motion versions ${nextValue.version} with 11.12.0 may not work as expected.`);
|
|
9042
9095
|
}
|
|
9043
9096
|
}
|
|
9044
9097
|
else if (isMotionValue(prevValue)) {
|
package/dist/cjs/react-mini.js
CHANGED
|
@@ -184,9 +184,8 @@ const progress = (from, to, value) => {
|
|
|
184
184
|
return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
|
|
185
185
|
};
|
|
186
186
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const generateLinearEasing = (easing, duration // as milliseconds
|
|
187
|
+
const generateLinearEasing = (easing, duration, // as milliseconds
|
|
188
|
+
resolution = 10 // as milliseconds
|
|
190
189
|
) => {
|
|
191
190
|
let points = "";
|
|
192
191
|
const numPoints = Math.max(Math.round(duration / resolution), 2);
|
|
@@ -424,6 +423,7 @@ class NativeAnimation {
|
|
|
424
423
|
valueKeyframes = [valueKeyframes];
|
|
425
424
|
}
|
|
426
425
|
hydrateKeyframes(valueName, valueKeyframes, readInitialKeyframe);
|
|
426
|
+
// TODO: Replace this with toString()?
|
|
427
427
|
if (isGenerator(options.type)) {
|
|
428
428
|
const generatorOptions = createGeneratorEasing(options, 100, options.type);
|
|
429
429
|
options.ease = supportsLinearEasing()
|
|
@@ -51,6 +51,7 @@ class NativeAnimation {
|
|
|
51
51
|
valueKeyframes = [valueKeyframes];
|
|
52
52
|
}
|
|
53
53
|
hydrateKeyframes(valueName, valueKeyframes, readInitialKeyframe);
|
|
54
|
+
// TODO: Replace this with toString()?
|
|
54
55
|
if (isGenerator(options.type)) {
|
|
55
56
|
const generatorOptions = createGeneratorEasing(options, 100, options.type);
|
|
56
57
|
options.ease = supportsLinearEasing()
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { progress } from '../../../../utils/progress.mjs';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const generateLinearEasing = (easing, duration // as milliseconds
|
|
3
|
+
const generateLinearEasing = (easing, duration, // as milliseconds
|
|
4
|
+
resolution = 10 // as milliseconds
|
|
6
5
|
) => {
|
|
7
6
|
let points = "";
|
|
8
7
|
const numPoints = Math.max(Math.round(duration / resolution), 2);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const springDefaults = {
|
|
2
|
+
// Default spring physics
|
|
3
|
+
stiffness: 100,
|
|
4
|
+
damping: 10,
|
|
5
|
+
mass: 1.0,
|
|
6
|
+
velocity: 0.0,
|
|
7
|
+
// Default duration/bounce-based options
|
|
8
|
+
duration: 800, // in ms
|
|
9
|
+
bounce: 0.3,
|
|
10
|
+
visualDuration: 0.3, // in seconds
|
|
11
|
+
// Rest thresholds
|
|
12
|
+
restSpeed: {
|
|
13
|
+
granular: 0.01,
|
|
14
|
+
default: 2,
|
|
15
|
+
},
|
|
16
|
+
restDelta: {
|
|
17
|
+
granular: 0.005,
|
|
18
|
+
default: 0.5,
|
|
19
|
+
},
|
|
20
|
+
// Limits
|
|
21
|
+
minDuration: 0.01, // in seconds
|
|
22
|
+
maxDuration: 10.0, // in seconds
|
|
23
|
+
minDamping: 0.05,
|
|
24
|
+
maxDamping: 1,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { springDefaults };
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
import { warning } from '../../../utils/errors.mjs';
|
|
2
2
|
import { clamp } from '../../../utils/clamp.mjs';
|
|
3
3
|
import { secondsToMilliseconds, millisecondsToSeconds } from '../../../utils/time-conversion.mjs';
|
|
4
|
+
import { springDefaults } from './defaults.mjs';
|
|
4
5
|
|
|
5
6
|
const safeMin = 0.001;
|
|
6
|
-
|
|
7
|
-
const maxDuration = 10.0;
|
|
8
|
-
const minDamping = 0.05;
|
|
9
|
-
const maxDamping = 1;
|
|
10
|
-
function findSpring({ duration = 800, bounce = 0.25, velocity = 0, mass = 1, }) {
|
|
7
|
+
function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass, }) {
|
|
11
8
|
let envelope;
|
|
12
9
|
let derivative;
|
|
13
|
-
warning(duration <= secondsToMilliseconds(maxDuration), "Spring duration must be 10 seconds or less");
|
|
10
|
+
warning(duration <= secondsToMilliseconds(springDefaults.maxDuration), "Spring duration must be 10 seconds or less");
|
|
14
11
|
let dampingRatio = 1 - bounce;
|
|
15
12
|
/**
|
|
16
13
|
* Restrict dampingRatio and duration to within acceptable ranges.
|
|
17
14
|
*/
|
|
18
|
-
dampingRatio = clamp(minDamping, maxDamping, dampingRatio);
|
|
19
|
-
duration = clamp(minDuration, maxDuration, millisecondsToSeconds(duration));
|
|
15
|
+
dampingRatio = clamp(springDefaults.minDamping, springDefaults.maxDamping, dampingRatio);
|
|
16
|
+
duration = clamp(springDefaults.minDuration, springDefaults.maxDuration, millisecondsToSeconds(duration));
|
|
20
17
|
if (dampingRatio < 1) {
|
|
21
18
|
/**
|
|
22
19
|
* Underdamped spring
|
|
@@ -60,8 +57,8 @@ function findSpring({ duration = 800, bounce = 0.25, velocity = 0, mass = 1, })
|
|
|
60
57
|
duration = secondsToMilliseconds(duration);
|
|
61
58
|
if (isNaN(undampedFreq)) {
|
|
62
59
|
return {
|
|
63
|
-
stiffness:
|
|
64
|
-
damping:
|
|
60
|
+
stiffness: springDefaults.stiffness,
|
|
61
|
+
damping: springDefaults.damping,
|
|
65
62
|
duration,
|
|
66
63
|
};
|
|
67
64
|
}
|
|
@@ -86,4 +83,4 @@ function calcAngularFreq(undampedFreq, dampingRatio) {
|
|
|
86
83
|
return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
|
|
87
84
|
}
|
|
88
85
|
|
|
89
|
-
export { calcAngularFreq, findSpring
|
|
86
|
+
export { calcAngularFreq, findSpring };
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { generateLinearEasing } from '../../animators/waapi/utils/linear.mjs';
|
|
1
2
|
import { millisecondsToSeconds, secondsToMilliseconds } from '../../../utils/time-conversion.mjs';
|
|
2
3
|
import { calcGeneratorVelocity } from '../utils/velocity.mjs';
|
|
3
4
|
import { findSpring, calcAngularFreq } from './find.mjs';
|
|
5
|
+
import { calcGeneratorDuration, maxGeneratorDuration } from '../utils/calc-duration.mjs';
|
|
6
|
+
import { clamp } from '../../../utils/clamp.mjs';
|
|
7
|
+
import { springDefaults } from './defaults.mjs';
|
|
4
8
|
|
|
5
9
|
const durationKeys = ["duration", "bounce"];
|
|
6
10
|
const physicsKeys = ["stiffness", "damping", "mass"];
|
|
@@ -9,29 +13,51 @@ function isSpringType(options, keys) {
|
|
|
9
13
|
}
|
|
10
14
|
function getSpringOptions(options) {
|
|
11
15
|
let springOptions = {
|
|
12
|
-
velocity:
|
|
13
|
-
stiffness:
|
|
14
|
-
damping:
|
|
15
|
-
mass:
|
|
16
|
+
velocity: springDefaults.velocity,
|
|
17
|
+
stiffness: springDefaults.stiffness,
|
|
18
|
+
damping: springDefaults.damping,
|
|
19
|
+
mass: springDefaults.mass,
|
|
16
20
|
isResolvedFromDuration: false,
|
|
17
21
|
...options,
|
|
18
22
|
};
|
|
19
23
|
// stiffness/damping/mass overrides duration/bounce
|
|
20
24
|
if (!isSpringType(options, physicsKeys) &&
|
|
21
25
|
isSpringType(options, durationKeys)) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
if (options.visualDuration) {
|
|
27
|
+
const visualDuration = options.visualDuration;
|
|
28
|
+
const root = (2 * Math.PI) / (visualDuration * 1.2);
|
|
29
|
+
const stiffness = root * root;
|
|
30
|
+
const damping = 2 * clamp(0.05, 1, 1 - options.bounce) * Math.sqrt(stiffness);
|
|
31
|
+
springOptions = {
|
|
32
|
+
...springOptions,
|
|
33
|
+
mass: springDefaults.mass,
|
|
34
|
+
stiffness,
|
|
35
|
+
damping,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const derived = findSpring(options);
|
|
40
|
+
springOptions = {
|
|
41
|
+
...springOptions,
|
|
42
|
+
...derived,
|
|
43
|
+
mass: springDefaults.mass,
|
|
44
|
+
};
|
|
45
|
+
springOptions.isResolvedFromDuration = true;
|
|
46
|
+
}
|
|
29
47
|
}
|
|
30
48
|
return springOptions;
|
|
31
49
|
}
|
|
32
|
-
function spring(
|
|
33
|
-
const
|
|
34
|
-
|
|
50
|
+
function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce = springDefaults.bounce) {
|
|
51
|
+
const options = typeof optionsOrVisualDuration !== "object"
|
|
52
|
+
? {
|
|
53
|
+
visualDuration: optionsOrVisualDuration,
|
|
54
|
+
keyframes: [0, 1],
|
|
55
|
+
bounce,
|
|
56
|
+
}
|
|
57
|
+
: optionsOrVisualDuration;
|
|
58
|
+
let { restSpeed, restDelta } = options;
|
|
59
|
+
const origin = options.keyframes[0];
|
|
60
|
+
const target = options.keyframes[options.keyframes.length - 1];
|
|
35
61
|
/**
|
|
36
62
|
* This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
|
|
37
63
|
* to reduce GC during animation.
|
|
@@ -53,8 +79,12 @@ function spring({ keyframes, restDelta, restSpeed, ...options }) {
|
|
|
53
79
|
* ratio between feeling good and finishing as soon as changes are imperceptible.
|
|
54
80
|
*/
|
|
55
81
|
const isGranularScale = Math.abs(initialDelta) < 5;
|
|
56
|
-
restSpeed || (restSpeed = isGranularScale
|
|
57
|
-
|
|
82
|
+
restSpeed || (restSpeed = isGranularScale
|
|
83
|
+
? springDefaults.restSpeed.granular
|
|
84
|
+
: springDefaults.restSpeed.default);
|
|
85
|
+
restDelta || (restDelta = isGranularScale
|
|
86
|
+
? springDefaults.restDelta.granular
|
|
87
|
+
: springDefaults.restDelta.default);
|
|
58
88
|
let resolveSpring;
|
|
59
89
|
if (dampingRatio < 1) {
|
|
60
90
|
const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
|
|
@@ -95,7 +125,7 @@ function spring({ keyframes, restDelta, restSpeed, ...options }) {
|
|
|
95
125
|
dampedAngularFreq);
|
|
96
126
|
};
|
|
97
127
|
}
|
|
98
|
-
|
|
128
|
+
const generator = {
|
|
99
129
|
calculatedDuration: isResolvedFromDuration ? duration || null : null,
|
|
100
130
|
next: (t) => {
|
|
101
131
|
const current = resolveSpring(t);
|
|
@@ -123,7 +153,13 @@ function spring({ keyframes, restDelta, restSpeed, ...options }) {
|
|
|
123
153
|
state.value = state.done ? target : current;
|
|
124
154
|
return state;
|
|
125
155
|
},
|
|
156
|
+
toString: () => {
|
|
157
|
+
const calculatedDuration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
|
|
158
|
+
const easing = generateLinearEasing((progress) => generator.next(calculatedDuration * progress).value, calculatedDuration, 30);
|
|
159
|
+
return calculatedDuration + "ms " + easing;
|
|
160
|
+
},
|
|
126
161
|
};
|
|
162
|
+
return generator;
|
|
127
163
|
}
|
|
128
164
|
|
|
129
165
|
export { spring };
|
|
@@ -17,7 +17,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
17
17
|
* and warn against mismatches.
|
|
18
18
|
*/
|
|
19
19
|
if (process.env.NODE_ENV === "development") {
|
|
20
|
-
warnOnce(nextValue.version === "11.
|
|
20
|
+
warnOnce(nextValue.version === "11.12.0", `Attempting to mix Motion versions ${nextValue.version} with 11.12.0 may not work as expected.`);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
else if (isMotionValue(prevValue)) {
|
|
@@ -34,7 +34,7 @@ class MotionValue {
|
|
|
34
34
|
* This will be replaced by the build step with the latest version number.
|
|
35
35
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
36
36
|
*/
|
|
37
|
-
this.version = "11.
|
|
37
|
+
this.version = "11.12.0";
|
|
38
38
|
/**
|
|
39
39
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
40
40
|
* if the value is numerical, but we might be able to widen the scope here and support
|