motion 12.7.3 → 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.
- package/README.md +1 -1
- package/dist/cjs/debug.js +22 -14
- package/dist/cjs/index.js +4113 -3624
- package/dist/cjs/mini.js +403 -324
- package/dist/cjs/react-client.js +3151 -3245
- package/dist/cjs/react-m.js +169 -166
- package/dist/cjs/react-mini.js +330 -251
- package/dist/es/framer-motion/dist/es/animation/animate/sequence.mjs +1 -1
- package/dist/es/framer-motion/dist/es/animation/animators/waapi/animate-elements.mjs +81 -9
- package/dist/es/framer-motion/dist/es/animation/interfaces/motion-value.mjs +11 -30
- package/dist/es/framer-motion/dist/es/animation/interfaces/visual-element-target.mjs +1 -1
- package/dist/es/framer-motion/dist/es/animation/optimized-appear/store-id.mjs +1 -1
- package/dist/es/framer-motion/dist/es/animation/sequence/create.mjs +3 -3
- package/dist/es/framer-motion/dist/es/animation/sequence/utils/edit.mjs +2 -2
- package/dist/es/framer-motion/dist/es/animation/utils/default-transitions.mjs +1 -1
- package/dist/es/framer-motion/dist/es/animation/utils/stagger.mjs +1 -1
- package/dist/es/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs +26 -23
- package/dist/es/framer-motion/dist/es/components/Reorder/utils/check-reorder.mjs +1 -1
- package/dist/es/framer-motion/dist/es/gestures/drag/VisualElementDragControls.mjs +2 -2
- package/dist/es/framer-motion/dist/es/gestures/drag/utils/constraints.mjs +2 -2
- package/dist/es/framer-motion/dist/es/gestures/focus.mjs +1 -1
- package/dist/es/framer-motion/dist/es/gestures/pan/PanSession.mjs +1 -1
- package/dist/es/framer-motion/dist/es/motion/utils/is-forced-motion-value.mjs +1 -1
- package/dist/es/framer-motion/dist/es/projection/animation/mix-values.mjs +3 -3
- package/dist/es/framer-motion/dist/es/projection/geometry/delta-apply.mjs +1 -1
- package/dist/es/framer-motion/dist/es/projection/geometry/delta-calc.mjs +1 -1
- package/dist/es/framer-motion/dist/es/projection/geometry/delta-remove.mjs +2 -2
- package/dist/es/framer-motion/dist/es/projection/node/create-projection-node.mjs +3 -5
- package/dist/es/framer-motion/dist/es/projection/styles/scale-border-radius.mjs +1 -1
- package/dist/es/framer-motion/dist/es/projection/styles/scale-box-shadow.mjs +2 -2
- package/dist/es/framer-motion/dist/es/projection/styles/scale-correction.mjs +1 -1
- package/dist/es/framer-motion/dist/es/render/VisualElement.mjs +7 -7
- package/dist/es/framer-motion/dist/es/render/dom/DOMVisualElement.mjs +1 -1
- package/dist/es/framer-motion/dist/es/render/dom/scroll/attach-animation.mjs +17 -0
- package/dist/es/framer-motion/dist/es/render/dom/scroll/attach-function.mjs +23 -0
- package/dist/es/framer-motion/dist/es/render/dom/scroll/index.mjs +6 -82
- package/dist/es/framer-motion/dist/es/render/dom/scroll/offsets/index.mjs +3 -3
- package/dist/es/framer-motion/dist/es/render/dom/scroll/utils/get-timeline.mjs +29 -0
- package/dist/es/framer-motion/dist/es/render/html/HTMLVisualElement.mjs +3 -3
- package/dist/es/framer-motion/dist/es/render/html/utils/build-styles.mjs +4 -4
- package/dist/es/framer-motion/dist/es/render/html/utils/build-transform.mjs +3 -3
- package/dist/es/framer-motion/dist/es/render/svg/SVGVisualElement.mjs +2 -2
- package/dist/es/framer-motion/dist/es/render/svg/config-motion.mjs +1 -1
- package/dist/es/framer-motion/dist/es/render/svg/utils/path.mjs +1 -1
- package/dist/es/framer-motion/dist/es/render/svg/utils/scrape-motion-values.mjs +1 -1
- package/dist/es/framer-motion/dist/es/render/svg/utils/transform-origin.mjs +1 -1
- package/dist/es/framer-motion/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/framer-motion/dist/es/utils/delay.mjs +1 -1
- package/dist/es/framer-motion/dist/es/utils/transform.mjs +1 -1
- package/dist/es/framer-motion/dist/es/utils/use-cycle.mjs +1 -1
- package/dist/es/framer-motion/dist/es/utils/use-instant-transition.mjs +4 -4
- package/dist/es/framer-motion/dist/es/value/use-spring.mjs +2 -2
- package/dist/es/framer-motion/dist/es/value/use-will-change/get-will-change-name.mjs +2 -2
- package/dist/es/motion/lib/index.mjs +109 -26
- package/dist/es/motion/lib/react.mjs +108 -32
- package/dist/es/motion-dom/dist/es/animation/AsyncMotionValueAnimation.mjs +179 -0
- package/dist/es/motion-dom/dist/es/animation/GroupAnimation.mjs +6 -15
- package/dist/es/{framer-motion/dist/es/animation/animators/MainThreadAnimation.mjs → motion-dom/dist/es/animation/JSAnimation.mjs} +108 -156
- package/dist/es/motion-dom/dist/es/animation/NativeAnimation.mjs +64 -67
- package/dist/es/motion-dom/dist/es/animation/NativeAnimationExtended.mjs +65 -0
- package/dist/es/motion-dom/dist/es/animation/NativeAnimationWrapper.mjs +14 -0
- package/dist/es/{framer-motion/dist/es/animation/animators → motion-dom/dist/es/animation}/drivers/driver-frameloop.mjs +2 -2
- package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/keyframes.mjs +5 -5
- package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/spring/find.mjs +1 -1
- package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/spring/index.mjs +5 -6
- package/dist/es/{framer-motion/dist/es/render/dom → motion-dom/dist/es/animation/keyframes}/DOMKeyframesResolver.mjs +9 -8
- package/dist/es/{framer-motion/dist/es/render/utils → motion-dom/dist/es/animation/keyframes}/KeyframesResolver.mjs +28 -35
- package/dist/es/motion-dom/dist/es/animation/keyframes/get-final.mjs +3 -4
- package/dist/es/{framer-motion/dist/es/utils → motion-dom/dist/es/animation/keyframes}/offsets/fill.mjs +2 -2
- package/dist/es/motion-dom/dist/es/animation/keyframes/utils/apply-px-defaults.mjs +11 -0
- package/dist/es/motion-dom/dist/es/animation/keyframes/utils/fill-wildcards.mjs +7 -0
- package/dist/es/{framer-motion/dist/es/animation → motion-dom/dist/es/animation/keyframes}/utils/is-none.mjs +1 -1
- package/dist/es/{framer-motion/dist/es/render/html → motion-dom/dist/es/animation/keyframes}/utils/make-none-animatable.mjs +1 -1
- package/dist/es/{framer-motion/dist/es/render/dom → motion-dom/dist/es/animation/keyframes}/utils/unit-conversion.mjs +2 -2
- package/dist/es/motion-dom/dist/es/animation/utils/WithPromise.mjs +28 -0
- package/dist/es/motion-dom/dist/es/animation/utils/active-animations.mjs +9 -0
- package/dist/es/{framer-motion/dist/es/animation/animators → motion-dom/dist/es/animation}/utils/can-animate.mjs +3 -3
- package/dist/es/{framer-motion/dist/es/render/dom → motion-dom/dist/es/animation}/utils/css-variables-conversion.mjs +2 -2
- package/dist/es/motion-dom/dist/es/animation/utils/replace-transition-type.mjs +18 -0
- package/dist/es/motion-dom/dist/es/animation/waapi/easing/is-supported.mjs +1 -1
- package/dist/es/motion-dom/dist/es/animation/waapi/easing/map-easing.mjs +5 -3
- package/dist/es/motion-dom/dist/es/animation/waapi/start-waapi-animation.mjs +6 -4
- package/dist/es/motion-dom/dist/es/animation/waapi/supports/waapi.mjs +39 -0
- package/dist/es/motion-dom/dist/es/animation/waapi/utils/apply-generator.mjs +2 -1
- package/dist/es/motion-dom/dist/es/animation/waapi/utils/unsupported-easing.mjs +20 -0
- package/dist/es/motion-dom/dist/es/frameloop/batcher.mjs +2 -1
- package/dist/es/motion-dom/dist/es/frameloop/order.mjs +1 -0
- package/dist/es/motion-dom/dist/es/render/dom/is-css-var.mjs +3 -0
- package/dist/es/motion-dom/dist/es/render/dom/style-computed.mjs +10 -0
- package/dist/es/motion-dom/dist/es/render/dom/style-set.mjs +9 -0
- package/dist/es/{framer-motion/dist/es/render/html → motion-dom/dist/es/render}/utils/keys-transform.mjs +1 -1
- package/dist/es/{framer-motion/dist/es/render/dom → motion-dom/dist/es}/scroll/observe.mjs +1 -1
- package/dist/es/motion-dom/dist/es/stats/index.mjs +2 -0
- package/dist/es/{framer-motion → motion-dom}/dist/es/utils/interpolate.mjs +4 -3
- package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/color.mjs +3 -3
- package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/complex.mjs +5 -5
- package/dist/es/motion-dom/dist/es/value/index.mjs +3 -1
- package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/color/rgba.mjs +2 -2
- package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types}/dimensions.mjs +3 -3
- package/dist/es/{framer-motion/dist/es/render/dom/value-types/type-int.mjs → motion-dom/dist/es/value/types/int.mjs} +1 -1
- package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types/maps}/defaults.mjs +2 -2
- 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
- package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types/maps}/transform.mjs +2 -2
- package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/numbers/index.mjs +1 -1
- package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/numbers/units.mjs +3 -2
- package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types/utils}/animatable-none.mjs +4 -4
- package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types/utils}/find.mjs +4 -4
- package/dist/es/motion-dom/dist/es/view/index.mjs +64 -0
- package/dist/es/motion-dom/dist/es/view/queue.mjs +52 -0
- package/dist/es/motion-dom/dist/es/view/start.mjs +155 -0
- package/dist/es/motion-dom/dist/es/view/utils/choose-layer-type.mjs +11 -0
- package/dist/es/motion-dom/dist/es/view/utils/css.mjs +32 -0
- package/dist/es/motion-dom/dist/es/view/utils/get-layer-name.mjs +8 -0
- package/dist/es/motion-dom/dist/es/view/utils/get-view-animations.mjs +12 -0
- package/dist/es/motion-dom/dist/es/view/utils/has-target.mjs +5 -0
- package/dist/es/{framer-motion → motion-utils}/dist/es/easing/cubic-bezier.mjs +1 -1
- package/dist/es/{framer-motion → motion-utils}/dist/es/easing/steps.mjs +1 -1
- package/dist/es/{framer-motion → motion-utils}/dist/es/easing/utils/get-easing-for-segment.mjs +1 -1
- package/dist/es/{framer-motion → motion-utils}/dist/es/easing/utils/map.mjs +7 -4
- package/dist/es/motion-utils/dist/es/global-config.mjs +1 -4
- package/dist/es/motion-utils/dist/es/warn-once.mjs +4 -1
- package/dist/motion.dev.js +4108 -3619
- package/dist/motion.js +1 -1
- package/package.json +3 -3
- package/dist/es/framer-motion/dist/es/animation/animators/AcceleratedAnimation.mjs +0 -324
- package/dist/es/framer-motion/dist/es/animation/animators/BaseAnimation.mjs +0 -120
- package/dist/es/framer-motion/dist/es/animation/animators/waapi/utils/supports-waapi.mjs +0 -5
- package/dist/es/framer-motion/dist/es/render/dom/value-types/number.mjs +0 -18
- package/dist/es/framer-motion/dist/es/utils/use-instant-transition-state.mjs +0 -5
- package/dist/es/motion-dom/dist/es/animation/keyframes/hydrate.mjs +0 -26
- package/dist/es/motion-dom/dist/es/animation/waapi/utils/attach-timeline.mjs +0 -6
- package/dist/es/motion-dom/dist/es/render/dom/style.mjs +0 -15
- /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/inertia.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/spring/defaults.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/utils/velocity.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/utils → motion-dom/dist/es/animation/keyframes}/offsets/default.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/utils → motion-dom/dist/es/animation/keyframes}/offsets/time.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/utils/is-animatable.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/render/dom → motion-dom/dist/es/animation}/utils/is-css-variable.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/animation/animators → motion-dom/dist/es/animation/waapi}/utils/accelerated-values.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/render/html/utils → motion-dom/dist/es/render/dom}/parse-transform.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/render/html → motion-dom/dist/es/render}/utils/keys-position.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/immediate.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/index.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/number.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/utils/mix/visibility.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/render/dom/value-types/type-auto.mjs → motion-dom/dist/es/value/types/auto.mjs} +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/color/hex.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/utils → motion-dom/dist/es/value/types/color}/hsla-to-rgba.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/color/hsla.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/color/index.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/color/utils.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/complex/filter.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/complex/index.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types}/test.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/utils/color-regex.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/utils/float-regex.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/render/dom/value-types → motion-dom/dist/es/value/types/utils}/get-as-type.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/utils/is-nullish.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/utils/sanitize.mjs +0 -0
- /package/dist/es/{framer-motion → motion-dom}/dist/es/value/types/utils/single-color-regex.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/clamp.mjs +0 -0
- /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/anticipate.mjs +0 -0
- /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/back.mjs +0 -0
- /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/circ.mjs +0 -0
- /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/ease.mjs +0 -0
- /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/modifiers/mirror.mjs +0 -0
- /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/modifiers/reverse.mjs +0 -0
- /package/dist/es/{motion-dom/dist/es → motion-utils/dist/es/easing}/utils/is-bezier-definition.mjs +0 -0
- /package/dist/es/{framer-motion → motion-utils}/dist/es/easing/utils/is-easing-array.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/is-numerical-string.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/is-zero-value-string.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/pipe.mjs +0 -0
- /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/wrap.mjs +0 -0
|
@@ -1,68 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { mix } from '
|
|
4
|
-
import { pipe } from '../../utils/pipe.mjs';
|
|
5
|
-
import { inertia } from '../generators/inertia.mjs';
|
|
6
|
-
import { keyframes } from '../generators/keyframes.mjs';
|
|
7
|
-
import { spring } from '../generators/spring/index.mjs';
|
|
8
|
-
import { BaseAnimation } from './BaseAnimation.mjs';
|
|
1
|
+
import { time } from '../frameloop/sync-time.mjs';
|
|
2
|
+
import { activeAnimations } from '../stats/animation-count.mjs';
|
|
3
|
+
import { mix } from '../utils/mix/index.mjs';
|
|
9
4
|
import { frameloopDriver } from './drivers/driver-frameloop.mjs';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { calcGeneratorDuration } from '
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
5
|
+
import { inertia } from './generators/inertia.mjs';
|
|
6
|
+
import { keyframes } from './generators/keyframes.mjs';
|
|
7
|
+
import { calcGeneratorDuration } from './generators/utils/calc-duration.mjs';
|
|
8
|
+
import { getFinalKeyframe } from './keyframes/get-final.mjs';
|
|
9
|
+
import { replaceTransitionType } from './utils/replace-transition-type.mjs';
|
|
10
|
+
import { WithPromise } from './utils/WithPromise.mjs';
|
|
11
|
+
import { invariant } from '../../../../motion-utils/dist/es/errors.mjs';
|
|
12
|
+
import { pipe } from '../../../../motion-utils/dist/es/pipe.mjs';
|
|
13
|
+
import { millisecondsToSeconds, secondsToMilliseconds } from '../../../../motion-utils/dist/es/time-conversion.mjs';
|
|
14
|
+
import { clamp } from '../../../../motion-utils/dist/es/clamp.mjs';
|
|
16
15
|
|
|
17
|
-
const generators = {
|
|
18
|
-
decay: inertia,
|
|
19
|
-
inertia,
|
|
20
|
-
tween: keyframes,
|
|
21
|
-
keyframes: keyframes,
|
|
22
|
-
spring,
|
|
23
|
-
};
|
|
24
16
|
const percentToProgress = (percent) => percent / 100;
|
|
25
|
-
|
|
26
|
-
* Animation that runs on the main thread. Designed to be WAAPI-spec in the subset of
|
|
27
|
-
* features we expose publically. Mostly the compatibility is to ensure visual identity
|
|
28
|
-
* between both WAAPI and main thread animations.
|
|
29
|
-
*/
|
|
30
|
-
class MainThreadAnimation extends BaseAnimation {
|
|
17
|
+
class JSAnimation extends WithPromise {
|
|
31
18
|
constructor(options) {
|
|
32
|
-
super(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
this.holdTime = null;
|
|
37
|
-
/**
|
|
38
|
-
* The time at which the animation was cancelled.
|
|
39
|
-
*/
|
|
40
|
-
this.cancelTime = null;
|
|
19
|
+
super();
|
|
20
|
+
this.state = "idle";
|
|
21
|
+
this.startTime = null;
|
|
22
|
+
this.isStopped = false;
|
|
41
23
|
/**
|
|
42
24
|
* The current time of the animation.
|
|
43
25
|
*/
|
|
44
26
|
this.currentTime = 0;
|
|
45
27
|
/**
|
|
46
|
-
*
|
|
47
|
-
*/
|
|
48
|
-
this.playbackSpeed = 1;
|
|
49
|
-
/**
|
|
50
|
-
* The state of the animation to apply when the animation is resolved. This
|
|
51
|
-
* allows calls to the public API to control the animation before it is resolved,
|
|
52
|
-
* without us having to resolve it first.
|
|
28
|
+
* The time at which the animation was paused.
|
|
53
29
|
*/
|
|
54
|
-
this.
|
|
30
|
+
this.holdTime = null;
|
|
55
31
|
/**
|
|
56
|
-
*
|
|
32
|
+
* Playback speed as a factor. 0 would be stopped, -1 reverse and 2 double speed.
|
|
57
33
|
*/
|
|
58
|
-
this.
|
|
59
|
-
this.state = "idle";
|
|
34
|
+
this.playbackSpeed = 1;
|
|
60
35
|
/**
|
|
61
36
|
* This method is bound to the instance to fix a pattern where
|
|
62
37
|
* animation.stop is returned as a reference from a useEffect.
|
|
63
38
|
*/
|
|
64
39
|
this.stop = () => {
|
|
65
|
-
this.
|
|
40
|
+
const { motionValue } = this.options;
|
|
41
|
+
if (motionValue && motionValue.updatedAt !== time.now()) {
|
|
42
|
+
this.tick(time.now());
|
|
43
|
+
}
|
|
66
44
|
this.isStopped = true;
|
|
67
45
|
if (this.state === "idle")
|
|
68
46
|
return;
|
|
@@ -70,49 +48,36 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
70
48
|
const { onStop } = this.options;
|
|
71
49
|
onStop && onStop();
|
|
72
50
|
};
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
this.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
flatten() {
|
|
80
|
-
super.flatten();
|
|
81
|
-
// If we've already resolved the animation, re-initialise it
|
|
82
|
-
if (this._resolved) {
|
|
83
|
-
Object.assign(this._resolved, this.initPlayback(this._resolved.keyframes));
|
|
84
|
-
}
|
|
51
|
+
activeAnimations.mainThread++;
|
|
52
|
+
this.options = options;
|
|
53
|
+
this.initAnimation();
|
|
54
|
+
this.play();
|
|
55
|
+
if (options.autoplay === false)
|
|
56
|
+
this.pause();
|
|
85
57
|
}
|
|
86
|
-
|
|
87
|
-
const {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
* If our generator doesn't support mixing numbers, we need to replace keyframes with
|
|
93
|
-
* [0, 100] and then make a function that maps that to the actual keyframes.
|
|
94
|
-
*
|
|
95
|
-
* 100 is chosen instead of 1 as it works nicer with spring animations.
|
|
96
|
-
*/
|
|
97
|
-
let mapPercentToKeyframes;
|
|
98
|
-
let mirroredGenerator;
|
|
58
|
+
initAnimation() {
|
|
59
|
+
const { options } = this;
|
|
60
|
+
replaceTransitionType(options);
|
|
61
|
+
const { type = keyframes, repeat = 0, repeatDelay = 0, repeatType, velocity = 0, } = options;
|
|
62
|
+
let { keyframes: keyframes$1 } = options;
|
|
63
|
+
const generatorFactory = type || keyframes;
|
|
99
64
|
if (process.env.NODE_ENV !== "production" &&
|
|
100
65
|
generatorFactory !== keyframes) {
|
|
101
66
|
invariant(keyframes$1.length <= 2, `Only two keyframes currently supported with spring and inertia animations. Trying to animate ${keyframes$1}`);
|
|
102
67
|
}
|
|
103
68
|
if (generatorFactory !== keyframes &&
|
|
104
69
|
typeof keyframes$1[0] !== "number") {
|
|
105
|
-
|
|
70
|
+
this.mixKeyframes = pipe(percentToProgress, mix(keyframes$1[0], keyframes$1[1]));
|
|
106
71
|
keyframes$1 = [0, 100];
|
|
107
72
|
}
|
|
108
|
-
const generator = generatorFactory({ ...
|
|
73
|
+
const generator = generatorFactory({ ...options, keyframes: keyframes$1 });
|
|
109
74
|
/**
|
|
110
75
|
* If we have a mirror repeat type we need to create a second generator that outputs the
|
|
111
76
|
* mirrored (not reversed) animation and later ping pong between the two generators.
|
|
112
77
|
*/
|
|
113
78
|
if (repeatType === "mirror") {
|
|
114
|
-
mirroredGenerator = generatorFactory({
|
|
115
|
-
...
|
|
79
|
+
this.mirroredGenerator = generatorFactory({
|
|
80
|
+
...options,
|
|
116
81
|
keyframes: [...keyframes$1].reverse(),
|
|
117
82
|
velocity: -velocity,
|
|
118
83
|
});
|
|
@@ -129,39 +94,29 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
129
94
|
generator.calculatedDuration = calcGeneratorDuration(generator);
|
|
130
95
|
}
|
|
131
96
|
const { calculatedDuration } = generator;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
mirroredGenerator,
|
|
137
|
-
mapPercentToKeyframes,
|
|
138
|
-
calculatedDuration,
|
|
139
|
-
resolvedDuration,
|
|
140
|
-
totalDuration,
|
|
141
|
-
};
|
|
97
|
+
this.calculatedDuration = calculatedDuration;
|
|
98
|
+
this.resolvedDuration = calculatedDuration + repeatDelay;
|
|
99
|
+
this.totalDuration = this.resolvedDuration * (repeat + 1) - repeatDelay;
|
|
100
|
+
this.generator = generator;
|
|
142
101
|
}
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
this.
|
|
147
|
-
|
|
148
|
-
this.pause();
|
|
102
|
+
updateTime(timestamp) {
|
|
103
|
+
const animationTime = Math.round(timestamp - this.startTime) * this.playbackSpeed;
|
|
104
|
+
// Update currentTime
|
|
105
|
+
if (this.holdTime !== null) {
|
|
106
|
+
this.currentTime = this.holdTime;
|
|
149
107
|
}
|
|
150
108
|
else {
|
|
151
|
-
|
|
109
|
+
// Rounding the time because floating point arithmetic is not always accurate, e.g. 3000.367 - 1000.367 =
|
|
110
|
+
// 2000.0000000000002. This is a problem when we are comparing the currentTime with the duration, for
|
|
111
|
+
// example.
|
|
112
|
+
this.currentTime = animationTime;
|
|
152
113
|
}
|
|
153
114
|
}
|
|
154
115
|
tick(timestamp, sample = false) {
|
|
155
|
-
const {
|
|
156
|
-
// If the animations has failed to resolve, return the final keyframe.
|
|
157
|
-
if (!resolved) {
|
|
158
|
-
const { keyframes } = this.options;
|
|
159
|
-
return { done: true, value: keyframes[keyframes.length - 1] };
|
|
160
|
-
}
|
|
161
|
-
const { finalKeyframe, generator, mirroredGenerator, mapPercentToKeyframes, keyframes, calculatedDuration, totalDuration, resolvedDuration, } = resolved;
|
|
116
|
+
const { generator, totalDuration, mixKeyframes, mirroredGenerator, resolvedDuration, calculatedDuration, } = this;
|
|
162
117
|
if (this.startTime === null)
|
|
163
118
|
return generator.next(0);
|
|
164
|
-
const { delay, repeat, repeatType, repeatDelay, onUpdate } = this.options;
|
|
119
|
+
const { delay = 0, keyframes, repeat, repeatType, repeatDelay, type, onUpdate, finalKeyframe, } = this.options;
|
|
165
120
|
/**
|
|
166
121
|
* requestAnimationFrame timestamps can come through as lower than
|
|
167
122
|
* the startTime as set by performance.now(). Here we prevent this,
|
|
@@ -174,23 +129,15 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
174
129
|
else if (this.speed < 0) {
|
|
175
130
|
this.startTime = Math.min(timestamp - totalDuration / this.speed, this.startTime);
|
|
176
131
|
}
|
|
177
|
-
// Update currentTime
|
|
178
132
|
if (sample) {
|
|
179
133
|
this.currentTime = timestamp;
|
|
180
134
|
}
|
|
181
|
-
else if (this.holdTime !== null) {
|
|
182
|
-
this.currentTime = this.holdTime;
|
|
183
|
-
}
|
|
184
135
|
else {
|
|
185
|
-
|
|
186
|
-
// 2000.0000000000002. This is a problem when we are comparing the currentTime with the duration, for
|
|
187
|
-
// example.
|
|
188
|
-
this.currentTime =
|
|
189
|
-
Math.round(timestamp - this.startTime) * this.speed;
|
|
136
|
+
this.updateTime(timestamp);
|
|
190
137
|
}
|
|
191
138
|
// Rebase on delay
|
|
192
|
-
const timeWithoutDelay = this.currentTime - delay * (this.
|
|
193
|
-
const isInDelayPhase = this.
|
|
139
|
+
const timeWithoutDelay = this.currentTime - delay * (this.playbackSpeed >= 0 ? 1 : -1);
|
|
140
|
+
const isInDelayPhase = this.playbackSpeed >= 0
|
|
194
141
|
? timeWithoutDelay < 0
|
|
195
142
|
: timeWithoutDelay > totalDuration;
|
|
196
143
|
this.currentTime = Math.max(timeWithoutDelay, 0);
|
|
@@ -251,20 +198,21 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
251
198
|
const state = isInDelayPhase
|
|
252
199
|
? { done: false, value: keyframes[0] }
|
|
253
200
|
: frameGenerator.next(elapsed);
|
|
254
|
-
if (
|
|
255
|
-
state.value =
|
|
201
|
+
if (mixKeyframes) {
|
|
202
|
+
state.value = mixKeyframes(state.value);
|
|
256
203
|
}
|
|
257
204
|
let { done } = state;
|
|
258
205
|
if (!isInDelayPhase && calculatedDuration !== null) {
|
|
259
206
|
done =
|
|
260
|
-
this.
|
|
207
|
+
this.playbackSpeed >= 0
|
|
261
208
|
? this.currentTime >= totalDuration
|
|
262
209
|
: this.currentTime <= 0;
|
|
263
210
|
}
|
|
264
211
|
const isAnimationFinished = this.holdTime === null &&
|
|
265
212
|
(this.state === "finished" || (this.state === "running" && done));
|
|
266
|
-
|
|
267
|
-
|
|
213
|
+
// TODO: The exception for inertia could be cleaner here
|
|
214
|
+
if (isAnimationFinished && type !== inertia) {
|
|
215
|
+
state.value = getFinalKeyframe(keyframes, this.options, finalKeyframe, this.speed);
|
|
268
216
|
}
|
|
269
217
|
if (onUpdate) {
|
|
270
218
|
onUpdate(state.value);
|
|
@@ -274,9 +222,16 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
274
222
|
}
|
|
275
223
|
return state;
|
|
276
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* Allows the returned animation to be awaited or promise-chained. Currently
|
|
227
|
+
* resolves when the animation finishes at all but in a future update could/should
|
|
228
|
+
* reject if its cancels.
|
|
229
|
+
*/
|
|
230
|
+
then(resolve, reject) {
|
|
231
|
+
return this.finished.then(resolve, reject);
|
|
232
|
+
}
|
|
277
233
|
get duration() {
|
|
278
|
-
|
|
279
|
-
return resolved ? millisecondsToSeconds(resolved.calculatedDuration) : 0;
|
|
234
|
+
return millisecondsToSeconds(this.calculatedDuration);
|
|
280
235
|
}
|
|
281
236
|
get time() {
|
|
282
237
|
return millisecondsToSeconds(this.currentTime);
|
|
@@ -284,17 +239,20 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
284
239
|
set time(newTime) {
|
|
285
240
|
newTime = secondsToMilliseconds(newTime);
|
|
286
241
|
this.currentTime = newTime;
|
|
287
|
-
if (this.
|
|
242
|
+
if (this.startTime === null ||
|
|
243
|
+
this.holdTime !== null ||
|
|
244
|
+
this.playbackSpeed === 0) {
|
|
288
245
|
this.holdTime = newTime;
|
|
289
246
|
}
|
|
290
247
|
else if (this.driver) {
|
|
291
|
-
this.startTime = this.driver.now() - newTime / this.
|
|
248
|
+
this.startTime = this.driver.now() - newTime / this.playbackSpeed;
|
|
292
249
|
}
|
|
293
250
|
}
|
|
294
251
|
get speed() {
|
|
295
252
|
return this.playbackSpeed;
|
|
296
253
|
}
|
|
297
254
|
set speed(newSpeed) {
|
|
255
|
+
this.updateTime(time.now());
|
|
298
256
|
const hasChanged = this.playbackSpeed !== newSpeed;
|
|
299
257
|
this.playbackSpeed = newSpeed;
|
|
300
258
|
if (hasChanged) {
|
|
@@ -302,13 +260,6 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
302
260
|
}
|
|
303
261
|
}
|
|
304
262
|
play() {
|
|
305
|
-
if (!this.resolver.isScheduled) {
|
|
306
|
-
this.resolver.resume();
|
|
307
|
-
}
|
|
308
|
-
if (!this._resolved) {
|
|
309
|
-
this.pendingPlayState = "running";
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
263
|
if (this.isStopped)
|
|
313
264
|
return;
|
|
314
265
|
const { driver = frameloopDriver, onPlay, startTime } = this.options;
|
|
@@ -320,16 +271,17 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
320
271
|
if (this.holdTime !== null) {
|
|
321
272
|
this.startTime = now - this.holdTime;
|
|
322
273
|
}
|
|
323
|
-
else if (!this.startTime) {
|
|
324
|
-
this.startTime = startTime ?? this.calcStartTime();
|
|
325
|
-
}
|
|
326
274
|
else if (this.state === "finished") {
|
|
275
|
+
console.log("JSAnimation updateFinished");
|
|
276
|
+
this.updateFinished();
|
|
327
277
|
this.startTime = now;
|
|
328
278
|
}
|
|
329
|
-
if (this.
|
|
330
|
-
this.
|
|
279
|
+
else if (!this.startTime) {
|
|
280
|
+
this.startTime = startTime ?? now;
|
|
281
|
+
}
|
|
282
|
+
if (this.state === "finished" && this.speed < 0) {
|
|
283
|
+
this.startTime += this.calculatedDuration;
|
|
331
284
|
}
|
|
332
|
-
this.cancelTime = this.startTime;
|
|
333
285
|
this.holdTime = null;
|
|
334
286
|
/**
|
|
335
287
|
* Set playState to running only after we've used it in
|
|
@@ -339,40 +291,34 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
339
291
|
this.driver.start();
|
|
340
292
|
}
|
|
341
293
|
pause() {
|
|
342
|
-
if (!this._resolved) {
|
|
343
|
-
this.pendingPlayState = "paused";
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
294
|
this.state = "paused";
|
|
347
|
-
this.
|
|
295
|
+
this.updateTime(time.now());
|
|
296
|
+
this.holdTime = this.currentTime;
|
|
348
297
|
}
|
|
349
298
|
complete() {
|
|
350
299
|
if (this.state !== "running") {
|
|
351
300
|
this.play();
|
|
352
301
|
}
|
|
353
|
-
this.
|
|
302
|
+
this.state = "finished";
|
|
354
303
|
this.holdTime = null;
|
|
355
304
|
}
|
|
356
305
|
finish() {
|
|
306
|
+
this.notifyFinished();
|
|
357
307
|
this.teardown();
|
|
358
308
|
this.state = "finished";
|
|
359
309
|
const { onComplete } = this.options;
|
|
360
310
|
onComplete && onComplete();
|
|
361
311
|
}
|
|
362
312
|
cancel() {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
313
|
+
this.holdTime = null;
|
|
314
|
+
this.startTime = 0;
|
|
315
|
+
this.tick(0);
|
|
366
316
|
this.teardown();
|
|
367
|
-
this.updateFinishedPromise();
|
|
368
317
|
}
|
|
369
318
|
teardown() {
|
|
370
319
|
this.state = "idle";
|
|
371
320
|
this.stopDriver();
|
|
372
|
-
this.
|
|
373
|
-
this.updateFinishedPromise();
|
|
374
|
-
this.startTime = this.cancelTime = null;
|
|
375
|
-
this.resolver.cancel();
|
|
321
|
+
this.startTime = this.holdTime = null;
|
|
376
322
|
activeAnimations.mainThread--;
|
|
377
323
|
}
|
|
378
324
|
stopDriver() {
|
|
@@ -381,17 +327,23 @@ class MainThreadAnimation extends BaseAnimation {
|
|
|
381
327
|
this.driver.stop();
|
|
382
328
|
this.driver = undefined;
|
|
383
329
|
}
|
|
384
|
-
sample(
|
|
330
|
+
sample(sampleTime) {
|
|
385
331
|
this.startTime = 0;
|
|
386
|
-
return this.tick(
|
|
332
|
+
return this.tick(sampleTime, true);
|
|
387
333
|
}
|
|
388
|
-
|
|
389
|
-
|
|
334
|
+
attachTimeline(timeline) {
|
|
335
|
+
this.pause();
|
|
336
|
+
if (this.options.allowFlatten) {
|
|
337
|
+
this.options.type = "keyframes";
|
|
338
|
+
this.options.ease = "linear";
|
|
339
|
+
this.initAnimation();
|
|
340
|
+
}
|
|
341
|
+
return timeline.observe(this);
|
|
390
342
|
}
|
|
391
343
|
}
|
|
392
|
-
// Legacy
|
|
344
|
+
// Legacy function support
|
|
393
345
|
function animateValue(options) {
|
|
394
|
-
return new
|
|
346
|
+
return new JSAnimation(options);
|
|
395
347
|
}
|
|
396
348
|
|
|
397
|
-
export {
|
|
349
|
+
export { JSAnimation, animateValue };
|
|
@@ -1,92 +1,88 @@
|
|
|
1
|
-
import {
|
|
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 {
|
|
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
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
59
|
-
this.
|
|
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.
|
|
89
|
-
|
|
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.
|
|
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
|
-
|
|
135
|
-
|
|
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.
|
|
142
|
+
attachTimeline({ timeline, observe }) {
|
|
143
|
+
if (this.allowFlatten) {
|
|
144
|
+
this.animation.effect?.updateTiming({ easing: "linear" });
|
|
145
|
+
}
|
|
147
146
|
this.animation.onfinish = null;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
|