framer-motion 10.9.4 → 10.10.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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var transform = require('./transform-587ecd00.js');
5
+ var transform = require('./transform-6d9fcb92.js');
6
6
 
7
7
 
8
8
 
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 transform = require('./transform-587ecd00.js');
6
+ var transform = require('./transform-6d9fcb92.js');
7
7
 
8
8
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
9
 
@@ -1752,7 +1752,7 @@ function calculateDuration(generator) {
1752
1752
  duration += timeStep;
1753
1753
  state = generator.next(duration);
1754
1754
  }
1755
- return duration;
1755
+ return duration >= maxDuration$1 ? Infinity : duration;
1756
1756
  }
1757
1757
  /**
1758
1758
  * Animate a single value on the main thread.
@@ -1825,26 +1825,36 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
1825
1825
  resolvedDuration = calculatedDuration + repeatDelay;
1826
1826
  totalDuration = resolvedDuration * (repeat + 1) - repeatDelay;
1827
1827
  }
1828
- let time = 0;
1828
+ let currentTime = 0;
1829
1829
  const tick = (timestamp) => {
1830
1830
  if (startTime === null)
1831
1831
  return;
1832
+ /**
1833
+ * requestAnimationFrame timestamps can come through as lower than
1834
+ * the startTime as set by performance.now(). Here we prevent this,
1835
+ * though in the future it could be possible to make setting startTime
1836
+ * a pending operation that gets resolved here.
1837
+ */
1838
+ if (speed > 0)
1839
+ startTime = Math.min(startTime, timestamp);
1832
1840
  if (holdTime !== null) {
1833
- time = holdTime;
1841
+ currentTime = holdTime;
1834
1842
  }
1835
1843
  else {
1836
- time = (timestamp - startTime) * speed;
1844
+ currentTime = (timestamp - startTime) * speed;
1837
1845
  }
1838
1846
  // Rebase on delay
1839
- time = Math.max(time - delay, 0);
1847
+ const timeWithoutDelay = currentTime - delay;
1848
+ const isInDelayPhase = timeWithoutDelay < 0;
1849
+ currentTime = Math.max(timeWithoutDelay, 0);
1840
1850
  /**
1841
1851
  * If this animation has finished, set the current time
1842
1852
  * to the total duration.
1843
1853
  */
1844
1854
  if (playState === "finished" && holdTime === null) {
1845
- time = totalDuration;
1855
+ currentTime = totalDuration;
1846
1856
  }
1847
- let elapsed = time;
1857
+ let elapsed = currentTime;
1848
1858
  let frameGenerator = generator;
1849
1859
  if (repeat) {
1850
1860
  /**
@@ -1852,7 +1862,7 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
1852
1862
  * than duration we'll get values like 2.5 (midway through the
1853
1863
  * third iteration)
1854
1864
  */
1855
- const progress = time / resolvedDuration;
1865
+ const progress = currentTime / resolvedDuration;
1856
1866
  /**
1857
1867
  * Get the current iteration (0 indexed). For instance the floor of
1858
1868
  * 2.5 is 2.
@@ -1888,23 +1898,30 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
1888
1898
  }
1889
1899
  }
1890
1900
  let p = clamp(0, 1, iterationProgress);
1891
- if (time > totalDuration) {
1901
+ if (currentTime > totalDuration) {
1892
1902
  p = repeatType === "reverse" && iterationIsOdd ? 1 : 0;
1893
1903
  }
1894
1904
  elapsed = p * resolvedDuration;
1895
1905
  }
1896
- const state = frameGenerator.next(elapsed);
1906
+ /**
1907
+ * If we're in negative time, set state as the initial keyframe.
1908
+ * This prevents delay: x, duration: 0 animations from finishing
1909
+ * instantly.
1910
+ */
1911
+ const state = isInDelayPhase
1912
+ ? { done: false, value: keyframes$1[0] }
1913
+ : frameGenerator.next(elapsed);
1897
1914
  if (mapNumbersToKeyframes) {
1898
1915
  state.value = mapNumbersToKeyframes(state.value);
1899
1916
  }
1900
1917
  let { done } = state;
1901
- if (calculatedDuration !== null) {
1902
- done = time >= totalDuration;
1918
+ if (!isInDelayPhase && calculatedDuration !== null) {
1919
+ done = currentTime >= totalDuration;
1903
1920
  }
1904
1921
  const isAnimationFinished = holdTime === null &&
1905
1922
  (playState === "finished" ||
1906
1923
  (playState === "running" && done) ||
1907
- (speed < 0 && time <= 0));
1924
+ (speed < 0 && currentTime <= 0));
1908
1925
  if (onUpdate) {
1909
1926
  onUpdate(state.value);
1910
1927
  }
@@ -1957,11 +1974,11 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
1957
1974
  return currentFinishedPromise.then(resolve, reject);
1958
1975
  },
1959
1976
  get time() {
1960
- return millisecondsToSeconds(time);
1977
+ return millisecondsToSeconds(currentTime);
1961
1978
  },
1962
1979
  set time(newTime) {
1963
1980
  newTime = secondsToMilliseconds(newTime);
1964
- time = newTime;
1981
+ currentTime = newTime;
1965
1982
  if (holdTime !== null || !animationDriver || speed === 0) {
1966
1983
  holdTime = newTime;
1967
1984
  }
@@ -1969,6 +1986,12 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
1969
1986
  startTime = animationDriver.now() - newTime / speed;
1970
1987
  }
1971
1988
  },
1989
+ get duration() {
1990
+ const duration = generator.calculatedDuration === null
1991
+ ? calculateDuration(generator)
1992
+ : generator.calculatedDuration;
1993
+ return millisecondsToSeconds(duration);
1994
+ },
1972
1995
  get speed() {
1973
1996
  return speed;
1974
1997
  },
@@ -1976,7 +1999,7 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
1976
1999
  if (newSpeed === speed || !animationDriver)
1977
2000
  return;
1978
2001
  speed = newSpeed;
1979
- controls.time = millisecondsToSeconds(time);
2002
+ controls.time = millisecondsToSeconds(currentTime);
1980
2003
  },
1981
2004
  get state() {
1982
2005
  return playState;
@@ -1984,7 +2007,7 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
1984
2007
  play,
1985
2008
  pause: () => {
1986
2009
  playState = "paused";
1987
- holdTime = time;
2010
+ holdTime = currentTime;
1988
2011
  },
1989
2012
  stop: () => {
1990
2013
  hasStopped = true;
@@ -2137,6 +2160,9 @@ function createAcceleratedAnimation(value, valueName, { onUpdate, onComplete, ..
2137
2160
  set speed(newSpeed) {
2138
2161
  animation.playbackRate = newSpeed;
2139
2162
  },
2163
+ get duration() {
2164
+ return millisecondsToSeconds(duration);
2165
+ },
2140
2166
  play: () => {
2141
2167
  if (hasStopped)
2142
2168
  return;
@@ -2170,7 +2196,7 @@ function createAcceleratedAnimation(value, valueName, { onUpdate, onComplete, ..
2170
2196
  };
2171
2197
  }
2172
2198
 
2173
- function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplete, }) {
2199
+ function createInstantAnimation({ keyframes, delay, onUpdate, onComplete, }) {
2174
2200
  const setValue = () => {
2175
2201
  onUpdate && onUpdate(keyframes[keyframes.length - 1]);
2176
2202
  onComplete && onComplete();
@@ -2184,6 +2210,7 @@ function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplet
2184
2210
  return {
2185
2211
  time: 0,
2186
2212
  speed: 1,
2213
+ duration: 0,
2187
2214
  play: (noop),
2188
2215
  pause: (noop),
2189
2216
  stop: (noop),
@@ -2195,10 +2222,11 @@ function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplet
2195
2222
  complete: (noop),
2196
2223
  };
2197
2224
  };
2198
- return delayBy
2225
+ return delay
2199
2226
  ? animateValue({
2200
2227
  keyframes: [0, 1],
2201
- duration: delayBy,
2228
+ duration: 0,
2229
+ delay,
2202
2230
  onComplete: setValue,
2203
2231
  })
2204
2232
  : setValue();
@@ -2430,16 +2458,6 @@ const animateMotionValue = (valueName, value, target, transition = {}) => {
2430
2458
  valueTransition.onComplete && valueTransition.onComplete();
2431
2459
  },
2432
2460
  };
2433
- if (!isOriginAnimatable ||
2434
- !isTargetAnimatable ||
2435
- instantAnimationState.current ||
2436
- valueTransition.type === false) {
2437
- /**
2438
- * If we can't animate this value, or the global instant animation flag is set,
2439
- * or this is simply defined as an instant transition, return an instant transition.
2440
- */
2441
- return createInstantAnimation(options);
2442
- }
2443
2461
  /**
2444
2462
  * If there's no transition defined for this value, we can generate
2445
2463
  * unqiue transition settings for this value.
@@ -2461,6 +2479,16 @@ const animateMotionValue = (valueName, value, target, transition = {}) => {
2461
2479
  if (options.repeatDelay) {
2462
2480
  options.repeatDelay = secondsToMilliseconds(options.repeatDelay);
2463
2481
  }
2482
+ if (!isOriginAnimatable ||
2483
+ !isTargetAnimatable ||
2484
+ instantAnimationState.current ||
2485
+ valueTransition.type === false) {
2486
+ /**
2487
+ * If we can't animate this value, or the global instant animation flag is set,
2488
+ * or this is simply defined as an instant transition, return an instant transition.
2489
+ */
2490
+ return createInstantAnimation(options);
2491
+ }
2464
2492
  /**
2465
2493
  * Animate via WAAPI if possible.
2466
2494
  */
@@ -2581,7 +2609,7 @@ class MotionValue {
2581
2609
  * This will be replaced by the build step with the latest version number.
2582
2610
  * When MotionValues are provided to motion components, warn if versions are mixed.
2583
2611
  */
2584
- this.version = "10.9.4";
2612
+ this.version = "10.10.0";
2585
2613
  /**
2586
2614
  * Duration, in milliseconds, since last updating frame.
2587
2615
  *
@@ -3370,6 +3398,13 @@ class GroupPlaybackControls {
3370
3398
  set speed(speed) {
3371
3399
  this.setAll("speed", speed);
3372
3400
  }
3401
+ get duration() {
3402
+ let max = 0;
3403
+ for (let i = 0; i < this.animations.length; i++) {
3404
+ max = Math.max(max, this.animations[i].duration);
3405
+ }
3406
+ return max;
3407
+ }
3373
3408
  runAll(methodName) {
3374
3409
  this.animations.forEach((controls) => controls[methodName]());
3375
3410
  }
@@ -3740,7 +3775,7 @@ function updateMotionValuesFromProps(element, next, prev) {
3740
3775
  * and warn against mismatches.
3741
3776
  */
3742
3777
  if (process.env.NODE_ENV === "development") {
3743
- warnOnce(nextValue.version === "10.9.4", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.9.4 may not work as expected.`);
3778
+ warnOnce(nextValue.version === "10.10.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.10.0 may not work as expected.`);
3744
3779
  }
3745
3780
  }
3746
3781
  else if (isMotionValue(prevValue)) {
@@ -340,6 +340,7 @@ declare type ElementOrSelector = Element | Element[] | NodeListOf<Element> | str
340
340
  interface AnimationPlaybackControls {
341
341
  time: number;
342
342
  speed: number;
343
+ duration: number;
343
344
  stop: () => void;
344
345
  play: () => void;
345
346
  pause: () => void;
@@ -28,6 +28,13 @@ class GroupPlaybackControls {
28
28
  set speed(speed) {
29
29
  this.setAll("speed", speed);
30
30
  }
31
+ get duration() {
32
+ let max = 0;
33
+ for (let i = 0; i < this.animations.length; i++) {
34
+ max = Math.max(max, this.animations[i].duration);
35
+ }
36
+ return max;
37
+ }
31
38
  runAll(methodName) {
32
39
  this.animations.forEach((controls) => controls[methodName]());
33
40
  }
@@ -1,7 +1,7 @@
1
1
  import { animateValue } from './js/index.mjs';
2
2
  import { noop } from '../../utils/noop.mjs';
3
3
 
4
- function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplete, }) {
4
+ function createInstantAnimation({ keyframes, delay, onUpdate, onComplete, }) {
5
5
  const setValue = () => {
6
6
  onUpdate && onUpdate(keyframes[keyframes.length - 1]);
7
7
  onComplete && onComplete();
@@ -15,6 +15,7 @@ function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplet
15
15
  return {
16
16
  time: 0,
17
17
  speed: 1,
18
+ duration: 0,
18
19
  play: (noop),
19
20
  pause: (noop),
20
21
  stop: (noop),
@@ -26,10 +27,11 @@ function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplet
26
27
  complete: (noop),
27
28
  };
28
29
  };
29
- return delayBy
30
+ return delay
30
31
  ? animateValue({
31
32
  keyframes: [0, 1],
32
- duration: delayBy,
33
+ duration: 0,
34
+ delay,
33
35
  onComplete: setValue,
34
36
  })
35
37
  : setValue();
@@ -26,7 +26,7 @@ function calculateDuration(generator) {
26
26
  duration += timeStep;
27
27
  state = generator.next(duration);
28
28
  }
29
- return duration;
29
+ return duration >= maxDuration ? Infinity : duration;
30
30
  }
31
31
  /**
32
32
  * Animate a single value on the main thread.
@@ -99,26 +99,36 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
99
99
  resolvedDuration = calculatedDuration + repeatDelay;
100
100
  totalDuration = resolvedDuration * (repeat + 1) - repeatDelay;
101
101
  }
102
- let time = 0;
102
+ let currentTime = 0;
103
103
  const tick = (timestamp) => {
104
104
  if (startTime === null)
105
105
  return;
106
+ /**
107
+ * requestAnimationFrame timestamps can come through as lower than
108
+ * the startTime as set by performance.now(). Here we prevent this,
109
+ * though in the future it could be possible to make setting startTime
110
+ * a pending operation that gets resolved here.
111
+ */
112
+ if (speed > 0)
113
+ startTime = Math.min(startTime, timestamp);
106
114
  if (holdTime !== null) {
107
- time = holdTime;
115
+ currentTime = holdTime;
108
116
  }
109
117
  else {
110
- time = (timestamp - startTime) * speed;
118
+ currentTime = (timestamp - startTime) * speed;
111
119
  }
112
120
  // Rebase on delay
113
- time = Math.max(time - delay, 0);
121
+ const timeWithoutDelay = currentTime - delay;
122
+ const isInDelayPhase = timeWithoutDelay < 0;
123
+ currentTime = Math.max(timeWithoutDelay, 0);
114
124
  /**
115
125
  * If this animation has finished, set the current time
116
126
  * to the total duration.
117
127
  */
118
128
  if (playState === "finished" && holdTime === null) {
119
- time = totalDuration;
129
+ currentTime = totalDuration;
120
130
  }
121
- let elapsed = time;
131
+ let elapsed = currentTime;
122
132
  let frameGenerator = generator;
123
133
  if (repeat) {
124
134
  /**
@@ -126,7 +136,7 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
126
136
  * than duration we'll get values like 2.5 (midway through the
127
137
  * third iteration)
128
138
  */
129
- const progress = time / resolvedDuration;
139
+ const progress = currentTime / resolvedDuration;
130
140
  /**
131
141
  * Get the current iteration (0 indexed). For instance the floor of
132
142
  * 2.5 is 2.
@@ -162,23 +172,30 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
162
172
  }
163
173
  }
164
174
  let p = clamp(0, 1, iterationProgress);
165
- if (time > totalDuration) {
175
+ if (currentTime > totalDuration) {
166
176
  p = repeatType === "reverse" && iterationIsOdd ? 1 : 0;
167
177
  }
168
178
  elapsed = p * resolvedDuration;
169
179
  }
170
- const state = frameGenerator.next(elapsed);
180
+ /**
181
+ * If we're in negative time, set state as the initial keyframe.
182
+ * This prevents delay: x, duration: 0 animations from finishing
183
+ * instantly.
184
+ */
185
+ const state = isInDelayPhase
186
+ ? { done: false, value: keyframes$1[0] }
187
+ : frameGenerator.next(elapsed);
171
188
  if (mapNumbersToKeyframes) {
172
189
  state.value = mapNumbersToKeyframes(state.value);
173
190
  }
174
191
  let { done } = state;
175
- if (calculatedDuration !== null) {
176
- done = time >= totalDuration;
192
+ if (!isInDelayPhase && calculatedDuration !== null) {
193
+ done = currentTime >= totalDuration;
177
194
  }
178
195
  const isAnimationFinished = holdTime === null &&
179
196
  (playState === "finished" ||
180
197
  (playState === "running" && done) ||
181
- (speed < 0 && time <= 0));
198
+ (speed < 0 && currentTime <= 0));
182
199
  if (onUpdate) {
183
200
  onUpdate(state.value);
184
201
  }
@@ -231,11 +248,11 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
231
248
  return currentFinishedPromise.then(resolve, reject);
232
249
  },
233
250
  get time() {
234
- return millisecondsToSeconds(time);
251
+ return millisecondsToSeconds(currentTime);
235
252
  },
236
253
  set time(newTime) {
237
254
  newTime = secondsToMilliseconds(newTime);
238
- time = newTime;
255
+ currentTime = newTime;
239
256
  if (holdTime !== null || !animationDriver || speed === 0) {
240
257
  holdTime = newTime;
241
258
  }
@@ -243,6 +260,12 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
243
260
  startTime = animationDriver.now() - newTime / speed;
244
261
  }
245
262
  },
263
+ get duration() {
264
+ const duration = generator.calculatedDuration === null
265
+ ? calculateDuration(generator)
266
+ : generator.calculatedDuration;
267
+ return millisecondsToSeconds(duration);
268
+ },
246
269
  get speed() {
247
270
  return speed;
248
271
  },
@@ -250,7 +273,7 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
250
273
  if (newSpeed === speed || !animationDriver)
251
274
  return;
252
275
  speed = newSpeed;
253
- controls.time = millisecondsToSeconds(time);
276
+ controls.time = millisecondsToSeconds(currentTime);
254
277
  },
255
278
  get state() {
256
279
  return playState;
@@ -258,7 +281,7 @@ function animateValue({ autoplay = true, delay = 0, driver = frameloopDriver, ke
258
281
  play,
259
282
  pause: () => {
260
283
  playState = "paused";
261
- holdTime = time;
284
+ holdTime = currentTime;
262
285
  },
263
286
  stop: () => {
264
287
  hasStopped = true;
@@ -133,6 +133,9 @@ function createAcceleratedAnimation(value, valueName, { onUpdate, onComplete, ..
133
133
  set speed(newSpeed) {
134
134
  animation.playbackRate = newSpeed;
135
135
  },
136
+ get duration() {
137
+ return millisecondsToSeconds(duration);
138
+ },
136
139
  play: () => {
137
140
  if (hasStopped)
138
141
  return;
@@ -50,16 +50,6 @@ const animateMotionValue = (valueName, value, target, transition = {}) => {
50
50
  valueTransition.onComplete && valueTransition.onComplete();
51
51
  },
52
52
  };
53
- if (!isOriginAnimatable ||
54
- !isTargetAnimatable ||
55
- instantAnimationState.current ||
56
- valueTransition.type === false) {
57
- /**
58
- * If we can't animate this value, or the global instant animation flag is set,
59
- * or this is simply defined as an instant transition, return an instant transition.
60
- */
61
- return createInstantAnimation(options);
62
- }
63
53
  /**
64
54
  * If there's no transition defined for this value, we can generate
65
55
  * unqiue transition settings for this value.
@@ -81,6 +71,16 @@ const animateMotionValue = (valueName, value, target, transition = {}) => {
81
71
  if (options.repeatDelay) {
82
72
  options.repeatDelay = secondsToMilliseconds(options.repeatDelay);
83
73
  }
74
+ if (!isOriginAnimatable ||
75
+ !isTargetAnimatable ||
76
+ instantAnimationState.current ||
77
+ valueTransition.type === false) {
78
+ /**
79
+ * If we can't animate this value, or the global instant animation flag is set,
80
+ * or this is simply defined as an instant transition, return an instant transition.
81
+ */
82
+ return createInstantAnimation(options);
83
+ }
84
84
  /**
85
85
  * Animate via WAAPI if possible.
86
86
  */
@@ -22,7 +22,7 @@ function updateMotionValuesFromProps(element, next, prev) {
22
22
  * and warn against mismatches.
23
23
  */
24
24
  if (process.env.NODE_ENV === "development") {
25
- warnOnce(nextValue.version === "10.9.4", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.9.4 may not work as expected.`);
25
+ warnOnce(nextValue.version === "10.10.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.10.0 may not work as expected.`);
26
26
  }
27
27
  }
28
28
  else if (isMotionValue(prevValue)) {
@@ -26,7 +26,7 @@ class MotionValue {
26
26
  * This will be replaced by the build step with the latest version number.
27
27
  * When MotionValues are provided to motion components, warn if versions are mixed.
28
28
  */
29
- this.version = "10.9.4";
29
+ this.version = "10.10.0";
30
30
  /**
31
31
  * Duration, in milliseconds, since last updating frame.
32
32
  *