framer-motion 7.6.16 → 7.6.18

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.
Files changed (57) hide show
  1. package/dist/cjs/index.js +914 -56
  2. package/dist/es/animation/legacy-popmotion/decay.mjs +27 -0
  3. package/dist/es/animation/legacy-popmotion/find-spring.mjs +88 -0
  4. package/dist/es/animation/legacy-popmotion/index.mjs +101 -0
  5. package/dist/es/animation/legacy-popmotion/inertia.mjs +85 -0
  6. package/dist/es/animation/legacy-popmotion/keyframes.mjs +52 -0
  7. package/dist/es/animation/legacy-popmotion/spring.mjs +146 -0
  8. package/dist/es/animation/utils/easing.mjs +7 -5
  9. package/dist/es/animation/utils/transitions.mjs +2 -1
  10. package/dist/es/components/Reorder/utils/check-reorder.mjs +1 -1
  11. package/dist/es/easing/anticipate.mjs +11 -0
  12. package/dist/es/easing/back.mjs +9 -0
  13. package/dist/es/easing/circ.mjs +8 -0
  14. package/dist/es/easing/cubic-bezier.mjs +51 -0
  15. package/dist/es/easing/ease.mjs +8 -0
  16. package/dist/es/easing/modifiers/mirror.mjs +5 -0
  17. package/dist/es/easing/modifiers/reverse.mjs +5 -0
  18. package/dist/es/gestures/PanSession.mjs +3 -2
  19. package/dist/es/gestures/drag/VisualElementDragControls.mjs +1 -1
  20. package/dist/es/gestures/drag/utils/constraints.mjs +3 -1
  21. package/dist/es/gestures/use-tap-gesture.mjs +1 -1
  22. package/dist/es/index.mjs +5 -0
  23. package/dist/es/projection/animation/mix-values.mjs +5 -2
  24. package/dist/es/projection/geometry/delta-apply.mjs +1 -1
  25. package/dist/es/projection/geometry/delta-calc.mjs +1 -1
  26. package/dist/es/projection/geometry/delta-remove.mjs +1 -1
  27. package/dist/es/projection/node/create-projection-node.mjs +1 -1
  28. package/dist/es/projection/styles/scale-box-shadow.mjs +1 -1
  29. package/dist/es/render/utils/motion-values.mjs +1 -1
  30. package/dist/es/utils/clamp.mjs +3 -0
  31. package/dist/es/utils/distance.mjs +9 -0
  32. package/dist/es/utils/hsla-to-rgba.mjs +42 -0
  33. package/dist/es/utils/interpolate.mjs +91 -0
  34. package/dist/es/utils/mix-color.mjs +37 -0
  35. package/dist/es/utils/mix-complex.mjs +79 -0
  36. package/dist/es/utils/mix.mjs +24 -0
  37. package/dist/es/utils/noop.mjs +3 -0
  38. package/dist/es/utils/pipe.mjs +11 -0
  39. package/dist/es/utils/progress.mjs +18 -0
  40. package/dist/es/utils/transform.mjs +1 -1
  41. package/dist/es/utils/use-cycle.mjs +1 -1
  42. package/dist/es/utils/velocity-per-second.mjs +11 -0
  43. package/dist/es/utils/wrap.mjs +6 -0
  44. package/dist/es/value/index.mjs +2 -2
  45. package/dist/es/value/use-on-change.mjs +3 -1
  46. package/dist/es/value/use-spring.mjs +1 -1
  47. package/dist/framer-motion.dev.js +1272 -1222
  48. package/dist/framer-motion.js +1 -1
  49. package/dist/index.d.ts +41 -30
  50. package/dist/projection.dev.js +1397 -1373
  51. package/dist/size-rollup-dom-animation.js +1 -1
  52. package/dist/size-rollup-dom-max.js +1 -1
  53. package/dist/size-rollup-motion.js +1 -1
  54. package/dist/size-webpack-dom-animation.js +1 -1
  55. package/dist/size-webpack-dom-max.js +1 -1
  56. package/dist/three-entry.d.ts +1 -16
  57. package/package.json +7 -8
package/dist/cjs/index.js CHANGED
@@ -4,7 +4,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var React = require('react');
6
6
  var styleValueTypes = require('style-value-types');
7
- var popmotion = require('popmotion');
8
7
  var heyListen = require('hey-listen');
9
8
  var sync = require('framesync');
10
9
  var dom = require('@motionone/dom');
@@ -1497,6 +1496,16 @@ function useUnmountEffect(callback) {
1497
1496
  return React.useEffect(() => () => callback(), []);
1498
1497
  }
1499
1498
 
1499
+ /**
1500
+ * Pipe
1501
+ * Compose other transformers to run linearily
1502
+ * pipe(min(20), max(40))
1503
+ * @param {...functions} transformers
1504
+ * @return {function}
1505
+ */
1506
+ const combineFunctions = (a, b) => (v) => b(a(v));
1507
+ const pipe = (...transformers) => transformers.reduce(combineFunctions);
1508
+
1500
1509
  /**
1501
1510
  * @param handlers -
1502
1511
  * @internal
@@ -1543,7 +1552,7 @@ function useTapGesture({ onTap, onTapStart, onTapCancel, whileTap, visualElement
1543
1552
  if (isPressing.current)
1544
1553
  return;
1545
1554
  isPressing.current = true;
1546
- cancelPointerEndListeners.current = popmotion.pipe(addPointerEvent(window, "pointerup", onPointerUp, eventOptions), addPointerEvent(window, "pointercancel", onPointerCancel, eventOptions));
1555
+ cancelPointerEndListeners.current = pipe(addPointerEvent(window, "pointerup", onPointerUp, eventOptions), addPointerEvent(window, "pointercancel", onPointerCancel, eventOptions));
1547
1556
  /**
1548
1557
  * Ensure we trigger animations before firing event callback
1549
1558
  */
@@ -1808,28 +1817,104 @@ function shallowCompare(next, prev) {
1808
1817
  */
1809
1818
  const secondsToMilliseconds = (seconds) => seconds * 1000;
1810
1819
 
1820
+ const noop = (any) => any;
1821
+
1822
+ /*
1823
+ Bezier function generator
1824
+ This has been modified from Gaëtan Renaudeau's BezierEasing
1825
+ https://github.com/gre/bezier-easing/blob/master/src/index.js
1826
+ https://github.com/gre/bezier-easing/blob/master/LICENSE
1827
+
1828
+ I've removed the newtonRaphsonIterate algo because in benchmarking it
1829
+ wasn't noticiably faster than binarySubdivision, indeed removing it
1830
+ usually improved times, depending on the curve.
1831
+ I also removed the lookup table, as for the added bundle size and loop we're
1832
+ only cutting ~4 or so subdivision iterations. I bumped the max iterations up
1833
+ to 12 to compensate and this still tended to be faster for no perceivable
1834
+ loss in accuracy.
1835
+ Usage
1836
+ const easeOut = cubicBezier(.17,.67,.83,.67);
1837
+ const x = easeOut(0.5); // returns 0.627...
1838
+ */
1839
+ // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
1840
+ const calcBezier = (t, a1, a2) => (((1.0 - 3.0 * a2 + 3.0 * a1) * t + (3.0 * a2 - 6.0 * a1)) * t + 3.0 * a1) *
1841
+ t;
1842
+ const subdivisionPrecision = 0.0000001;
1843
+ const subdivisionMaxIterations = 12;
1844
+ function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
1845
+ let currentX;
1846
+ let currentT;
1847
+ let i = 0;
1848
+ do {
1849
+ currentT = lowerBound + (upperBound - lowerBound) / 2.0;
1850
+ currentX = calcBezier(currentT, mX1, mX2) - x;
1851
+ if (currentX > 0.0) {
1852
+ upperBound = currentT;
1853
+ }
1854
+ else {
1855
+ lowerBound = currentT;
1856
+ }
1857
+ } while (Math.abs(currentX) > subdivisionPrecision &&
1858
+ ++i < subdivisionMaxIterations);
1859
+ return currentT;
1860
+ }
1861
+ function cubicBezier(mX1, mY1, mX2, mY2) {
1862
+ // If this is a linear gradient, return linear easing
1863
+ if (mX1 === mY1 && mX2 === mY2)
1864
+ return noop;
1865
+ const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
1866
+ // If animation is at start/end, return t without easing
1867
+ return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
1868
+ }
1869
+
1870
+ // Accepts an easing function and returns a new one that outputs mirrored values for
1871
+ // the second half of the animation. Turns easeIn into easeInOut.
1872
+ const mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
1873
+
1874
+ // Accepts an easing function and returns a new one that outputs reversed values.
1875
+ // Turns easeIn into easeOut.
1876
+ const reverseEasing = (easing) => (p) => 1 - easing(1 - p);
1877
+
1878
+ const easeIn = (p) => p * p;
1879
+ const easeOut = reverseEasing(easeIn);
1880
+ const easeInOut = mirrorEasing(easeIn);
1881
+
1882
+ const circIn = (p) => 1 - Math.sin(Math.acos(p));
1883
+ const circOut = reverseEasing(circIn);
1884
+ const circInOut = mirrorEasing(circOut);
1885
+
1886
+ const createBackIn = (power = 1.525) => (p) => p * p * ((power + 1) * p - power);
1887
+ const backIn = createBackIn();
1888
+ const backOut = reverseEasing(backIn);
1889
+ const backInOut = mirrorEasing(backIn);
1890
+
1891
+ const createAnticipate = (power) => {
1892
+ const backEasing = createBackIn(power);
1893
+ return (p) => (p *= 2) < 1
1894
+ ? 0.5 * backEasing(p)
1895
+ : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
1896
+ };
1897
+ const anticipate = createAnticipate();
1898
+
1811
1899
  const easingLookup = {
1812
- linear: popmotion.linear,
1813
- easeIn: popmotion.easeIn,
1814
- easeInOut: popmotion.easeInOut,
1815
- easeOut: popmotion.easeOut,
1816
- circIn: popmotion.circIn,
1817
- circInOut: popmotion.circInOut,
1818
- circOut: popmotion.circOut,
1819
- backIn: popmotion.backIn,
1820
- backInOut: popmotion.backInOut,
1821
- backOut: popmotion.backOut,
1822
- anticipate: popmotion.anticipate,
1823
- bounceIn: popmotion.bounceIn,
1824
- bounceInOut: popmotion.bounceInOut,
1825
- bounceOut: popmotion.bounceOut,
1900
+ linear: noop,
1901
+ easeIn,
1902
+ easeInOut,
1903
+ easeOut,
1904
+ circIn,
1905
+ circInOut,
1906
+ circOut,
1907
+ backIn,
1908
+ backInOut,
1909
+ backOut,
1910
+ anticipate,
1826
1911
  };
1827
1912
  const easingDefinitionToFunction = (definition) => {
1828
1913
  if (Array.isArray(definition)) {
1829
1914
  // If cubic bezier definition, create bezier curve
1830
1915
  heyListen.invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`);
1831
1916
  const [x1, y1, x2, y2] = definition;
1832
- return popmotion.cubicBezier(x1, y1, x2, y2);
1917
+ return cubicBezier(x1, y1, x2, y2);
1833
1918
  }
1834
1919
  else if (typeof definition === "string") {
1835
1920
  // Else lookup from table
@@ -1886,7 +1971,7 @@ const linearTween = () => ({
1886
1971
  ease: "linear",
1887
1972
  duration: 0.3,
1888
1973
  });
1889
- const keyframes = (values) => ({
1974
+ const keyframes$1 = (values) => ({
1890
1975
  type: "keyframes",
1891
1976
  duration: 0.8,
1892
1977
  values,
@@ -1910,7 +1995,7 @@ const defaultTransitions = {
1910
1995
  const getDefaultTransition = (valueKey, to) => {
1911
1996
  let transitionFactory;
1912
1997
  if (isKeyframesTarget(to)) {
1913
- transitionFactory = keyframes;
1998
+ transitionFactory = keyframes$1;
1914
1999
  }
1915
2000
  else {
1916
2001
  transitionFactory =
@@ -1970,6 +2055,758 @@ function delay(callback, timeout) {
1970
2055
  return () => sync.cancelSync.read(checkElapsed);
1971
2056
  }
1972
2057
 
2058
+ const clamp = (min, max, v) => Math.min(Math.max(v, min), max);
2059
+
2060
+ /*
2061
+ Value in range from progress
2062
+
2063
+ Given a lower limit and an upper limit, we return the value within
2064
+ that range as expressed by progress (usually a number from 0 to 1)
2065
+
2066
+ So progress = 0.5 would change
2067
+
2068
+ from -------- to
2069
+
2070
+ to
2071
+
2072
+ from ---- to
2073
+
2074
+ E.g. from = 10, to = 20, progress = 0.5 => 15
2075
+
2076
+ @param [number]: Lower limit of range
2077
+ @param [number]: Upper limit of range
2078
+ @param [number]: The progress between lower and upper limits expressed 0-1
2079
+ @return [number]: Value as calculated from progress within range (not limited within range)
2080
+ */
2081
+ const mix = (from, to, progress) => -progress * from + progress * to + from;
2082
+
2083
+ // Adapted from https://gist.github.com/mjackson/5311256
2084
+ function hueToRgb(p, q, t) {
2085
+ if (t < 0)
2086
+ t += 1;
2087
+ if (t > 1)
2088
+ t -= 1;
2089
+ if (t < 1 / 6)
2090
+ return p + (q - p) * 6 * t;
2091
+ if (t < 1 / 2)
2092
+ return q;
2093
+ if (t < 2 / 3)
2094
+ return p + (q - p) * (2 / 3 - t) * 6;
2095
+ return p;
2096
+ }
2097
+ function hslaToRgba({ hue, saturation, lightness, alpha }) {
2098
+ hue /= 360;
2099
+ saturation /= 100;
2100
+ lightness /= 100;
2101
+ let red = 0;
2102
+ let green = 0;
2103
+ let blue = 0;
2104
+ if (!saturation) {
2105
+ red = green = blue = lightness;
2106
+ }
2107
+ else {
2108
+ const q = lightness < 0.5
2109
+ ? lightness * (1 + saturation)
2110
+ : lightness + saturation - lightness * saturation;
2111
+ const p = 2 * lightness - q;
2112
+ red = hueToRgb(p, q, hue + 1 / 3);
2113
+ green = hueToRgb(p, q, hue);
2114
+ blue = hueToRgb(p, q, hue - 1 / 3);
2115
+ }
2116
+ return {
2117
+ red: Math.round(red * 255),
2118
+ green: Math.round(green * 255),
2119
+ blue: Math.round(blue * 255),
2120
+ alpha,
2121
+ };
2122
+ }
2123
+
2124
+ // Linear color space blending
2125
+ // Explained https://www.youtube.com/watch?v=LKnqECcg6Gw
2126
+ // Demonstrated http://codepen.io/osublake/pen/xGVVaN
2127
+ const mixLinearColor = (from, to, v) => {
2128
+ const fromExpo = from * from;
2129
+ return Math.sqrt(Math.max(0, v * (to * to - fromExpo) + fromExpo));
2130
+ };
2131
+ const colorTypes = [styleValueTypes.hex, styleValueTypes.rgba, styleValueTypes.hsla];
2132
+ const getColorType = (v) => colorTypes.find((type) => type.test(v));
2133
+ function asRGBA(color) {
2134
+ const type = getColorType(color);
2135
+ heyListen.invariant(Boolean(type), `'${color}' is not an animatable color. Use the equivalent color code instead.`);
2136
+ let model = type.parse(color);
2137
+ if (type === styleValueTypes.hsla) {
2138
+ model = hslaToRgba(model);
2139
+ }
2140
+ return model;
2141
+ }
2142
+ const mixColor = (from, to) => {
2143
+ const fromRGBA = asRGBA(from);
2144
+ const toRGBA = asRGBA(to);
2145
+ const blended = { ...fromRGBA };
2146
+ return (v) => {
2147
+ blended.red = mixLinearColor(fromRGBA.red, toRGBA.red, v);
2148
+ blended.green = mixLinearColor(fromRGBA.green, toRGBA.green, v);
2149
+ blended.blue = mixLinearColor(fromRGBA.blue, toRGBA.blue, v);
2150
+ blended.alpha = mix(fromRGBA.alpha, toRGBA.alpha, v);
2151
+ return styleValueTypes.rgba.transform(blended);
2152
+ };
2153
+ };
2154
+
2155
+ function getMixer$1(origin, target) {
2156
+ if (typeof origin === "number") {
2157
+ return (v) => mix(origin, target, v);
2158
+ }
2159
+ else if (styleValueTypes.color.test(origin)) {
2160
+ return mixColor(origin, target);
2161
+ }
2162
+ else {
2163
+ return mixComplex(origin, target);
2164
+ }
2165
+ }
2166
+ const mixArray = (from, to) => {
2167
+ const output = [...from];
2168
+ const numValues = output.length;
2169
+ const blendValue = from.map((fromThis, i) => getMixer$1(fromThis, to[i]));
2170
+ return (v) => {
2171
+ for (let i = 0; i < numValues; i++) {
2172
+ output[i] = blendValue[i](v);
2173
+ }
2174
+ return output;
2175
+ };
2176
+ };
2177
+ const mixObject = (origin, target) => {
2178
+ const output = { ...origin, ...target };
2179
+ const blendValue = {};
2180
+ for (const key in output) {
2181
+ if (origin[key] !== undefined && target[key] !== undefined) {
2182
+ blendValue[key] = getMixer$1(origin[key], target[key]);
2183
+ }
2184
+ }
2185
+ return (v) => {
2186
+ for (const key in blendValue) {
2187
+ output[key] = blendValue[key](v);
2188
+ }
2189
+ return output;
2190
+ };
2191
+ };
2192
+ /**
2193
+ * TODO: Combine with function within complex when style-value-types moved inside Framer Motion
2194
+ */
2195
+ function analyse(value) {
2196
+ const parsed = styleValueTypes.complex.parse(value);
2197
+ const numValues = parsed.length;
2198
+ let numNumbers = 0;
2199
+ let numColors = 0;
2200
+ for (let i = 0; i < numValues; i++) {
2201
+ // Parsed complex values return with colors first, so if we've seen any number
2202
+ // we're already past that part of the array and don't need to continue running typeof
2203
+ if (numNumbers || typeof parsed[i] === "number") {
2204
+ numNumbers++;
2205
+ }
2206
+ else {
2207
+ numColors++;
2208
+ }
2209
+ }
2210
+ return { parsed, numNumbers, numColors };
2211
+ }
2212
+ const mixComplex = (origin, target) => {
2213
+ const template = styleValueTypes.complex.createTransformer(target);
2214
+ const originStats = analyse(origin);
2215
+ const targetStats = analyse(target);
2216
+ const canInterpolate = originStats.numColors === targetStats.numColors &&
2217
+ originStats.numNumbers >= targetStats.numNumbers;
2218
+ if (canInterpolate) {
2219
+ return pipe(mixArray(originStats.parsed, targetStats.parsed), template);
2220
+ }
2221
+ else {
2222
+ heyListen.warning(true, `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`);
2223
+ return (p) => `${p > 0 ? target : origin}`;
2224
+ }
2225
+ };
2226
+
2227
+ /*
2228
+ Progress within given range
2229
+
2230
+ Given a lower limit and an upper limit, we return the progress
2231
+ (expressed as a number 0-1) represented by the given value, and
2232
+ limit that progress to within 0-1.
2233
+
2234
+ @param [number]: Lower limit
2235
+ @param [number]: Upper limit
2236
+ @param [number]: Value to find progress within given range
2237
+ @return [number]: Progress of value within range as expressed 0-1
2238
+ */
2239
+ const progress = (from, to, value) => {
2240
+ const toFromDifference = to - from;
2241
+ return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
2242
+ };
2243
+
2244
+ const mixNumber = (from, to) => (p) => mix(from, to, p);
2245
+ function detectMixerFactory(v) {
2246
+ if (typeof v === "number") {
2247
+ return mixNumber;
2248
+ }
2249
+ else if (typeof v === "string") {
2250
+ if (styleValueTypes.color.test(v)) {
2251
+ return mixColor;
2252
+ }
2253
+ else {
2254
+ return mixComplex;
2255
+ }
2256
+ }
2257
+ else if (Array.isArray(v)) {
2258
+ return mixArray;
2259
+ }
2260
+ else if (typeof v === "object") {
2261
+ return mixObject;
2262
+ }
2263
+ return mixNumber;
2264
+ }
2265
+ function createMixers(output, ease, customMixer) {
2266
+ const mixers = [];
2267
+ const mixerFactory = customMixer || detectMixerFactory(output[0]);
2268
+ const numMixers = output.length - 1;
2269
+ for (let i = 0; i < numMixers; i++) {
2270
+ let mixer = mixerFactory(output[i], output[i + 1]);
2271
+ if (ease) {
2272
+ const easingFunction = Array.isArray(ease) ? ease[i] : ease;
2273
+ mixer = pipe(easingFunction, mixer);
2274
+ }
2275
+ mixers.push(mixer);
2276
+ }
2277
+ return mixers;
2278
+ }
2279
+ /**
2280
+ * Create a function that maps from a numerical input array to a generic output array.
2281
+ *
2282
+ * Accepts:
2283
+ * - Numbers
2284
+ * - Colors (hex, hsl, hsla, rgb, rgba)
2285
+ * - Complex (combinations of one or more numbers or strings)
2286
+ *
2287
+ * ```jsx
2288
+ * const mixColor = interpolate([0, 1], ['#fff', '#000'])
2289
+ *
2290
+ * mixColor(0.5) // 'rgba(128, 128, 128, 1)'
2291
+ * ```
2292
+ *
2293
+ * TODO Revist this approach once we've moved to data models for values,
2294
+ * probably not needed to pregenerate mixer functions.
2295
+ *
2296
+ * @public
2297
+ */
2298
+ function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {}) {
2299
+ const inputLength = input.length;
2300
+ heyListen.invariant(inputLength === output.length, "Both input and output ranges must be the same length");
2301
+ heyListen.invariant(!ease || !Array.isArray(ease) || ease.length === inputLength - 1, "Array of easing functions must be of length `input.length - 1`, as it applies to the transitions **between** the defined values.");
2302
+ // If input runs highest -> lowest, reverse both arrays
2303
+ if (input[0] > input[inputLength - 1]) {
2304
+ input = [...input].reverse();
2305
+ output = [...output].reverse();
2306
+ }
2307
+ const mixers = createMixers(output, ease, mixer);
2308
+ const numMixers = mixers.length;
2309
+ const interpolator = (v) => {
2310
+ let i = 0;
2311
+ if (numMixers > 1) {
2312
+ for (; i < input.length - 2; i++) {
2313
+ if (v < input[i + 1])
2314
+ break;
2315
+ }
2316
+ }
2317
+ const progressInRange = progress(input[i], input[i + 1], v);
2318
+ return mixers[i](progressInRange);
2319
+ };
2320
+ return isClamp
2321
+ ? (v) => interpolator(clamp(input[0], input[inputLength - 1], v))
2322
+ : interpolator;
2323
+ }
2324
+
2325
+ function defaultEasing(values, easing) {
2326
+ return values.map(() => easing || easeInOut).splice(0, values.length - 1);
2327
+ }
2328
+ function defaultOffset(values) {
2329
+ const numValues = values.length;
2330
+ return values.map((_value, i) => i !== 0 ? i / (numValues - 1) : 0);
2331
+ }
2332
+ function convertOffsetToTimes(offset, duration) {
2333
+ return offset.map((o) => o * duration);
2334
+ }
2335
+ function keyframes({ from = 0, to = 1, ease, offset, duration = 300, }) {
2336
+ /**
2337
+ * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
2338
+ * to reduce GC during animation.
2339
+ */
2340
+ const state = { done: false, value: from };
2341
+ /**
2342
+ * Convert values to an array if they've been given as from/to options
2343
+ */
2344
+ const values = Array.isArray(to) ? to : [from, to];
2345
+ /**
2346
+ * Create a times array based on the provided 0-1 offsets
2347
+ */
2348
+ const times = convertOffsetToTimes(
2349
+ // Only use the provided offsets if they're the correct length
2350
+ // TODO Maybe we should warn here if there's a length mismatch
2351
+ offset && offset.length === values.length
2352
+ ? offset
2353
+ : defaultOffset(values), duration);
2354
+ function createInterpolator() {
2355
+ return interpolate(times, values, {
2356
+ ease: Array.isArray(ease) ? ease : defaultEasing(values, ease),
2357
+ });
2358
+ }
2359
+ let interpolator = createInterpolator();
2360
+ return {
2361
+ next: (t) => {
2362
+ state.value = interpolator(t);
2363
+ state.done = t >= duration;
2364
+ return state;
2365
+ },
2366
+ flipTarget: () => {
2367
+ values.reverse();
2368
+ interpolator = createInterpolator();
2369
+ },
2370
+ };
2371
+ }
2372
+
2373
+ const safeMin = 0.001;
2374
+ const minDuration = 0.01;
2375
+ const maxDuration = 10.0;
2376
+ const minDamping = 0.05;
2377
+ const maxDamping = 1;
2378
+ function findSpring({ duration = 800, bounce = 0.25, velocity = 0, mass = 1, }) {
2379
+ let envelope;
2380
+ let derivative;
2381
+ heyListen.warning(duration <= maxDuration * 1000, "Spring duration must be 10 seconds or less");
2382
+ let dampingRatio = 1 - bounce;
2383
+ /**
2384
+ * Restrict dampingRatio and duration to within acceptable ranges.
2385
+ */
2386
+ dampingRatio = clamp(minDamping, maxDamping, dampingRatio);
2387
+ duration = clamp(minDuration, maxDuration, duration / 1000);
2388
+ if (dampingRatio < 1) {
2389
+ /**
2390
+ * Underdamped spring
2391
+ */
2392
+ envelope = (undampedFreq) => {
2393
+ const exponentialDecay = undampedFreq * dampingRatio;
2394
+ const delta = exponentialDecay * duration;
2395
+ const a = exponentialDecay - velocity;
2396
+ const b = calcAngularFreq(undampedFreq, dampingRatio);
2397
+ const c = Math.exp(-delta);
2398
+ return safeMin - (a / b) * c;
2399
+ };
2400
+ derivative = (undampedFreq) => {
2401
+ const exponentialDecay = undampedFreq * dampingRatio;
2402
+ const delta = exponentialDecay * duration;
2403
+ const d = delta * velocity + velocity;
2404
+ const e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq, 2) * duration;
2405
+ const f = Math.exp(-delta);
2406
+ const g = calcAngularFreq(Math.pow(undampedFreq, 2), dampingRatio);
2407
+ const factor = -envelope(undampedFreq) + safeMin > 0 ? -1 : 1;
2408
+ return (factor * ((d - e) * f)) / g;
2409
+ };
2410
+ }
2411
+ else {
2412
+ /**
2413
+ * Critically-damped spring
2414
+ */
2415
+ envelope = (undampedFreq) => {
2416
+ const a = Math.exp(-undampedFreq * duration);
2417
+ const b = (undampedFreq - velocity) * duration + 1;
2418
+ return -safeMin + a * b;
2419
+ };
2420
+ derivative = (undampedFreq) => {
2421
+ const a = Math.exp(-undampedFreq * duration);
2422
+ const b = (velocity - undampedFreq) * (duration * duration);
2423
+ return a * b;
2424
+ };
2425
+ }
2426
+ const initialGuess = 5 / duration;
2427
+ const undampedFreq = approximateRoot(envelope, derivative, initialGuess);
2428
+ duration = duration * 1000;
2429
+ if (isNaN(undampedFreq)) {
2430
+ return {
2431
+ stiffness: 100,
2432
+ damping: 10,
2433
+ duration,
2434
+ };
2435
+ }
2436
+ else {
2437
+ const stiffness = Math.pow(undampedFreq, 2) * mass;
2438
+ return {
2439
+ stiffness,
2440
+ damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),
2441
+ duration,
2442
+ };
2443
+ }
2444
+ }
2445
+ const rootIterations = 12;
2446
+ function approximateRoot(envelope, derivative, initialGuess) {
2447
+ let result = initialGuess;
2448
+ for (let i = 1; i < rootIterations; i++) {
2449
+ result = result - envelope(result) / derivative(result);
2450
+ }
2451
+ return result;
2452
+ }
2453
+ function calcAngularFreq(undampedFreq, dampingRatio) {
2454
+ return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
2455
+ }
2456
+
2457
+ const durationKeys = ["duration", "bounce"];
2458
+ const physicsKeys = ["stiffness", "damping", "mass"];
2459
+ function isSpringType(options, keys) {
2460
+ return keys.some((key) => options[key] !== undefined);
2461
+ }
2462
+ function getSpringOptions(options) {
2463
+ let springOptions = {
2464
+ velocity: 0.0,
2465
+ stiffness: 100,
2466
+ damping: 10,
2467
+ mass: 1.0,
2468
+ isResolvedFromDuration: false,
2469
+ ...options,
2470
+ };
2471
+ // stiffness/damping/mass overrides duration/bounce
2472
+ if (!isSpringType(options, physicsKeys) &&
2473
+ isSpringType(options, durationKeys)) {
2474
+ const derived = findSpring(options);
2475
+ springOptions = {
2476
+ ...springOptions,
2477
+ ...derived,
2478
+ velocity: 0.0,
2479
+ mass: 1.0,
2480
+ };
2481
+ springOptions.isResolvedFromDuration = true;
2482
+ }
2483
+ return springOptions;
2484
+ }
2485
+ /**
2486
+ * This is based on the spring implementation of Wobble https://github.com/skevy/wobble
2487
+ */
2488
+ function spring({ from = 0.0, to = 1.0, restSpeed = 2, restDelta = 0.01, ...options }) {
2489
+ /**
2490
+ * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
2491
+ * to reduce GC during animation.
2492
+ */
2493
+ const state = { done: false, value: from };
2494
+ let { stiffness, damping, mass, velocity, duration, isResolvedFromDuration, } = getSpringOptions(options);
2495
+ let resolveSpring = zero;
2496
+ let resolveVelocity = zero;
2497
+ function createSpring() {
2498
+ const initialVelocity = velocity ? -(velocity / 1000) : 0.0;
2499
+ const initialDelta = to - from;
2500
+ const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass));
2501
+ const undampedAngularFreq = Math.sqrt(stiffness / mass) / 1000;
2502
+ /**
2503
+ * If we're working within what looks like a 0-1 range, change the default restDelta
2504
+ * to 0.01
2505
+ */
2506
+ if (restDelta === undefined) {
2507
+ restDelta = Math.min(Math.abs(to - from) / 100, 0.4);
2508
+ }
2509
+ if (dampingRatio < 1) {
2510
+ const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
2511
+ // Underdamped spring
2512
+ resolveSpring = (t) => {
2513
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
2514
+ return (to -
2515
+ envelope *
2516
+ (((initialVelocity +
2517
+ dampingRatio * undampedAngularFreq * initialDelta) /
2518
+ angularFreq) *
2519
+ Math.sin(angularFreq * t) +
2520
+ initialDelta * Math.cos(angularFreq * t)));
2521
+ };
2522
+ resolveVelocity = (t) => {
2523
+ // TODO Resolve these calculations with the above
2524
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
2525
+ return (dampingRatio *
2526
+ undampedAngularFreq *
2527
+ envelope *
2528
+ ((Math.sin(angularFreq * t) *
2529
+ (initialVelocity +
2530
+ dampingRatio *
2531
+ undampedAngularFreq *
2532
+ initialDelta)) /
2533
+ angularFreq +
2534
+ initialDelta * Math.cos(angularFreq * t)) -
2535
+ envelope *
2536
+ (Math.cos(angularFreq * t) *
2537
+ (initialVelocity +
2538
+ dampingRatio *
2539
+ undampedAngularFreq *
2540
+ initialDelta) -
2541
+ angularFreq *
2542
+ initialDelta *
2543
+ Math.sin(angularFreq * t)));
2544
+ };
2545
+ }
2546
+ else if (dampingRatio === 1) {
2547
+ // Critically damped spring
2548
+ resolveSpring = (t) => to -
2549
+ Math.exp(-undampedAngularFreq * t) *
2550
+ (initialDelta +
2551
+ (initialVelocity + undampedAngularFreq * initialDelta) *
2552
+ t);
2553
+ }
2554
+ else {
2555
+ // Overdamped spring
2556
+ const dampedAngularFreq = undampedAngularFreq * Math.sqrt(dampingRatio * dampingRatio - 1);
2557
+ resolveSpring = (t) => {
2558
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
2559
+ // When performing sinh or cosh values can hit Infinity so we cap them here
2560
+ const freqForT = Math.min(dampedAngularFreq * t, 300);
2561
+ return (to -
2562
+ (envelope *
2563
+ ((initialVelocity +
2564
+ dampingRatio * undampedAngularFreq * initialDelta) *
2565
+ Math.sinh(freqForT) +
2566
+ dampedAngularFreq *
2567
+ initialDelta *
2568
+ Math.cosh(freqForT))) /
2569
+ dampedAngularFreq);
2570
+ };
2571
+ }
2572
+ }
2573
+ createSpring();
2574
+ return {
2575
+ next: (t) => {
2576
+ const current = resolveSpring(t);
2577
+ if (!isResolvedFromDuration) {
2578
+ const currentVelocity = resolveVelocity(t) * 1000;
2579
+ const isBelowVelocityThreshold = Math.abs(currentVelocity) <= restSpeed;
2580
+ const isBelowDisplacementThreshold = Math.abs(to - current) <= restDelta;
2581
+ state.done =
2582
+ isBelowVelocityThreshold && isBelowDisplacementThreshold;
2583
+ }
2584
+ else {
2585
+ state.done = t >= duration;
2586
+ }
2587
+ state.value = state.done ? to : current;
2588
+ return state;
2589
+ },
2590
+ flipTarget: () => {
2591
+ velocity = -velocity;
2592
+ [from, to] = [to, from];
2593
+ createSpring();
2594
+ },
2595
+ };
2596
+ }
2597
+ spring.needsInterpolation = (a, b) => typeof a === "string" || typeof b === "string";
2598
+ const zero = (_t) => 0;
2599
+
2600
+ function decay({ velocity = 0, from = 0, power = 0.8, timeConstant = 350, restDelta = 0.5, modifyTarget, }) {
2601
+ /**
2602
+ * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
2603
+ * to reduce GC during animation.
2604
+ */
2605
+ const state = { done: false, value: from };
2606
+ let amplitude = power * velocity;
2607
+ const ideal = from + amplitude;
2608
+ const target = modifyTarget === undefined ? ideal : modifyTarget(ideal);
2609
+ /**
2610
+ * If the target has changed we need to re-calculate the amplitude, otherwise
2611
+ * the animation will start from the wrong position.
2612
+ */
2613
+ if (target !== ideal)
2614
+ amplitude = target - from;
2615
+ return {
2616
+ next: (t) => {
2617
+ const delta = -amplitude * Math.exp(-t / timeConstant);
2618
+ state.done = !(delta > restDelta || delta < -restDelta);
2619
+ state.value = state.done ? target : target + delta;
2620
+ return state;
2621
+ },
2622
+ flipTarget: () => { },
2623
+ };
2624
+ }
2625
+
2626
+ const types = { decay, keyframes, spring };
2627
+ function loopElapsed(elapsed, duration, delay = 0) {
2628
+ return elapsed - duration - delay;
2629
+ }
2630
+ function reverseElapsed(elapsed, duration = 0, delay = 0, isForwardPlayback = true) {
2631
+ return isForwardPlayback
2632
+ ? loopElapsed(duration + -elapsed, duration, delay)
2633
+ : duration - (elapsed - duration) + delay;
2634
+ }
2635
+ function hasRepeatDelayElapsed(elapsed, duration, delay, isForwardPlayback) {
2636
+ return isForwardPlayback ? elapsed >= duration + delay : elapsed <= -delay;
2637
+ }
2638
+ const framesync = (update) => {
2639
+ const passTimestamp = ({ delta }) => update(delta);
2640
+ return {
2641
+ start: () => sync__default["default"].update(passTimestamp, true),
2642
+ stop: () => sync.cancelSync.update(passTimestamp),
2643
+ };
2644
+ };
2645
+ function animate$1({ from, autoplay = true, driver = framesync, elapsed = 0, repeat: repeatMax = 0, repeatType = "loop", repeatDelay = 0, onPlay, onStop, onComplete, onRepeat, onUpdate, type = "keyframes", ...options }) {
2646
+ var _a, _b;
2647
+ let { to } = options;
2648
+ let driverControls;
2649
+ let repeatCount = 0;
2650
+ let computedDuration = options
2651
+ .duration;
2652
+ let latest;
2653
+ let isComplete = false;
2654
+ let isForwardPlayback = true;
2655
+ let interpolateFromNumber;
2656
+ const animator = types[Array.isArray(to) ? "keyframes" : type];
2657
+ if ((_b = (_a = animator).needsInterpolation) === null || _b === void 0 ? void 0 : _b.call(_a, from, to)) {
2658
+ interpolateFromNumber = interpolate([0, 100], [from, to], {
2659
+ clamp: false,
2660
+ });
2661
+ from = 0;
2662
+ to = 100;
2663
+ }
2664
+ const animation = animator({ ...options, from, to });
2665
+ function repeat() {
2666
+ repeatCount++;
2667
+ if (repeatType === "reverse") {
2668
+ isForwardPlayback = repeatCount % 2 === 0;
2669
+ elapsed = reverseElapsed(elapsed, computedDuration, repeatDelay, isForwardPlayback);
2670
+ }
2671
+ else {
2672
+ elapsed = loopElapsed(elapsed, computedDuration, repeatDelay);
2673
+ if (repeatType === "mirror")
2674
+ animation.flipTarget();
2675
+ }
2676
+ isComplete = false;
2677
+ onRepeat && onRepeat();
2678
+ }
2679
+ function complete() {
2680
+ driverControls.stop();
2681
+ onComplete && onComplete();
2682
+ }
2683
+ function update(delta) {
2684
+ if (!isForwardPlayback)
2685
+ delta = -delta;
2686
+ elapsed += delta;
2687
+ if (!isComplete) {
2688
+ const state = animation.next(Math.max(0, elapsed));
2689
+ latest = state.value;
2690
+ if (interpolateFromNumber)
2691
+ latest = interpolateFromNumber(latest);
2692
+ isComplete = isForwardPlayback ? state.done : elapsed <= 0;
2693
+ }
2694
+ onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(latest);
2695
+ if (isComplete) {
2696
+ if (repeatCount === 0)
2697
+ computedDuration !== null && computedDuration !== void 0 ? computedDuration : (computedDuration = elapsed);
2698
+ if (repeatCount < repeatMax) {
2699
+ hasRepeatDelayElapsed(elapsed, computedDuration, repeatDelay, isForwardPlayback) && repeat();
2700
+ }
2701
+ else {
2702
+ complete();
2703
+ }
2704
+ }
2705
+ }
2706
+ function play() {
2707
+ onPlay === null || onPlay === void 0 ? void 0 : onPlay();
2708
+ driverControls = driver(update);
2709
+ driverControls.start();
2710
+ }
2711
+ autoplay && play();
2712
+ return {
2713
+ stop: () => {
2714
+ onStop === null || onStop === void 0 ? void 0 : onStop();
2715
+ driverControls.stop();
2716
+ },
2717
+ };
2718
+ }
2719
+
2720
+ /*
2721
+ Convert velocity into velocity per second
2722
+
2723
+ @param [number]: Unit per frame
2724
+ @param [number]: Frame duration in ms
2725
+ */
2726
+ function velocityPerSecond(velocity, frameDuration) {
2727
+ return frameDuration ? velocity * (1000 / frameDuration) : 0;
2728
+ }
2729
+
2730
+ function inertia({ from = 0, velocity = 0, min, max, power = 0.8, timeConstant = 750, bounceStiffness = 500, bounceDamping = 10, restDelta = 1, modifyTarget, driver, onUpdate, onComplete, onStop, }) {
2731
+ let currentAnimation;
2732
+ function isOutOfBounds(v) {
2733
+ return (min !== undefined && v < min) || (max !== undefined && v > max);
2734
+ }
2735
+ function boundaryNearest(v) {
2736
+ if (min === undefined)
2737
+ return max;
2738
+ if (max === undefined)
2739
+ return min;
2740
+ return Math.abs(min - v) < Math.abs(max - v) ? min : max;
2741
+ }
2742
+ function startAnimation(options) {
2743
+ currentAnimation === null || currentAnimation === void 0 ? void 0 : currentAnimation.stop();
2744
+ currentAnimation = animate$1({
2745
+ ...options,
2746
+ driver,
2747
+ onUpdate: (v) => {
2748
+ var _a;
2749
+ onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(v);
2750
+ (_a = options.onUpdate) === null || _a === void 0 ? void 0 : _a.call(options, v);
2751
+ },
2752
+ onComplete,
2753
+ onStop,
2754
+ });
2755
+ }
2756
+ function startSpring(options) {
2757
+ startAnimation({
2758
+ type: "spring",
2759
+ stiffness: bounceStiffness,
2760
+ damping: bounceDamping,
2761
+ restDelta,
2762
+ ...options,
2763
+ });
2764
+ }
2765
+ if (isOutOfBounds(from)) {
2766
+ // Start the animation with spring if outside the defined boundaries
2767
+ startSpring({ from, velocity, to: boundaryNearest(from) });
2768
+ }
2769
+ else {
2770
+ /**
2771
+ * Or if the value is out of bounds, simulate the inertia movement
2772
+ * with the decay animation.
2773
+ *
2774
+ * Pre-calculate the target so we can detect if it's out-of-bounds.
2775
+ * If it is, we want to check per frame when to switch to a spring
2776
+ * animation
2777
+ */
2778
+ let target = power * velocity + from;
2779
+ if (typeof modifyTarget !== "undefined")
2780
+ target = modifyTarget(target);
2781
+ const boundary = boundaryNearest(target);
2782
+ const heading = boundary === min ? -1 : 1;
2783
+ let prev;
2784
+ let current;
2785
+ const checkBoundary = (v) => {
2786
+ prev = current;
2787
+ current = v;
2788
+ velocity = velocityPerSecond(v - prev, sync.getFrameData().delta);
2789
+ if ((heading === 1 && v > boundary) ||
2790
+ (heading === -1 && v < boundary)) {
2791
+ startSpring({ from: v, to: boundary, velocity });
2792
+ }
2793
+ };
2794
+ startAnimation({
2795
+ type: "decay",
2796
+ from,
2797
+ velocity,
2798
+ timeConstant,
2799
+ power,
2800
+ restDelta,
2801
+ modifyTarget,
2802
+ onUpdate: isOutOfBounds(target) ? checkBoundary : undefined,
2803
+ });
2804
+ }
2805
+ return {
2806
+ stop: () => currentAnimation === null || currentAnimation === void 0 ? void 0 : currentAnimation.stop(),
2807
+ };
2808
+ }
2809
+
1973
2810
  /**
1974
2811
  * Decide whether a transition is defined on a given Transition.
1975
2812
  * This filters out orchestration options and returns true
@@ -2100,8 +2937,8 @@ function getAnimation(key, value, target, transition, onComplete) {
2100
2937
  };
2101
2938
  return valueTransition.type === "inertia" ||
2102
2939
  valueTransition.type === "decay"
2103
- ? popmotion.inertia({ ...options, ...valueTransition })
2104
- : popmotion.animate({
2940
+ ? inertia({ ...options, ...valueTransition })
2941
+ : animate$1({
2105
2942
  ...getPopmotionAnimationOptions(valueTransition, options, key),
2106
2943
  onUpdate: (v) => {
2107
2944
  options.onUpdate(v);
@@ -2257,7 +3094,7 @@ class MotionValue {
2257
3094
  * This will be replaced by the build step with the latest version number.
2258
3095
  * When MotionValues are provided to motion components, warn if versions are mixed.
2259
3096
  */
2260
- this.version = "7.6.16";
3097
+ this.version = "7.6.18";
2261
3098
  /**
2262
3099
  * Duration, in milliseconds, since last updating frame.
2263
3100
  *
@@ -2472,7 +3309,7 @@ class MotionValue {
2472
3309
  // This could be isFloat(this.prev) && isFloat(this.current), but that would be wasteful
2473
3310
  return this.canTrackVelocity
2474
3311
  ? // These casts could be avoided if parseFloat would be typed better
2475
- popmotion.velocityPerSecond(parseFloat(this.current) -
3312
+ velocityPerSecond(parseFloat(this.current) -
2476
3313
  parseFloat(this.prev), this.timeDelta)
2477
3314
  : 0;
2478
3315
  }
@@ -3186,6 +4023,14 @@ const animations = {
3186
4023
  }),
3187
4024
  };
3188
4025
 
4026
+ const distance = (a, b) => Math.abs(a - b);
4027
+ function distance2D(a, b) {
4028
+ // Multi-dimensional
4029
+ const xDelta = distance(a.x, b.x);
4030
+ const yDelta = distance(a.y, b.y);
4031
+ return Math.sqrt(xDelta ** 2 + yDelta ** 2);
4032
+ }
4033
+
3189
4034
  /**
3190
4035
  * @internal
3191
4036
  */
@@ -3215,7 +4060,7 @@ class PanSession {
3215
4060
  // Only start panning if the offset is larger than 3 pixels. If we make it
3216
4061
  // any larger than this we'll want to reset the pointer history
3217
4062
  // on the first update to avoid visual snapping to the cursoe.
3218
- const isDistancePastThreshold = popmotion.distance(info.offset, { x: 0, y: 0 }) >= 3;
4063
+ const isDistancePastThreshold = distance2D(info.offset, { x: 0, y: 0 }) >= 3;
3219
4064
  if (!isPanStarted && !isDistancePastThreshold)
3220
4065
  return;
3221
4066
  const { point } = info;
@@ -3261,7 +4106,7 @@ class PanSession {
3261
4106
  const { onSessionStart } = handlers;
3262
4107
  onSessionStart &&
3263
4108
  onSessionStart(event, getPanInfo(initialInfo, this.history));
3264
- this.removeListeners = popmotion.pipe(addPointerEvent(window, "pointermove", this.handlePointerMove), addPointerEvent(window, "pointerup", this.handlePointerUp), addPointerEvent(window, "pointercancel", this.handlePointerUp));
4109
+ this.removeListeners = pipe(addPointerEvent(window, "pointermove", this.handlePointerMove), addPointerEvent(window, "pointerup", this.handlePointerUp), addPointerEvent(window, "pointercancel", this.handlePointerUp));
3265
4110
  }
3266
4111
  updateHandlers(handlers) {
3267
4112
  this.handlers = handlers;
@@ -3334,12 +4179,12 @@ function isNear(value, target = 0, maxDistance = 0.01) {
3334
4179
  }
3335
4180
  function calcAxisDelta(delta, source, target, origin = 0.5) {
3336
4181
  delta.origin = origin;
3337
- delta.originPoint = popmotion.mix(source.min, source.max, delta.origin);
4182
+ delta.originPoint = mix(source.min, source.max, delta.origin);
3338
4183
  delta.scale = calcLength(target) / calcLength(source);
3339
4184
  if (isNear(delta.scale, 1, 0.0001) || isNaN(delta.scale))
3340
4185
  delta.scale = 1;
3341
4186
  delta.translate =
3342
- popmotion.mix(target.min, target.max, delta.origin) - delta.originPoint;
4187
+ mix(target.min, target.max, delta.origin) - delta.originPoint;
3343
4188
  if (isNear(delta.translate) || isNaN(delta.translate))
3344
4189
  delta.translate = 0;
3345
4190
  }
@@ -3372,11 +4217,11 @@ function calcRelativePosition(target, layout, parent) {
3372
4217
  function applyConstraints(point, { min, max }, elastic) {
3373
4218
  if (min !== undefined && point < min) {
3374
4219
  // If we have a min point defined, and this is outside of that, constrain
3375
- point = elastic ? popmotion.mix(min, point, elastic.min) : Math.max(point, min);
4220
+ point = elastic ? mix(min, point, elastic.min) : Math.max(point, min);
3376
4221
  }
3377
4222
  else if (max !== undefined && point > max) {
3378
4223
  // If we have a max point defined, and this is outside of that, constrain
3379
- point = elastic ? popmotion.mix(max, point, elastic.max) : Math.min(point, max);
4224
+ point = elastic ? mix(max, point, elastic.max) : Math.min(point, max);
3380
4225
  }
3381
4226
  return point;
3382
4227
  }
@@ -3435,12 +4280,12 @@ function calcOrigin(source, target) {
3435
4280
  const sourceLength = calcLength(source);
3436
4281
  const targetLength = calcLength(target);
3437
4282
  if (targetLength > sourceLength) {
3438
- origin = popmotion.progress(target.min, target.max - sourceLength, source.min);
4283
+ origin = progress(target.min, target.max - sourceLength, source.min);
3439
4284
  }
3440
4285
  else if (sourceLength > targetLength) {
3441
- origin = popmotion.progress(source.min, source.max - targetLength, target.min);
4286
+ origin = progress(source.min, source.max - targetLength, target.min);
3442
4287
  }
3443
- return popmotion.clamp(0, 1, origin);
4288
+ return clamp(0, 1, origin);
3444
4289
  }
3445
4290
  /**
3446
4291
  * Rebase the calculated viewport constraints relative to the layout.min point.
@@ -3653,7 +4498,7 @@ function translateAxis(axis, distance) {
3653
4498
  */
3654
4499
  function transformAxis(axis, transforms, [key, scaleKey, originKey]) {
3655
4500
  const axisOrigin = transforms[originKey] !== undefined ? transforms[originKey] : 0.5;
3656
- const originPoint = popmotion.mix(axis.min, axis.max, axisOrigin);
4501
+ const originPoint = mix(axis.min, axis.max, axisOrigin);
3657
4502
  // Apply the axis delta to the final axis
3658
4503
  applyAxisDelta(axis, transforms[key], transforms[scaleKey], originPoint, transforms.scale);
3659
4504
  }
@@ -3968,7 +4813,7 @@ class VisualElementDragControls {
3968
4813
  const axisValue = this.getAxisMotionValue(axis);
3969
4814
  if (projection && projection.layout) {
3970
4815
  const { min, max } = projection.layout.layoutBox[axis];
3971
- axisValue.set(point[axis] - popmotion.mix(min, max, 0.5));
4816
+ axisValue.set(point[axis] - mix(min, max, 0.5));
3972
4817
  }
3973
4818
  });
3974
4819
  }
@@ -4024,7 +4869,7 @@ class VisualElementDragControls {
4024
4869
  */
4025
4870
  const axisValue = this.getAxisMotionValue(axis);
4026
4871
  const { min, max } = this.constraints[axis];
4027
- axisValue.set(popmotion.mix(min, max, boxProgress[axis]));
4872
+ axisValue.set(mix(min, max, boxProgress[axis]));
4028
4873
  });
4029
4874
  }
4030
4875
  addListeners() {
@@ -4534,7 +5379,7 @@ function updateMotionValuesFromProps(element, next, prev) {
4534
5379
  * and warn against mismatches.
4535
5380
  */
4536
5381
  if (process.env.NODE_ENV === "development") {
4537
- warnOnce(nextValue.version === "7.6.16", `Attempting to mix Framer Motion versions ${nextValue.version} with 7.6.16 may not work as expected.`);
5382
+ warnOnce(nextValue.version === "7.6.18", `Attempting to mix Framer Motion versions ${nextValue.version} with 7.6.18 may not work as expected.`);
4538
5383
  }
4539
5384
  }
4540
5385
  else if (isMotionValue(prevValue)) {
@@ -5202,7 +6047,7 @@ const correctBoxShadow = {
5202
6047
  * We could potentially improve the outcome of this by incorporating the ratio between
5203
6048
  * the two scales.
5204
6049
  */
5205
- const averageScale = popmotion.mix(xScale, yScale, 0.5);
6050
+ const averageScale = mix(xScale, yScale, 0.5);
5206
6051
  // Blur
5207
6052
  if (typeof shadow[2 + offset] === "number")
5208
6053
  shadow[2 + offset] /= averageScale;
@@ -5387,14 +6232,14 @@ const isPx = (value) => typeof value === "number" || styleValueTypes.px.test(val
5387
6232
  function mixValues(target, follow, lead, progress, shouldCrossfadeOpacity, isOnlyMember) {
5388
6233
  var _a, _b, _c, _d;
5389
6234
  if (shouldCrossfadeOpacity) {
5390
- target.opacity = popmotion.mix(0,
6235
+ target.opacity = mix(0,
5391
6236
  // (follow?.opacity as number) ?? 0,
5392
6237
  // TODO Reinstate this if only child
5393
6238
  (_a = lead.opacity) !== null && _a !== void 0 ? _a : 1, easeCrossfadeIn(progress));
5394
- target.opacityExit = popmotion.mix((_b = follow.opacity) !== null && _b !== void 0 ? _b : 1, 0, easeCrossfadeOut(progress));
6239
+ target.opacityExit = mix((_b = follow.opacity) !== null && _b !== void 0 ? _b : 1, 0, easeCrossfadeOut(progress));
5395
6240
  }
5396
6241
  else if (isOnlyMember) {
5397
- target.opacity = popmotion.mix((_c = follow.opacity) !== null && _c !== void 0 ? _c : 1, (_d = lead.opacity) !== null && _d !== void 0 ? _d : 1, progress);
6242
+ target.opacity = mix((_c = follow.opacity) !== null && _c !== void 0 ? _c : 1, (_d = lead.opacity) !== null && _d !== void 0 ? _d : 1, progress);
5398
6243
  }
5399
6244
  /**
5400
6245
  * Mix border radius
@@ -5411,7 +6256,7 @@ function mixValues(target, follow, lead, progress, shouldCrossfadeOpacity, isOnl
5411
6256
  leadRadius === 0 ||
5412
6257
  isPx(followRadius) === isPx(leadRadius);
5413
6258
  if (canMix) {
5414
- target[borderLabel] = Math.max(popmotion.mix(asNumber(followRadius), asNumber(leadRadius), progress), 0);
6259
+ target[borderLabel] = Math.max(mix(asNumber(followRadius), asNumber(leadRadius), progress), 0);
5415
6260
  if (styleValueTypes.percent.test(leadRadius) || styleValueTypes.percent.test(followRadius)) {
5416
6261
  target[borderLabel] += "%";
5417
6262
  }
@@ -5424,7 +6269,7 @@ function mixValues(target, follow, lead, progress, shouldCrossfadeOpacity, isOnl
5424
6269
  * Mix rotation
5425
6270
  */
5426
6271
  if (follow.rotate || lead.rotate) {
5427
- target.rotate = popmotion.mix(follow.rotate || 0, lead.rotate || 0, progress);
6272
+ target.rotate = mix(follow.rotate || 0, lead.rotate || 0, progress);
5428
6273
  }
5429
6274
  }
5430
6275
  function getRadius(values, radiusName) {
@@ -5454,8 +6299,8 @@ function getRadius(values, radiusName) {
5454
6299
  // latestLeadValues.backgroundColor as string
5455
6300
  // )(p)
5456
6301
  // }
5457
- const easeCrossfadeIn = compress(0, 0.5, popmotion.circOut);
5458
- const easeCrossfadeOut = compress(0.5, 0.95, popmotion.linear);
6302
+ const easeCrossfadeIn = compress(0, 0.5, circOut);
6303
+ const easeCrossfadeOut = compress(0.5, 0.95, noop);
5459
6304
  function compress(min, max, easing) {
5460
6305
  return (p) => {
5461
6306
  // Could replace ifs with clamp
@@ -5463,7 +6308,7 @@ function compress(min, max, easing) {
5463
6308
  return 0;
5464
6309
  if (p > max)
5465
6310
  return 1;
5466
- return easing(popmotion.progress(min, max, p));
6311
+ return easing(progress(min, max, p));
5467
6312
  };
5468
6313
  }
5469
6314
 
@@ -5503,12 +6348,12 @@ function removePointDelta(point, translate, scale, originPoint, boxScale) {
5503
6348
  function removeAxisDelta(axis, translate = 0, scale = 1, origin = 0.5, boxScale, originAxis = axis, sourceAxis = axis) {
5504
6349
  if (styleValueTypes.percent.test(translate)) {
5505
6350
  translate = parseFloat(translate);
5506
- const relativeProgress = popmotion.mix(sourceAxis.min, sourceAxis.max, translate / 100);
6351
+ const relativeProgress = mix(sourceAxis.min, sourceAxis.max, translate / 100);
5507
6352
  translate = relativeProgress - sourceAxis.min;
5508
6353
  }
5509
6354
  if (typeof translate !== "number")
5510
6355
  return;
5511
- let originPoint = popmotion.mix(originAxis.min, originAxis.max, origin);
6356
+ let originPoint = mix(originAxis.min, originAxis.max, origin);
5512
6357
  if (axis === originAxis)
5513
6358
  originPoint -= translate;
5514
6359
  axis.min = removePointDelta(axis.min, translate, scale, originPoint, boxScale);
@@ -6961,14 +7806,14 @@ function removeLeadSnapshots(stack) {
6961
7806
  stack.removeLeadSnapshot();
6962
7807
  }
6963
7808
  function mixAxisDelta(output, delta, p) {
6964
- output.translate = popmotion.mix(delta.translate, 0, p);
6965
- output.scale = popmotion.mix(delta.scale, 1, p);
7809
+ output.translate = mix(delta.translate, 0, p);
7810
+ output.scale = mix(delta.scale, 1, p);
6966
7811
  output.origin = delta.origin;
6967
7812
  output.originPoint = delta.originPoint;
6968
7813
  }
6969
7814
  function mixAxis(output, from, to, p) {
6970
- output.min = popmotion.mix(from.min, to.min, p);
6971
- output.max = popmotion.mix(from.max, to.max, p);
7815
+ output.min = mix(from.min, to.min, p);
7816
+ output.max = mix(from.max, to.max, p);
6972
7817
  }
6973
7818
  function mixBox(output, from, to, p) {
6974
7819
  mixAxis(output.x, from.x, to.x, p);
@@ -7542,7 +8387,7 @@ function checkReorder(order, value, offset, velocity) {
7542
8387
  return order;
7543
8388
  const item = order[index];
7544
8389
  const nextLayout = nextItem.layout;
7545
- const nextItemCenter = popmotion.mix(nextLayout.min, nextLayout.max, 0.5);
8390
+ const nextItemCenter = mix(nextLayout.min, nextLayout.max, 0.5);
7546
8391
  if ((nextOffset === 1 && item.layout.max + offset > nextItemCenter) ||
7547
8392
  (nextOffset === -1 && item.layout.min + offset < nextItemCenter)) {
7548
8393
  return moveItem(order, index, index + nextOffset);
@@ -7636,7 +8481,7 @@ function transform(...args) {
7636
8481
  const inputRange = args[1 + argOffset];
7637
8482
  const outputRange = args[2 + argOffset];
7638
8483
  const options = args[3 + argOffset];
7639
- const interpolator = popmotion.interpolate(inputRange, outputRange, {
8484
+ const interpolator = interpolate(inputRange, outputRange, {
7640
8485
  mixer: getMixer(outputRange[0]),
7641
8486
  ...options,
7642
8487
  });
@@ -7645,8 +8490,10 @@ function transform(...args) {
7645
8490
 
7646
8491
  function useOnChange(value, callback) {
7647
8492
  useIsomorphicLayoutEffect(() => {
7648
- if (isMotionValue(value))
8493
+ if (isMotionValue(value)) {
8494
+ callback(value.get());
7649
8495
  return value.onChange(callback);
8496
+ }
7650
8497
  }, [value, callback]);
7651
8498
  }
7652
8499
  function useMultiOnChange(values, handler, cleanup) {
@@ -7830,7 +8677,7 @@ function useSpring(source, config = {}) {
7830
8677
  if (activeSpringAnimation.current) {
7831
8678
  activeSpringAnimation.current.stop();
7832
8679
  }
7833
- activeSpringAnimation.current = popmotion.animate({
8680
+ activeSpringAnimation.current = animate$1({
7834
8681
  from: value.get(),
7835
8682
  to: v,
7836
8683
  velocity: value.getVelocity(),
@@ -8131,6 +8978,11 @@ function useAnimationControls() {
8131
8978
  }
8132
8979
  const useAnimation = useAnimationControls;
8133
8980
 
8981
+ const wrap = (min, max, v) => {
8982
+ const rangeSize = max - min;
8983
+ return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
8984
+ };
8985
+
8134
8986
  /**
8135
8987
  * Cycles through a series of visual properties. Can be used to toggle between or cycle through animations. It works similar to `useState` in React. It is provided an initial array of possible states, and returns an array of two arguments.
8136
8988
  *
@@ -8163,7 +9015,7 @@ function useCycle(...items) {
8163
9015
  const runCycle = React.useCallback((next) => {
8164
9016
  index.current =
8165
9017
  typeof next !== "number"
8166
- ? popmotion.wrap(0, items.length, index.current + 1)
9018
+ ? wrap(0, items.length, index.current + 1)
8167
9019
  : next;
8168
9020
  setItem(items[index.current]);
8169
9021
  },
@@ -8468,10 +9320,13 @@ exports.animations = animations;
8468
9320
  exports.buildTransform = buildTransform;
8469
9321
  exports.calcLength = calcLength;
8470
9322
  exports.checkTargetForNewValues = checkTargetForNewValues;
9323
+ exports.clamp = clamp;
8471
9324
  exports.createBox = createBox;
8472
9325
  exports.createDomMotionComponent = createDomMotionComponent;
8473
9326
  exports.createMotionComponent = createMotionComponent;
8474
9327
  exports.delay = delay;
9328
+ exports.distance = distance;
9329
+ exports.distance2D = distance2D;
8475
9330
  exports.domAnimation = domAnimation;
8476
9331
  exports.domMax = domMax;
8477
9332
  exports.filterProps = filterProps;
@@ -8482,8 +9337,10 @@ exports.isMotionValue = isMotionValue;
8482
9337
  exports.isValidMotionProp = isValidMotionProp;
8483
9338
  exports.m = m;
8484
9339
  exports.makeUseVisualState = makeUseVisualState;
9340
+ exports.mix = mix;
8485
9341
  exports.motion = motion;
8486
9342
  exports.motionValue = motionValue;
9343
+ exports.pipe = pipe;
8487
9344
  exports.resolveMotionValue = resolveMotionValue;
8488
9345
  exports.transform = transform;
8489
9346
  exports.unwrapMotionComponent = unwrapMotionComponent;
@@ -8517,4 +9374,5 @@ exports.useVelocity = useVelocity;
8517
9374
  exports.useViewportScroll = useViewportScroll;
8518
9375
  exports.useVisualElementContext = useVisualElementContext;
8519
9376
  exports.useWillChange = useWillChange;
9377
+ exports.wrap = wrap;
8520
9378
  exports.wrapHandler = wrapHandler;