| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- import { getValueTransition, frame, GroupAnimationWithThen } from 'motion-dom';
- import { secondsToMilliseconds, MotionGlobalConfig } from 'motion-utils';
- import { instantAnimationState } from '../../utils/use-instant-transition-state.mjs';
- import { AcceleratedAnimation } from '../animators/AcceleratedAnimation.mjs';
- import { MainThreadAnimation } from '../animators/MainThreadAnimation.mjs';
- import { getFinalKeyframe } from '../animators/waapi/utils/get-final-keyframe.mjs';
- import { getDefaultTransition } from '../utils/default-transitions.mjs';
- import { isTransitionDefined } from '../utils/is-transition-defined.mjs';
- const animateMotionValue = (name, value, target, transition = {}, element, isHandoff) => (onComplete) => {
- const valueTransition = getValueTransition(transition, name) || {};
- /**
- * Most transition values are currently completely overwritten by value-specific
- * transitions. In the future it'd be nicer to blend these transitions. But for now
- * delay actually does inherit from the root transition if not value-specific.
- */
- const delay = valueTransition.delay || transition.delay || 0;
- /**
- * Elapsed isn't a public transition option but can be passed through from
- * optimized appear effects in milliseconds.
- */
- let { elapsed = 0 } = transition;
- elapsed = elapsed - secondsToMilliseconds(delay);
- let options = {
- keyframes: Array.isArray(target) ? target : [null, target],
- ease: "easeOut",
- velocity: value.getVelocity(),
- ...valueTransition,
- delay: -elapsed,
- onUpdate: (v) => {
- value.set(v);
- valueTransition.onUpdate && valueTransition.onUpdate(v);
- },
- onComplete: () => {
- onComplete();
- valueTransition.onComplete && valueTransition.onComplete();
- },
- name,
- motionValue: value,
- element: isHandoff ? undefined : element,
- };
- /**
- * If there's no transition defined for this value, we can generate
- * unique transition settings for this value.
- */
- if (!isTransitionDefined(valueTransition)) {
- options = {
- ...options,
- ...getDefaultTransition(name, options),
- };
- }
- /**
- * Both WAAPI and our internal animation functions use durations
- * as defined by milliseconds, while our external API defines them
- * as seconds.
- */
- if (options.duration) {
- options.duration = secondsToMilliseconds(options.duration);
- }
- if (options.repeatDelay) {
- options.repeatDelay = secondsToMilliseconds(options.repeatDelay);
- }
- if (options.from !== undefined) {
- options.keyframes[0] = options.from;
- }
- let shouldSkip = false;
- if (options.type === false ||
- (options.duration === 0 && !options.repeatDelay)) {
- options.duration = 0;
- if (options.delay === 0) {
- shouldSkip = true;
- }
- }
- if (instantAnimationState.current ||
- MotionGlobalConfig.skipAnimations) {
- shouldSkip = true;
- options.duration = 0;
- options.delay = 0;
- }
- /**
- * If the transition type or easing has been explicitly set by the user
- * then we don't want to allow flattening the animation.
- */
- options.allowFlatten = !valueTransition.type && !valueTransition.ease;
- /**
- * If we can or must skip creating the animation, and apply only
- * the final keyframe, do so. We also check once keyframes are resolved but
- * this early check prevents the need to create an animation at all.
- */
- if (shouldSkip && !isHandoff && value.get() !== undefined) {
- const finalKeyframe = getFinalKeyframe(options.keyframes, valueTransition);
- if (finalKeyframe !== undefined) {
- frame.update(() => {
- options.onUpdate(finalKeyframe);
- options.onComplete();
- });
- // We still want to return some animation controls here rather
- // than returning undefined
- return new GroupAnimationWithThen([]);
- }
- }
- /**
- * Animate via WAAPI if possible. If this is a handoff animation, the optimised animation will be running via
- * WAAPI. Therefore, this animation must be JS to ensure it runs "under" the
- * optimised animation.
- */
- if (!isHandoff && AcceleratedAnimation.supports(options)) {
- return new AcceleratedAnimation(options);
- }
- else {
- return new MainThreadAnimation(options);
- }
- };
- export { animateMotionValue };
|