motion 12.7.4 → 12.7.5-alpha.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.
Files changed (173) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/debug.js +22 -14
  3. package/dist/cjs/index.js +4113 -3624
  4. package/dist/cjs/mini.js +403 -324
  5. package/dist/cjs/react-client.js +3151 -3245
  6. package/dist/cjs/react-m.js +169 -166
  7. package/dist/cjs/react-mini.js +330 -251
  8. package/dist/es/framer-motion/dist/es/animation/animate/sequence.mjs +1 -1
  9. package/dist/es/framer-motion/dist/es/animation/animators/waapi/animate-elements.mjs +81 -9
  10. package/dist/es/framer-motion/dist/es/animation/interfaces/motion-value.mjs +11 -30
  11. package/dist/es/framer-motion/dist/es/animation/interfaces/visual-element-target.mjs +1 -1
  12. package/dist/es/framer-motion/dist/es/animation/optimized-appear/store-id.mjs +1 -1
  13. package/dist/es/framer-motion/dist/es/animation/sequence/create.mjs +3 -3
  14. package/dist/es/framer-motion/dist/es/animation/sequence/utils/edit.mjs +2 -2
  15. package/dist/es/framer-motion/dist/es/animation/utils/default-transitions.mjs +1 -1
  16. package/dist/es/framer-motion/dist/es/animation/utils/stagger.mjs +1 -1
  17. package/dist/es/framer-motion/dist/es/components/Reorder/utils/check-reorder.mjs +1 -1
  18. package/dist/es/framer-motion/dist/es/gestures/drag/VisualElementDragControls.mjs +2 -2
  19. package/dist/es/framer-motion/dist/es/gestures/drag/utils/constraints.mjs +2 -2
  20. package/dist/es/framer-motion/dist/es/gestures/focus.mjs +1 -1
  21. package/dist/es/framer-motion/dist/es/gestures/pan/PanSession.mjs +1 -1
  22. package/dist/es/framer-motion/dist/es/motion/utils/is-forced-motion-value.mjs +1 -1
  23. package/dist/es/framer-motion/dist/es/projection/animation/mix-values.mjs +3 -3
  24. package/dist/es/framer-motion/dist/es/projection/geometry/delta-apply.mjs +1 -1
  25. package/dist/es/framer-motion/dist/es/projection/geometry/delta-calc.mjs +1 -1
  26. package/dist/es/framer-motion/dist/es/projection/geometry/delta-remove.mjs +2 -2
  27. package/dist/es/framer-motion/dist/es/projection/node/create-projection-node.mjs +3 -5
  28. package/dist/es/framer-motion/dist/es/projection/styles/scale-border-radius.mjs +1 -1
  29. package/dist/es/framer-motion/dist/es/projection/styles/scale-box-shadow.mjs +2 -2
  30. package/dist/es/framer-motion/dist/es/projection/styles/scale-correction.mjs +1 -1
  31. package/dist/es/framer-motion/dist/es/render/VisualElement.mjs +7 -7
  32. package/dist/es/framer-motion/dist/es/render/dom/DOMVisualElement.mjs +1 -1
  33. package/dist/es/framer-motion/dist/es/render/dom/scroll/attach-animation.mjs +17 -0
  34. package/dist/es/framer-motion/dist/es/render/dom/scroll/attach-function.mjs +23 -0
  35. package/dist/es/framer-motion/dist/es/render/dom/scroll/index.mjs +6 -82
  36. package/dist/es/framer-motion/dist/es/render/dom/scroll/offsets/index.mjs +3 -3
  37. package/dist/es/framer-motion/dist/es/render/dom/scroll/utils/get-timeline.mjs +29 -0
  38. package/dist/es/framer-motion/dist/es/render/html/HTMLVisualElement.mjs +3 -3
  39. package/dist/es/framer-motion/dist/es/render/html/utils/build-styles.mjs +4 -4
  40. package/dist/es/framer-motion/dist/es/render/html/utils/build-transform.mjs +3 -3
  41. package/dist/es/framer-motion/dist/es/render/svg/SVGVisualElement.mjs +2 -2
  42. package/dist/es/framer-motion/dist/es/render/svg/config-motion.mjs +1 -1
  43. package/dist/es/framer-motion/dist/es/render/svg/utils/path.mjs +1 -1
  44. package/dist/es/framer-motion/dist/es/render/svg/utils/scrape-motion-values.mjs +1 -1
  45. package/dist/es/framer-motion/dist/es/render/svg/utils/transform-origin.mjs +1 -1
  46. package/dist/es/framer-motion/dist/es/render/utils/motion-values.mjs +1 -1
  47. package/dist/es/framer-motion/dist/es/utils/delay.mjs +1 -1
  48. package/dist/es/framer-motion/dist/es/utils/transform.mjs +1 -1
  49. package/dist/es/framer-motion/dist/es/utils/use-cycle.mjs +1 -1
  50. package/dist/es/framer-motion/dist/es/utils/use-instant-transition.mjs +4 -4
  51. package/dist/es/framer-motion/dist/es/value/use-spring.mjs +2 -2
  52. package/dist/es/framer-motion/dist/es/value/use-will-change/get-will-change-name.mjs +2 -2
  53. package/dist/es/motion/lib/index.mjs +109 -26
  54. package/dist/es/motion/lib/react.mjs +108 -32
  55. package/dist/es/motion-dom/dist/es/animation/AsyncMotionValueAnimation.mjs +179 -0
  56. package/dist/es/motion-dom/dist/es/animation/GroupAnimation.mjs +6 -15
  57. package/dist/es/{framer-motion/dist/es/animation/animators/MainThreadAnimation.mjs → motion-dom/dist/es/animation/JSAnimation.mjs} +108 -156
  58. package/dist/es/motion-dom/dist/es/animation/NativeAnimation.mjs +64 -67
  59. package/dist/es/motion-dom/dist/es/animation/NativeAnimationExtended.mjs +65 -0
  60. package/dist/es/motion-dom/dist/es/animation/NativeAnimationWrapper.mjs +14 -0
  61. package/dist/es/{framer-motion/dist/es/animation/animators → motion-dom/dist/es/animation}/drivers/driver-frameloop.mjs +2 -2
  62. package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/keyframes.mjs +5 -5
  63. package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/spring/find.mjs +1 -1
  64. package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/spring/index.mjs +5 -6
  65. package/dist/es/{framer-motion/dist/es/render/dom → motion-dom/dist/es/animation/keyframes}/DOMKeyframesResolver.mjs +9 -8
  66. package/dist/es/{framer-motion/dist/es/render/utils → motion-dom/dist/es/animation/keyframes}/KeyframesResolver.mjs +28 -35
  67. package/dist/es/motion-dom/dist/es/animation/keyframes/get-final.mjs +3 -4
  68. package/dist/es/{framer-motion/dist/es/utils → motion-dom/dist/es/animation/keyframes}/offsets/fill.mjs +2 -2
  69. package/dist/es/motion-dom/dist/es/animation/keyframes/utils/apply-px-defaults.mjs +11 -0
  70. package/dist/es/motion-dom/dist/es/animation/keyframes/utils/fill-wildcards.mjs +7 -0
  71. package/dist/es/{framer-motion/dist/es/animation → motion-dom/dist/es/animation/keyframes}/utils/is-none.mjs +1 -1
  72. package/dist/es/{framer-motion/dist/es/render/html → motion-dom/dist/es/animation/keyframes}/utils/make-none-animatable.mjs +1 -1
  73. package/dist/es/{framer-motion/dist/es/render/dom → motion-dom/dist/es/animation/keyframes}/utils/unit-conversion.mjs +2 -2
  74. package/dist/es/motion-dom/dist/es/animation/utils/WithPromise.mjs +28 -0
  75. package/dist/es/motion-dom/dist/es/animation/utils/active-animations.mjs +9 -0
  76. package/dist/es/{framer-motion/dist/es/animation/animators → motion-dom/dist/es/animation}/utils/can-animate.mjs +3 -3
  77. package/dist/es/{framer-motion/dist/es/render/dom → motion-dom/dist/es/animation}/utils/css-variables-conversion.mjs +2 -2
  78. package/dist/es/motion-dom/dist/es/animation/utils/replace-transition-type.mjs +18 -0
  79. package/dist/es/motion-dom/dist/es/animation/waapi/easing/is-supported.mjs +1 -1
  80. package/dist/es/motion-dom/dist/es/animation/waapi/easing/map-easing.mjs +5 -3
  81. package/dist/es/motion-dom/dist/es/animation/waapi/start-waapi-animation.mjs +6 -4
  82. package/dist/es/motion-dom/dist/es/animation/waapi/supports/waapi.mjs +39 -0
  83. package/dist/es/motion-dom/dist/es/animation/waapi/utils/apply-generator.mjs +2 -1
  84. package/dist/es/motion-dom/dist/es/animation/waapi/utils/unsupported-easing.mjs +20 -0
  85. package/dist/es/motion-dom/dist/es/frameloop/batcher.mjs +2 -1
  86. package/dist/es/motion-dom/dist/es/frameloop/order.mjs +1 -0
  87. package/dist/es/motion-dom/dist/es/render/dom/is-css-var.mjs +3 -0
  88. package/dist/es/motion-dom/dist/es/render/dom/style-computed.mjs +10 -0
  89. package/dist/es/motion-dom/dist/es/render/dom/style-set.mjs +9 -0
  90. package/dist/es/{framer-motion/dist/es/render/html → motion-dom/dist/es/render}/utils/keys-transform.mjs +1 -1
  91. package/dist/es/{framer-motion/dist/es/render/dom → motion-dom/dist/es}/scroll/observe.mjs +1 -1
  92. package/dist/es/motion-dom/dist/es/stats/index.mjs +2 -0
  93. package/dist/es/{framer-motion → motion-dom}/dist/es/utils/interpolate.mjs +4 -3
  94. package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/color.mjs +3 -3
  95. package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/complex.mjs +5 -5
  96. package/dist/es/motion-dom/dist/es/value/index.mjs +3 -1
  97. package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/color/rgba.mjs +2 -2
  98. package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types}/dimensions.mjs +3 -3
  99. package/dist/es/{framer-motion/dist/es/render/dom/value-types/type-int.mjs → motion-dom/dist/es/value/types/int.mjs} +1 -1
  100. package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types/maps}/defaults.mjs +2 -2
  101. package/dist/es/{framer-motion/dist/es/render/dom/value-types/number-browser.mjs → motion-dom/dist/es/value/types/maps/number.mjs} +13 -3
  102. package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types/maps}/transform.mjs +2 -2
  103. package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/numbers/index.mjs +1 -1
  104. package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/numbers/units.mjs +3 -2
  105. package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types/utils}/animatable-none.mjs +4 -4
  106. package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types/utils}/find.mjs +4 -4
  107. package/dist/es/motion-dom/dist/es/view/index.mjs +64 -0
  108. package/dist/es/motion-dom/dist/es/view/queue.mjs +52 -0
  109. package/dist/es/motion-dom/dist/es/view/start.mjs +155 -0
  110. package/dist/es/motion-dom/dist/es/view/utils/choose-layer-type.mjs +11 -0
  111. package/dist/es/motion-dom/dist/es/view/utils/css.mjs +32 -0
  112. package/dist/es/motion-dom/dist/es/view/utils/get-layer-name.mjs +8 -0
  113. package/dist/es/motion-dom/dist/es/view/utils/get-view-animations.mjs +12 -0
  114. package/dist/es/motion-dom/dist/es/view/utils/has-target.mjs +5 -0
  115. package/dist/es/{framer-motion → motion-utils}/dist/es/easing/cubic-bezier.mjs +1 -1
  116. package/dist/es/{framer-motion → motion-utils}/dist/es/easing/steps.mjs +1 -1
  117. package/dist/es/{framer-motion → motion-utils}/dist/es/easing/utils/get-easing-for-segment.mjs +1 -1
  118. package/dist/es/{framer-motion → motion-utils}/dist/es/easing/utils/map.mjs +7 -4
  119. package/dist/es/motion-utils/dist/es/global-config.mjs +1 -4
  120. package/dist/es/motion-utils/dist/es/warn-once.mjs +4 -1
  121. package/dist/motion.dev.js +4108 -3619
  122. package/dist/motion.js +1 -1
  123. package/package.json +3 -3
  124. package/dist/es/framer-motion/dist/es/animation/animators/AcceleratedAnimation.mjs +0 -324
  125. package/dist/es/framer-motion/dist/es/animation/animators/BaseAnimation.mjs +0 -120
  126. package/dist/es/framer-motion/dist/es/animation/animators/waapi/utils/supports-waapi.mjs +0 -5
  127. package/dist/es/framer-motion/dist/es/render/dom/value-types/number.mjs +0 -18
  128. package/dist/es/framer-motion/dist/es/utils/use-instant-transition-state.mjs +0 -5
  129. package/dist/es/motion-dom/dist/es/animation/keyframes/hydrate.mjs +0 -26
  130. package/dist/es/motion-dom/dist/es/animation/waapi/utils/attach-timeline.mjs +0 -6
  131. package/dist/es/motion-dom/dist/es/render/dom/style.mjs +0 -15
  132. /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/inertia.mjs +0 -0
  133. /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/spring/defaults.mjs +0 -0
  134. /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/utils/velocity.mjs +0 -0
  135. /package/dist/es/{framer-motion/dist/es/utils → motion-dom/dist/es/animation/keyframes}/offsets/default.mjs +0 -0
  136. /package/dist/es/{framer-motion/dist/es/utils → motion-dom/dist/es/animation/keyframes}/offsets/time.mjs +0 -0
  137. /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/utils/is-animatable.mjs +0 -0
  138. /package/dist/es/{framer-motion/dist/es/render/dom → motion-dom/dist/es/animation}/utils/is-css-variable.mjs +0 -0
  139. /package/dist/es/{framer-motion/dist/es/animation/animators → motion-dom/dist/es/animation/waapi}/utils/accelerated-values.mjs +0 -0
  140. /package/dist/es/{framer-motion/dist/es/render/html/utils → motion-dom/dist/es/render/dom}/parse-transform.mjs +0 -0
  141. /package/dist/es/{framer-motion/dist/es/render/html → motion-dom/dist/es/render}/utils/keys-position.mjs +0 -0
  142. /package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/immediate.mjs +0 -0
  143. /package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/index.mjs +0 -0
  144. /package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/number.mjs +0 -0
  145. /package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/visibility.mjs +0 -0
  146. /package/dist/es/{framer-motion/dist/es/render/dom/value-types/type-auto.mjs → motion-dom/dist/es/value/types/auto.mjs} +0 -0
  147. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/color/hex.mjs +0 -0
  148. /package/dist/es/{framer-motion/dist/es/utils → motion-dom/dist/es/value/types/color}/hsla-to-rgba.mjs +0 -0
  149. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/color/hsla.mjs +0 -0
  150. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/color/index.mjs +0 -0
  151. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/color/utils.mjs +0 -0
  152. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/complex/filter.mjs +0 -0
  153. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/complex/index.mjs +0 -0
  154. /package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types}/test.mjs +0 -0
  155. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/utils/color-regex.mjs +0 -0
  156. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/utils/float-regex.mjs +0 -0
  157. /package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types/utils}/get-as-type.mjs +0 -0
  158. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/utils/is-nullish.mjs +0 -0
  159. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/utils/sanitize.mjs +0 -0
  160. /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/utils/single-color-regex.mjs +0 -0
  161. /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/clamp.mjs +0 -0
  162. /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/anticipate.mjs +0 -0
  163. /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/back.mjs +0 -0
  164. /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/circ.mjs +0 -0
  165. /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/ease.mjs +0 -0
  166. /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/modifiers/mirror.mjs +0 -0
  167. /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/modifiers/reverse.mjs +0 -0
  168. /package/dist/es/{motion-dom/dist/es → motion-utils/dist/es/easing}/utils/is-bezier-definition.mjs +0 -0
  169. /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/utils/is-easing-array.mjs +0 -0
  170. /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/is-numerical-string.mjs +0 -0
  171. /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/is-zero-value-string.mjs +0 -0
  172. /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/pipe.mjs +0 -0
  173. /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/wrap.mjs +0 -0
@@ -1,92 +1,88 @@
1
- import { style } from '../render/dom/style.mjs';
1
+ import { setStyle } from '../render/dom/style-set.mjs';
2
+ import { supportsScrollTimeline } from '../utils/supports/scroll-timeline.mjs';
2
3
  import { getFinalKeyframe } from './keyframes/get-final.mjs';
3
- import { hydrateKeyframes } from './keyframes/hydrate.mjs';
4
+ import { WithPromise } from './utils/WithPromise.mjs';
4
5
  import { startWaapiAnimation } from './waapi/start-waapi-animation.mjs';
5
6
  import { applyGeneratorOptions } from './waapi/utils/apply-generator.mjs';
6
7
  import { invariant } from '../../../../motion-utils/dist/es/errors.mjs';
7
8
  import { millisecondsToSeconds, secondsToMilliseconds } from '../../../../motion-utils/dist/es/time-conversion.mjs';
8
9
  import { noop } from '../../../../motion-utils/dist/es/noop.mjs';
9
10
 
10
- const animationMaps = new WeakMap();
11
- const animationMapKey = (name, pseudoElement) => `${name}:${pseudoElement}`;
12
- function getAnimationMap(element) {
13
- const map = animationMaps.get(element) || new Map();
14
- animationMaps.set(element, map);
15
- return map;
16
- }
17
11
  /**
18
12
  * NativeAnimation implements AnimationPlaybackControls for the browser's Web Animations API.
19
13
  */
20
- class NativeAnimation {
14
+ class NativeAnimation extends WithPromise {
21
15
  constructor(options) {
22
- /**
23
- * If we already have an animation, we don't need to instantiate one
24
- * and can just use this as a controls interface.
25
- */
26
- if ("animation" in options) {
27
- this.animation = options.animation;
16
+ super();
17
+ this.finishedTime = null;
18
+ this.isStopped = false;
19
+ if (!options)
28
20
  return;
29
- }
30
- const { element, name, keyframes: unresolvedKeyframes, pseudoElement, allowFlatten = false, } = options;
31
- let { transition } = options;
21
+ const { element, name, keyframes, pseudoElement, allowFlatten = false, finalKeyframe, } = options;
32
22
  this.isPseudoElement = Boolean(pseudoElement);
33
23
  this.allowFlatten = allowFlatten;
34
- /**
35
- * Stop any existing animations on the element before reading existing keyframes.
36
- *
37
- * TODO: Check for VisualElement before using animation state. This is a fallback
38
- * for mini animate(). Do this when implementing NativeAnimationExtended.
39
- */
40
- const animationMap = getAnimationMap(element);
41
- const key = animationMapKey(name, pseudoElement || "");
42
- const currentAnimation = animationMap.get(key);
43
- currentAnimation && currentAnimation.stop();
44
- /**
45
- * TODO: If these keyframes aren't correctly hydrated then we want to throw
46
- * run an instant animation.
47
- */
48
- const keyframes = hydrateKeyframes(element, name, unresolvedKeyframes, pseudoElement);
49
- invariant(typeof transition.type !== "string", `animateMini doesn't support "type" as a string. Did you mean to import { spring } from "motion"?`);
50
- transition = applyGeneratorOptions(transition);
24
+ this.options = options;
25
+ invariant(typeof options.type !== "string", `animateMini doesn't support "type" as a string. Did you mean to import { spring } from "motion"?`);
26
+ const transition = applyGeneratorOptions(options);
51
27
  this.animation = startWaapiAnimation(element, name, keyframes, transition, pseudoElement);
52
28
  if (transition.autoplay === false) {
53
29
  this.animation.pause();
54
30
  }
55
- this.removeAnimation = () => animationMap.delete(key);
56
31
  this.animation.onfinish = () => {
32
+ this.finishedTime = this.time;
57
33
  if (!pseudoElement) {
58
- style.set(element, name, getFinalKeyframe(keyframes, transition));
59
- this.cancel();
34
+ const keyframe = getFinalKeyframe(keyframes, this.options, finalKeyframe, this.speed);
35
+ if (this.updateMotionValue) {
36
+ this.updateMotionValue(keyframe);
37
+ }
38
+ else {
39
+ /**
40
+ * If we can, we want to commit the final style as set by the user,
41
+ * rather than the computed keyframe value supplied by the animation.
42
+ */
43
+ setStyle(element, name, keyframe);
44
+ }
45
+ this.animation.cancel();
60
46
  }
47
+ this.notifyFinished();
61
48
  };
62
- /**
63
- * TODO: Check for VisualElement before using animation state.
64
- */
65
- animationMap.set(key, this);
66
49
  }
67
50
  play() {
51
+ if (this.isStopped)
52
+ return;
68
53
  this.animation.play();
54
+ if (this.state === "finished") {
55
+ this.updateFinished();
56
+ }
69
57
  }
70
58
  pause() {
71
59
  this.animation.pause();
72
60
  }
73
61
  complete() {
74
- this.animation.finish();
62
+ this.animation.finish?.();
75
63
  }
76
64
  cancel() {
77
65
  try {
78
66
  this.animation.cancel();
79
67
  }
80
68
  catch (e) { }
81
- this.removeAnimation();
82
69
  }
83
70
  stop() {
71
+ if (this.isStopped)
72
+ return;
73
+ this.isStopped = true;
84
74
  const { state } = this;
85
75
  if (state === "idle" || state === "finished") {
86
76
  return;
87
77
  }
88
- this.commitStyles();
89
- this.cancel();
78
+ if (this.updateMotionValue) {
79
+ this.updateMotionValue();
80
+ }
81
+ else {
82
+ this.commitStyles();
83
+ }
84
+ if (!this.isPseudoElement)
85
+ this.cancel();
90
86
  }
91
87
  /**
92
88
  * WAAPI doesn't natively have any interruption capabilities.
@@ -106,13 +102,14 @@ class NativeAnimation {
106
102
  }
107
103
  }
108
104
  get duration() {
109
- const duration = this.animation.effect?.getComputedTiming().duration || 0;
105
+ const duration = this.animation.effect?.getComputedTiming?.().duration || 0;
110
106
  return millisecondsToSeconds(Number(duration));
111
107
  }
112
108
  get time() {
113
109
  return millisecondsToSeconds(Number(this.animation.currentTime) || 0);
114
110
  }
115
111
  set time(newTime) {
112
+ this.finishedTime = null;
116
113
  this.animation.currentTime = secondsToMilliseconds(newTime);
117
114
  }
118
115
  /**
@@ -123,37 +120,37 @@ class NativeAnimation {
123
120
  return this.animation.playbackRate;
124
121
  }
125
122
  set speed(newSpeed) {
123
+ // Allow backwards playback after finishing
124
+ if (newSpeed < 0)
125
+ this.finishedTime = null;
126
126
  this.animation.playbackRate = newSpeed;
127
127
  }
128
128
  get state() {
129
- return this.animation.playState;
129
+ return this.finishedTime !== null
130
+ ? "finished"
131
+ : this.animation.playState;
130
132
  }
131
133
  get startTime() {
132
134
  return Number(this.animation.startTime);
133
135
  }
134
- get finished() {
135
- return this.animation.finished;
136
- }
137
- flatten() {
138
- if (this.allowFlatten) {
139
- this.animation.effect?.updateTiming({ easing: "linear" });
140
- }
136
+ set startTime(newStartTime) {
137
+ this.animation.startTime = newStartTime;
141
138
  }
142
139
  /**
143
140
  * Attaches a timeline to the animation, for instance the `ScrollTimeline`.
144
141
  */
145
- attachTimeline(timeline) {
146
- this.animation.timeline = timeline;
142
+ attachTimeline({ timeline, observe }) {
143
+ if (this.allowFlatten) {
144
+ this.animation.effect?.updateTiming({ easing: "linear" });
145
+ }
147
146
  this.animation.onfinish = null;
148
- return noop;
149
- }
150
- /**
151
- * Allows the animation to be awaited.
152
- *
153
- * @deprecated Use `finished` instead.
154
- */
155
- then(onResolve, onReject) {
156
- return this.finished.then(onResolve).catch(onReject);
147
+ if (supportsScrollTimeline()) {
148
+ this.animation.timeline = timeline;
149
+ return noop;
150
+ }
151
+ else {
152
+ return observe(this);
153
+ }
157
154
  }
158
155
  }
159
156
 
@@ -0,0 +1,65 @@
1
+ import { JSAnimation } from './JSAnimation.mjs';
2
+ import { NativeAnimation } from './NativeAnimation.mjs';
3
+ import { replaceTransitionType } from './utils/replace-transition-type.mjs';
4
+ import { replaceStringEasing } from './waapi/utils/unsupported-easing.mjs';
5
+ import { secondsToMilliseconds } from '../../../../motion-utils/dist/es/time-conversion.mjs';
6
+
7
+ /**
8
+ * 10ms is chosen here as it strikes a balance between smooth
9
+ * results (more than one keyframe per frame at 60fps) and
10
+ * keyframe quantity.
11
+ */
12
+ const sampleDelta = 10; //ms
13
+ class NativeAnimationExtended extends NativeAnimation {
14
+ constructor(options) {
15
+ /**
16
+ * The base NativeAnimation function only supports a subset
17
+ * of Motion easings, and WAAPI also only supports some
18
+ * easing functions via string/cubic-bezier definitions.
19
+ *
20
+ * This function replaces those unsupported easing functions
21
+ * with a JS easing function. This will later get compiled
22
+ * to a linear() easing function.
23
+ */
24
+ replaceStringEasing(options);
25
+ /**
26
+ * Ensure we replace the transition type with a generator function
27
+ * before passing to WAAPI.
28
+ *
29
+ * TODO: Does this have a better home? It could be shared with
30
+ * JSAnimation.
31
+ */
32
+ replaceTransitionType(options);
33
+ super(options);
34
+ if (options.startTime) {
35
+ this.startTime = options.startTime;
36
+ }
37
+ this.options = options;
38
+ }
39
+ /**
40
+ * WAAPI doesn't natively have any interruption capabilities.
41
+ *
42
+ * Rather than read commited styles back out of the DOM, we can
43
+ * create a renderless JS animation and sample it twice to calculate
44
+ * its current value, "previous" value, and therefore allow
45
+ * Motion to calculate velocity for any subsequent animation.
46
+ */
47
+ updateMotionValue(value) {
48
+ const { motionValue, onUpdate, onComplete, element, ...options } = this.options;
49
+ if (!motionValue)
50
+ return;
51
+ if (value !== undefined) {
52
+ motionValue.set(value);
53
+ return;
54
+ }
55
+ const sampleAnimation = new JSAnimation({
56
+ ...options,
57
+ autoplay: false,
58
+ });
59
+ const sampleTime = secondsToMilliseconds(this.finishedTime ?? this.time);
60
+ motionValue.setWithVelocity(sampleAnimation.sample(sampleTime - sampleDelta).value, sampleAnimation.sample(sampleTime).value, sampleDelta);
61
+ sampleAnimation.stop();
62
+ }
63
+ }
64
+
65
+ export { NativeAnimationExtended };
@@ -0,0 +1,14 @@
1
+ import { NativeAnimation } from './NativeAnimation.mjs';
2
+
3
+ class NativeAnimationWrapper extends NativeAnimation {
4
+ constructor(animation) {
5
+ super();
6
+ this.animation = animation;
7
+ animation.onfinish = () => {
8
+ this.finishedTime = this.time;
9
+ this.notifyFinished();
10
+ };
11
+ }
12
+ }
13
+
14
+ export { NativeAnimationWrapper };
@@ -1,5 +1,5 @@
1
- import { frame, cancelFrame, frameData } from '../../../../../../motion-dom/dist/es/frameloop/frame.mjs';
2
- import { time } from '../../../../../../motion-dom/dist/es/frameloop/sync-time.mjs';
1
+ import { time } from '../../frameloop/sync-time.mjs';
2
+ import { frame, cancelFrame, frameData } from '../../frameloop/frame.mjs';
3
3
 
4
4
  const frameloopDriver = (update) => {
5
5
  const passTimestamp = ({ timestamp }) => update(timestamp);
@@ -1,9 +1,9 @@
1
- import { easeInOut } from '../../easing/ease.mjs';
2
- import { isEasingArray } from '../../easing/utils/is-easing-array.mjs';
3
- import { easingDefinitionToFunction } from '../../easing/utils/map.mjs';
4
1
  import { interpolate } from '../../utils/interpolate.mjs';
5
- import { defaultOffset } from '../../utils/offsets/default.mjs';
6
- import { convertOffsetToTimes } from '../../utils/offsets/time.mjs';
2
+ import { defaultOffset } from '../keyframes/offsets/default.mjs';
3
+ import { convertOffsetToTimes } from '../keyframes/offsets/time.mjs';
4
+ import { easeInOut } from '../../../../../motion-utils/dist/es/easing/ease.mjs';
5
+ import { isEasingArray } from '../../../../../motion-utils/dist/es/easing/utils/is-easing-array.mjs';
6
+ import { easingDefinitionToFunction } from '../../../../../motion-utils/dist/es/easing/utils/map.mjs';
7
7
 
8
8
  function defaultEasing(values, easing) {
9
9
  return values.map(() => easing || easeInOut).splice(0, values.length - 1);
@@ -1,7 +1,7 @@
1
- import { clamp } from '../../../utils/clamp.mjs';
2
1
  import { springDefaults } from './defaults.mjs';
3
2
  import { warning } from '../../../../../../motion-utils/dist/es/errors.mjs';
4
3
  import { secondsToMilliseconds, millisecondsToSeconds } from '../../../../../../motion-utils/dist/es/time-conversion.mjs';
4
+ import { clamp } from '../../../../../../motion-utils/dist/es/clamp.mjs';
5
5
 
6
6
  const safeMin = 0.001;
7
7
  function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass, }) {
@@ -1,12 +1,11 @@
1
- import { clamp } from '../../../utils/clamp.mjs';
1
+ import { generateLinearEasing } from '../../waapi/utils/linear.mjs';
2
+ import { calcGeneratorDuration, maxGeneratorDuration } from '../utils/calc-duration.mjs';
3
+ import { createGeneratorEasing } from '../utils/create-generator-easing.mjs';
2
4
  import { calcGeneratorVelocity } from '../utils/velocity.mjs';
3
5
  import { springDefaults } from './defaults.mjs';
4
6
  import { findSpring, calcAngularFreq } from './find.mjs';
5
7
  import { millisecondsToSeconds, secondsToMilliseconds } from '../../../../../../motion-utils/dist/es/time-conversion.mjs';
6
- import { createGeneratorEasing } from '../../../../../../motion-dom/dist/es/animation/generators/utils/create-generator-easing.mjs';
7
- import { supportsLinearEasing } from '../../../../../../motion-dom/dist/es/utils/supports/linear-easing.mjs';
8
- import { calcGeneratorDuration, maxGeneratorDuration } from '../../../../../../motion-dom/dist/es/animation/generators/utils/calc-duration.mjs';
9
- import { generateLinearEasing } from '../../../../../../motion-dom/dist/es/animation/waapi/utils/linear.mjs';
8
+ import { clamp } from '../../../../../../motion-utils/dist/es/clamp.mjs';
10
9
 
11
10
  const durationKeys = ["duration", "bounce"];
12
11
  const physicsKeys = ["stiffness", "damping", "mass"];
@@ -168,7 +167,7 @@ function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce
168
167
  }
169
168
  spring.applyToOptions = (options) => {
170
169
  const generatorOptions = createGeneratorEasing(options, 100, spring);
171
- options.ease = supportsLinearEasing() ? generatorOptions.ease : "easeOut";
170
+ options.ease = generatorOptions.ease;
172
171
  options.duration = secondsToMilliseconds(generatorOptions.duration);
173
172
  options.type = "keyframes";
174
173
  return options;
@@ -1,11 +1,11 @@
1
- import { isNone } from '../../animation/utils/is-none.mjs';
2
- import { positionalKeys } from '../html/utils/keys-position.mjs';
3
- import { makeNoneKeyframesAnimatable } from '../html/utils/make-none-animatable.mjs';
4
- import { KeyframeResolver } from '../utils/KeyframesResolver.mjs';
5
- import { getVariableValue } from './utils/css-variables-conversion.mjs';
6
- import { isCSSVariableToken } from './utils/is-css-variable.mjs';
1
+ import { positionalKeys } from '../../render/utils/keys-position.mjs';
2
+ import { findDimensionValueType } from '../../value/types/dimensions.mjs';
3
+ import { getVariableValue } from '../utils/css-variables-conversion.mjs';
4
+ import { isCSSVariableToken } from '../utils/is-css-variable.mjs';
5
+ import { KeyframeResolver } from './KeyframesResolver.mjs';
6
+ import { isNone } from './utils/is-none.mjs';
7
+ import { makeNoneKeyframesAnimatable } from './utils/make-none-animatable.mjs';
7
8
  import { isNumOrPxType, positionalValues } from './utils/unit-conversion.mjs';
8
- import { findDimensionValueType } from './value-types/dimensions.mjs';
9
9
 
10
10
  class DOMKeyframesResolver extends KeyframeResolver {
11
11
  constructor(unresolvedKeyframes, onComplete, name, motionValue, element) {
@@ -80,7 +80,8 @@ class DOMKeyframesResolver extends KeyframeResolver {
80
80
  const { unresolvedKeyframes, name } = this;
81
81
  const noneKeyframeIndexes = [];
82
82
  for (let i = 0; i < unresolvedKeyframes.length; i++) {
83
- if (isNone(unresolvedKeyframes[i])) {
83
+ if (unresolvedKeyframes[i] === null ||
84
+ isNone(unresolvedKeyframes[i])) {
84
85
  noneKeyframeIndexes.push(i);
85
86
  }
86
87
  }
@@ -1,9 +1,11 @@
1
- import { removeNonTranslationalTransform } from '../dom/utils/unit-conversion.mjs';
2
- import { frame } from '../../../../../motion-dom/dist/es/frameloop/frame.mjs';
1
+ import { fillWildcards } from './utils/fill-wildcards.mjs';
2
+ import { removeNonTranslationalTransform } from './utils/unit-conversion.mjs';
3
+ import { frame } from '../../frameloop/frame.mjs';
3
4
 
4
5
  const toResolve = new Set();
5
6
  let isScheduled = false;
6
7
  let anyNeedsMeasurement = false;
8
+ let isForced = false;
7
9
  function measureAllKeyframes() {
8
10
  if (anyNeedsMeasurement) {
9
11
  const resolversToMeasure = Array.from(toResolve).filter((resolver) => resolver.needsMeasurement);
@@ -43,7 +45,7 @@ function measureAllKeyframes() {
43
45
  }
44
46
  anyNeedsMeasurement = false;
45
47
  isScheduled = false;
46
- toResolve.forEach((resolver) => resolver.complete());
48
+ toResolve.forEach((resolver) => resolver.complete(isForced));
47
49
  toResolve.clear();
48
50
  }
49
51
  function readAllKeyframes() {
@@ -55,8 +57,10 @@ function readAllKeyframes() {
55
57
  });
56
58
  }
57
59
  function flushKeyframeResolvers() {
60
+ isForced = true;
58
61
  readAllKeyframes();
59
62
  measureAllKeyframes();
63
+ isForced = false;
60
64
  }
61
65
  class KeyframeResolver {
62
66
  constructor(unresolvedKeyframes, onComplete, name, motionValue, element, isAsync = false) {
@@ -105,47 +109,36 @@ class KeyframeResolver {
105
109
  }
106
110
  readKeyframes() {
107
111
  const { unresolvedKeyframes, name, element, motionValue } = this;
108
- /**
109
- * If a keyframe is null, we hydrate it either by reading it from
110
- * the instance, or propagating from previous keyframes.
111
- */
112
- for (let i = 0; i < unresolvedKeyframes.length; i++) {
113
- if (unresolvedKeyframes[i] === null) {
114
- /**
115
- * If the first keyframe is null, we need to find its value by sampling the element
116
- */
117
- if (i === 0) {
118
- const currentValue = motionValue?.get();
119
- const finalKeyframe = unresolvedKeyframes[unresolvedKeyframes.length - 1];
120
- if (currentValue !== undefined) {
121
- unresolvedKeyframes[0] = currentValue;
122
- }
123
- else if (element && name) {
124
- const valueAsRead = element.readValue(name, finalKeyframe);
125
- if (valueAsRead !== undefined && valueAsRead !== null) {
126
- unresolvedKeyframes[0] = valueAsRead;
127
- }
128
- }
129
- if (unresolvedKeyframes[0] === undefined) {
130
- unresolvedKeyframes[0] = finalKeyframe;
131
- }
132
- if (motionValue && currentValue === undefined) {
133
- motionValue.set(unresolvedKeyframes[0]);
134
- }
135
- }
136
- else {
137
- unresolvedKeyframes[i] = unresolvedKeyframes[i - 1];
112
+ // If initial keyframe is null we need to read it from the DOM
113
+ if (unresolvedKeyframes[0] === null) {
114
+ const currentValue = motionValue?.get();
115
+ // TODO: This doesn't work if the final keyframe is a wildcard
116
+ const finalKeyframe = unresolvedKeyframes[unresolvedKeyframes.length - 1];
117
+ if (currentValue !== undefined) {
118
+ unresolvedKeyframes[0] = currentValue;
119
+ }
120
+ else if (element && name) {
121
+ const valueAsRead = element.readValue(name, finalKeyframe);
122
+ if (valueAsRead !== undefined && valueAsRead !== null) {
123
+ unresolvedKeyframes[0] = valueAsRead;
138
124
  }
139
125
  }
126
+ if (unresolvedKeyframes[0] === undefined) {
127
+ unresolvedKeyframes[0] = finalKeyframe;
128
+ }
129
+ if (motionValue && currentValue === undefined) {
130
+ motionValue.set(unresolvedKeyframes[0]);
131
+ }
140
132
  }
133
+ fillWildcards(unresolvedKeyframes);
141
134
  }
142
135
  setFinalKeyframe() { }
143
136
  measureInitialState() { }
144
137
  renderEndStyles() { }
145
138
  measureEndState() { }
146
- complete() {
139
+ complete(isForced = false) {
147
140
  this.isComplete = true;
148
- this.onComplete(this.unresolvedKeyframes, this.finalKeyframe);
141
+ this.onComplete(this.unresolvedKeyframes, this.finalKeyframe, isForced);
149
142
  toResolve.delete(this);
150
143
  }
151
144
  cancel() {
@@ -1,9 +1,8 @@
1
1
  const isNotNull = (value) => value !== null;
2
- function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyframe) {
2
+ function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyframe, speed = 1) {
3
3
  const resolvedKeyframes = keyframes.filter(isNotNull);
4
- const index = repeat && repeatType !== "loop" && repeat % 2 === 1
5
- ? 0
6
- : resolvedKeyframes.length - 1;
4
+ const useFirstKeyframe = speed < 0 || (repeat && repeatType !== "loop" && repeat % 2 === 1);
5
+ const index = useFirstKeyframe ? 0 : resolvedKeyframes.length - 1;
7
6
  return !index || finalKeyframe === undefined
8
7
  ? resolvedKeyframes[index]
9
8
  : finalKeyframe;
@@ -1,5 +1,5 @@
1
- import { mixNumber } from '../mix/number.mjs';
2
- import { progress } from '../../../../../motion-utils/dist/es/progress.mjs';
1
+ import { mixNumber } from '../../../utils/mix/number.mjs';
2
+ import { progress } from '../../../../../../motion-utils/dist/es/progress.mjs';
3
3
 
4
4
  function fillOffset(offset, remaining) {
5
5
  const min = offset[offset.length - 1];
@@ -0,0 +1,11 @@
1
+ import { pxValues } from '../../waapi/utils/px-values.mjs';
2
+
3
+ function applyPxDefaults(keyframes, name) {
4
+ for (let i = 0; i < keyframes.length; i++) {
5
+ if (typeof keyframes[i] === "number" && pxValues.has(name)) {
6
+ keyframes[i] = keyframes[i] + "px";
7
+ }
8
+ }
9
+ }
10
+
11
+ export { applyPxDefaults };
@@ -0,0 +1,7 @@
1
+ function fillWildcards(keyframes) {
2
+ for (let i = 1; i < keyframes.length; i++) {
3
+ keyframes[i] ?? (keyframes[i] = keyframes[i - 1]);
4
+ }
5
+ }
6
+
7
+ export { fillWildcards };
@@ -1,4 +1,4 @@
1
- import { isZeroValueString } from '../../utils/is-zero-value-string.mjs';
1
+ import { isZeroValueString } from '../../../../../../motion-utils/dist/es/is-zero-value-string.mjs';
2
2
 
3
3
  function isNone(value) {
4
4
  if (typeof value === "number") {
@@ -1,5 +1,5 @@
1
1
  import { analyseComplexValue } from '../../../value/types/complex/index.mjs';
2
- import { getAnimatableNone } from '../../dom/value-types/animatable-none.mjs';
2
+ import { getAnimatableNone } from '../../../value/types/utils/animatable-none.mjs';
3
3
 
4
4
  /**
5
5
  * If we encounter keyframes like "none" or "0" and we also have keyframes like
@@ -1,7 +1,7 @@
1
+ import { parseValueFromTransform } from '../../../render/dom/parse-transform.mjs';
2
+ import { transformPropOrder } from '../../../render/utils/keys-transform.mjs';
1
3
  import { number } from '../../../value/types/numbers/index.mjs';
2
4
  import { px } from '../../../value/types/numbers/units.mjs';
3
- import { transformPropOrder } from '../../html/utils/keys-transform.mjs';
4
- import { parseValueFromTransform } from '../../html/utils/parse-transform.mjs';
5
5
 
6
6
  const isNumOrPxType = (v) => v === number || v === px;
7
7
  const transformKeys = new Set(["x", "y", "z"]);
@@ -0,0 +1,28 @@
1
+ class WithPromise {
2
+ constructor() {
3
+ this.count = 0;
4
+ this.updateFinished();
5
+ }
6
+ get finished() {
7
+ return this._finished;
8
+ }
9
+ updateFinished() {
10
+ this.count++;
11
+ this._finished = new Promise((resolve) => {
12
+ this.resolve = resolve;
13
+ });
14
+ }
15
+ notifyFinished() {
16
+ this.resolve();
17
+ }
18
+ /**
19
+ * Allows the animation to be awaited.
20
+ *
21
+ * @deprecated Use `finished` instead.
22
+ */
23
+ then(onResolve, onReject) {
24
+ return this.finished.then(onResolve, onReject);
25
+ }
26
+ }
27
+
28
+ export { WithPromise };
@@ -0,0 +1,9 @@
1
+ const animationMaps = new WeakMap();
2
+ const animationMapKey = (name, pseudoElement = "") => `${name}:${pseudoElement}`;
3
+ function getAnimationMap(element) {
4
+ const map = animationMaps.get(element) || new Map();
5
+ animationMaps.set(element, map);
6
+ return map;
7
+ }
8
+
9
+ export { animationMapKey, getAnimationMap };
@@ -1,6 +1,6 @@
1
- import { isAnimatable } from '../../utils/is-animatable.mjs';
2
- import { warning } from '../../../../../../motion-utils/dist/es/errors.mjs';
3
- import { isGenerator } from '../../../../../../motion-dom/dist/es/animation/generators/utils/is-generator.mjs';
1
+ import { isGenerator } from '../generators/utils/is-generator.mjs';
2
+ import { isAnimatable } from './is-animatable.mjs';
3
+ import { warning } from '../../../../../motion-utils/dist/es/errors.mjs';
4
4
 
5
5
  function hasKeyframesChanged(keyframes) {
6
6
  const current = keyframes[0];
@@ -1,6 +1,6 @@
1
- import { isNumericalString } from '../../../utils/is-numerical-string.mjs';
2
1
  import { isCSSVariableToken } from './is-css-variable.mjs';
3
- import { invariant } from '../../../../../../motion-utils/dist/es/errors.mjs';
2
+ import { invariant } from '../../../../../motion-utils/dist/es/errors.mjs';
3
+ import { isNumericalString } from '../../../../../motion-utils/dist/es/is-numerical-string.mjs';
4
4
 
5
5
  /**
6
6
  * Parse Framer's special CSS variable format into a CSS token and a fallback.
@@ -0,0 +1,18 @@
1
+ import { inertia } from '../generators/inertia.mjs';
2
+ import { keyframes } from '../generators/keyframes.mjs';
3
+ import { spring } from '../generators/spring/index.mjs';
4
+
5
+ const transitionTypeMap = {
6
+ decay: inertia,
7
+ inertia,
8
+ tween: keyframes,
9
+ keyframes: keyframes,
10
+ spring,
11
+ };
12
+ function replaceTransitionType(transition) {
13
+ if (typeof transition.type === "string") {
14
+ transition.type = transitionTypeMap[transition.type];
15
+ }
16
+ }
17
+
18
+ export { replaceTransitionType };
@@ -1,6 +1,6 @@
1
- import { isBezierDefinition } from '../../../utils/is-bezier-definition.mjs';
2
1
  import { supportsLinearEasing } from '../../../utils/supports/linear-easing.mjs';
3
2
  import { supportedWaapiEasing } from './supported.mjs';
3
+ import { isBezierDefinition } from '../../../../../../motion-utils/dist/es/easing/utils/is-bezier-definition.mjs';
4
4
 
5
5
  function isWaapiSupportedEasing(easing) {
6
6
  return Boolean((typeof easing === "function" && supportsLinearEasing()) ||