import { getValueTransition } from '../utils/get-value-transition.mjs'; import { resolveTransition } from '../utils/resolve-transition.mjs'; import { positionalKeys } from '../../render/utils/keys-position.mjs'; import { setTarget } from '../../render/utils/setters.mjs'; import { addValueToWillChange } from '../../value/will-change/add-will-change.mjs'; import { getOptimisedAppearId } from '../optimized-appear/get-appear-id.mjs'; import { animateMotionValue } from './motion-value.mjs'; import { frame } from '../../frameloop/frame.mjs'; /** * Decide whether we should block this animation. Previously, we achieved this * just by checking whether the key was listed in protectedKeys, but this * posed problems if an animation was triggered by afterChildren and protectedKeys * had been set to true in the meantime. */ function shouldBlockAnimation({ protectedKeys, needsAnimating }, key) { const shouldBlock = protectedKeys.hasOwnProperty(key) && needsAnimating[key] !== true; needsAnimating[key] = false; return shouldBlock; } function animateTarget(visualElement, targetAndTransition, { delay = 0, transitionOverride, type } = {}) { let { transition, transitionEnd, ...target } = targetAndTransition; const defaultTransition = visualElement.getDefaultTransition(); transition = transition ? resolveTransition(transition, defaultTransition) : defaultTransition; const reduceMotion = transition?.reduceMotion; if (transitionOverride) transition = transitionOverride; const animations = []; const animationTypeState = type && visualElement.animationState && visualElement.animationState.getState()[type]; for (const key in target) { const value = visualElement.getValue(key, visualElement.latestValues[key] ?? null); const valueTarget = target[key]; if (valueTarget === undefined || (animationTypeState && shouldBlockAnimation(animationTypeState, key))) { continue; } const valueTransition = { delay, ...getValueTransition(transition || {}, key), }; /** * If the value is already at the defined target, skip the animation. */ const currentValue = value.get(); if (currentValue !== undefined && !value.isAnimating && !Array.isArray(valueTarget) && valueTarget === currentValue && !valueTransition.velocity) { continue; } /** * If this is the first time a value is being animated, check * to see if we're handling off from an existing animation. */ let isHandoff = false; if (window.MotionHandoffAnimation) { const appearId = getOptimisedAppearId(visualElement); if (appearId) { const startTime = window.MotionHandoffAnimation(appearId, key, frame); if (startTime !== null) { valueTransition.startTime = startTime; isHandoff = true; } } } addValueToWillChange(visualElement, key); const shouldReduceMotion = reduceMotion ?? visualElement.shouldReduceMotion; value.start(animateMotionValue(key, value, valueTarget, shouldReduceMotion && positionalKeys.has(key) ? { type: false } : valueTransition, visualElement, isHandoff)); const animation = value.animation; if (animation) { animations.push(animation); } } if (transitionEnd) { const applyTransitionEnd = () => frame.update(() => { transitionEnd && setTarget(visualElement, transitionEnd); }); if (animations.length) { Promise.all(animations).then(applyTransitionEnd); } else { applyTransitionEnd(); } } return animations; } export { animateTarget }; //# sourceMappingURL=visual-element-target.mjs.map