first commit
This commit is contained in:
47
node_modules/framer-motion/dist/es/animation/animate/index.mjs
generated
vendored
Normal file
47
node_modules/framer-motion/dist/es/animation/animate/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import { GroupAnimationWithThen } from 'motion-dom';
|
||||
import { removeItem } from 'motion-utils';
|
||||
import { animateSequence } from './sequence.mjs';
|
||||
import { animateSubject } from './subject.mjs';
|
||||
|
||||
function isSequence(value) {
|
||||
return Array.isArray(value) && value.some(Array.isArray);
|
||||
}
|
||||
/**
|
||||
* Creates an animation function that is optionally scoped
|
||||
* to a specific element.
|
||||
*/
|
||||
function createScopedAnimate(scope) {
|
||||
/**
|
||||
* Implementation
|
||||
*/
|
||||
function scopedAnimate(subjectOrSequence, optionsOrKeyframes, options) {
|
||||
let animations = [];
|
||||
let animationOnComplete;
|
||||
if (isSequence(subjectOrSequence)) {
|
||||
animations = animateSequence(subjectOrSequence, optionsOrKeyframes, scope);
|
||||
}
|
||||
else {
|
||||
// Extract top-level onComplete so it doesn't get applied per-value
|
||||
const { onComplete, ...rest } = options || {};
|
||||
if (typeof onComplete === "function") {
|
||||
animationOnComplete = onComplete;
|
||||
}
|
||||
animations = animateSubject(subjectOrSequence, optionsOrKeyframes, rest, scope);
|
||||
}
|
||||
const animation = new GroupAnimationWithThen(animations);
|
||||
if (animationOnComplete) {
|
||||
animation.finished.then(animationOnComplete);
|
||||
}
|
||||
if (scope) {
|
||||
scope.animations.push(animation);
|
||||
animation.finished.then(() => {
|
||||
removeItem(scope.animations, animation);
|
||||
});
|
||||
}
|
||||
return animation;
|
||||
}
|
||||
return scopedAnimate;
|
||||
}
|
||||
const animate = createScopedAnimate();
|
||||
|
||||
export { animate, createScopedAnimate };
|
||||
19
node_modules/framer-motion/dist/es/animation/animate/resolve-subjects.mjs
generated
vendored
Normal file
19
node_modules/framer-motion/dist/es/animation/animate/resolve-subjects.mjs
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import { resolveElements } from 'motion-dom';
|
||||
import { isDOMKeyframes } from '../utils/is-dom-keyframes.mjs';
|
||||
|
||||
function resolveSubjects(subject, keyframes, scope, selectorCache) {
|
||||
if (typeof subject === "string" && isDOMKeyframes(keyframes)) {
|
||||
return resolveElements(subject, scope, selectorCache);
|
||||
}
|
||||
else if (subject instanceof NodeList) {
|
||||
return Array.from(subject);
|
||||
}
|
||||
else if (Array.isArray(subject)) {
|
||||
return subject;
|
||||
}
|
||||
else {
|
||||
return [subject];
|
||||
}
|
||||
}
|
||||
|
||||
export { resolveSubjects };
|
||||
14
node_modules/framer-motion/dist/es/animation/animate/sequence.mjs
generated
vendored
Normal file
14
node_modules/framer-motion/dist/es/animation/animate/sequence.mjs
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import { spring } from 'motion-dom';
|
||||
import { createAnimationsFromSequence } from '../sequence/create.mjs';
|
||||
import { animateSubject } from './subject.mjs';
|
||||
|
||||
function animateSequence(sequence, options, scope) {
|
||||
const animations = [];
|
||||
const animationDefinitions = createAnimationsFromSequence(sequence, options, scope, { spring });
|
||||
animationDefinitions.forEach(({ keyframes, transition }, subject) => {
|
||||
animations.push(...animateSubject(subject, keyframes, transition));
|
||||
});
|
||||
return animations;
|
||||
}
|
||||
|
||||
export { animateSequence };
|
||||
10
node_modules/framer-motion/dist/es/animation/animate/single-value.mjs
generated
vendored
Normal file
10
node_modules/framer-motion/dist/es/animation/animate/single-value.mjs
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import { isMotionValue, motionValue } from 'motion-dom';
|
||||
import { animateMotionValue } from '../interfaces/motion-value.mjs';
|
||||
|
||||
function animateSingleValue(value, keyframes, options) {
|
||||
const motionValue$1 = isMotionValue(value) ? value : motionValue(value);
|
||||
motionValue$1.start(animateMotionValue("", motionValue$1, keyframes, options));
|
||||
return motionValue$1.animation;
|
||||
}
|
||||
|
||||
export { animateSingleValue };
|
||||
53
node_modules/framer-motion/dist/es/animation/animate/subject.mjs
generated
vendored
Normal file
53
node_modules/framer-motion/dist/es/animation/animate/subject.mjs
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import { isMotionValue } from 'motion-dom';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { visualElementStore } from '../../render/store.mjs';
|
||||
import { animateTarget } from '../interfaces/visual-element-target.mjs';
|
||||
import { createDOMVisualElement, createObjectVisualElement } from '../utils/create-visual-element.mjs';
|
||||
import { isDOMKeyframes } from '../utils/is-dom-keyframes.mjs';
|
||||
import { resolveSubjects } from './resolve-subjects.mjs';
|
||||
import { animateSingleValue } from './single-value.mjs';
|
||||
|
||||
function isSingleValue(subject, keyframes) {
|
||||
return (isMotionValue(subject) ||
|
||||
typeof subject === "number" ||
|
||||
(typeof subject === "string" && !isDOMKeyframes(keyframes)));
|
||||
}
|
||||
/**
|
||||
* Implementation
|
||||
*/
|
||||
function animateSubject(subject, keyframes, options, scope) {
|
||||
const animations = [];
|
||||
if (isSingleValue(subject, keyframes)) {
|
||||
animations.push(animateSingleValue(subject, isDOMKeyframes(keyframes)
|
||||
? keyframes.default || keyframes
|
||||
: keyframes, options ? options.default || options : options));
|
||||
}
|
||||
else {
|
||||
const subjects = resolveSubjects(subject, keyframes, scope);
|
||||
const numSubjects = subjects.length;
|
||||
invariant(Boolean(numSubjects), "No valid elements provided.", "no-valid-elements");
|
||||
for (let i = 0; i < numSubjects; i++) {
|
||||
const thisSubject = subjects[i];
|
||||
invariant(thisSubject !== null, "You're trying to perform an animation on null. Ensure that selectors are correctly finding elements and refs are correctly hydrated.", "animate-null");
|
||||
const createVisualElement = thisSubject instanceof Element
|
||||
? createDOMVisualElement
|
||||
: createObjectVisualElement;
|
||||
if (!visualElementStore.has(thisSubject)) {
|
||||
createVisualElement(thisSubject);
|
||||
}
|
||||
const visualElement = visualElementStore.get(thisSubject);
|
||||
const transition = { ...options };
|
||||
/**
|
||||
* Resolve stagger function if provided.
|
||||
*/
|
||||
if ("delay" in transition &&
|
||||
typeof transition.delay === "function") {
|
||||
transition.delay = transition.delay(i, numSubjects);
|
||||
}
|
||||
animations.push(...animateTarget(visualElement, { ...keyframes, transition }, {}));
|
||||
}
|
||||
}
|
||||
return animations;
|
||||
}
|
||||
|
||||
export { animateSubject };
|
||||
105
node_modules/framer-motion/dist/es/animation/animators/waapi/animate-elements.mjs
generated
vendored
Normal file
105
node_modules/framer-motion/dist/es/animation/animators/waapi/animate-elements.mjs
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
import { resolveElements, getValueTransition, getAnimationMap, animationMapKey, getComputedStyle, fillWildcards, applyPxDefaults, NativeAnimation } from 'motion-dom';
|
||||
import { invariant, secondsToMilliseconds } from 'motion-utils';
|
||||
|
||||
function animateElements(elementOrSelector, keyframes, options, scope) {
|
||||
const elements = resolveElements(elementOrSelector, scope);
|
||||
const numElements = elements.length;
|
||||
invariant(Boolean(numElements), "No valid elements provided.", "no-valid-elements");
|
||||
/**
|
||||
* WAAPI doesn't support interrupting animations.
|
||||
*
|
||||
* Therefore, starting animations requires a three-step process:
|
||||
* 1. Stop existing animations (write styles to DOM)
|
||||
* 2. Resolve keyframes (read styles from DOM)
|
||||
* 3. Create new animations (write styles to DOM)
|
||||
*
|
||||
* The hybrid `animate()` function uses AsyncAnimation to resolve
|
||||
* keyframes before creating new animations, which removes style
|
||||
* thrashing. Here, we have much stricter filesize constraints.
|
||||
* Therefore we do this in a synchronous way that ensures that
|
||||
* at least within `animate()` calls there is no style thrashing.
|
||||
*
|
||||
* In the motion-native-animate-mini-interrupt benchmark this
|
||||
* was 80% faster than a single loop.
|
||||
*/
|
||||
const animationDefinitions = [];
|
||||
/**
|
||||
* Step 1: Build options and stop existing animations (write)
|
||||
*/
|
||||
for (let i = 0; i < numElements; i++) {
|
||||
const element = elements[i];
|
||||
const elementTransition = { ...options };
|
||||
/**
|
||||
* Resolve stagger function if provided.
|
||||
*/
|
||||
if (typeof elementTransition.delay === "function") {
|
||||
elementTransition.delay = elementTransition.delay(i, numElements);
|
||||
}
|
||||
for (const valueName in keyframes) {
|
||||
let valueKeyframes = keyframes[valueName];
|
||||
if (!Array.isArray(valueKeyframes)) {
|
||||
valueKeyframes = [valueKeyframes];
|
||||
}
|
||||
const valueOptions = {
|
||||
...getValueTransition(elementTransition, valueName),
|
||||
};
|
||||
valueOptions.duration && (valueOptions.duration = secondsToMilliseconds(valueOptions.duration));
|
||||
valueOptions.delay && (valueOptions.delay = secondsToMilliseconds(valueOptions.delay));
|
||||
/**
|
||||
* If there's an existing animation playing on this element then stop it
|
||||
* before creating a new one.
|
||||
*/
|
||||
const map = getAnimationMap(element);
|
||||
const key = animationMapKey(valueName, valueOptions.pseudoElement || "");
|
||||
const currentAnimation = map.get(key);
|
||||
currentAnimation && currentAnimation.stop();
|
||||
animationDefinitions.push({
|
||||
map,
|
||||
key,
|
||||
unresolvedKeyframes: valueKeyframes,
|
||||
options: {
|
||||
...valueOptions,
|
||||
element,
|
||||
name: valueName,
|
||||
allowFlatten: !elementTransition.type && !elementTransition.ease,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Step 2: Resolve keyframes (read)
|
||||
*/
|
||||
for (let i = 0; i < animationDefinitions.length; i++) {
|
||||
const { unresolvedKeyframes, options: animationOptions } = animationDefinitions[i];
|
||||
const { element, name, pseudoElement } = animationOptions;
|
||||
if (!pseudoElement && unresolvedKeyframes[0] === null) {
|
||||
unresolvedKeyframes[0] = getComputedStyle(element, name);
|
||||
}
|
||||
fillWildcards(unresolvedKeyframes);
|
||||
applyPxDefaults(unresolvedKeyframes, name);
|
||||
/**
|
||||
* If we only have one keyframe, explicitly read the initial keyframe
|
||||
* from the computed style. This is to ensure consistency with WAAPI behaviour
|
||||
* for restarting animations, for instance .play() after finish, when it
|
||||
* has one vs two keyframes.
|
||||
*/
|
||||
if (!pseudoElement && unresolvedKeyframes.length < 2) {
|
||||
unresolvedKeyframes.unshift(getComputedStyle(element, name));
|
||||
}
|
||||
animationOptions.keyframes = unresolvedKeyframes;
|
||||
}
|
||||
/**
|
||||
* Step 3: Create new animations (write)
|
||||
*/
|
||||
const animations = [];
|
||||
for (let i = 0; i < animationDefinitions.length; i++) {
|
||||
const { map, key, options: animationOptions } = animationDefinitions[i];
|
||||
const animation = new NativeAnimation(animationOptions);
|
||||
map.set(key, animation);
|
||||
animation.finished.finally(() => map.delete(key));
|
||||
animations.push(animation);
|
||||
}
|
||||
return animations;
|
||||
}
|
||||
|
||||
export { animateElements };
|
||||
13
node_modules/framer-motion/dist/es/animation/animators/waapi/animate-sequence.mjs
generated
vendored
Normal file
13
node_modules/framer-motion/dist/es/animation/animators/waapi/animate-sequence.mjs
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { GroupAnimationWithThen } from 'motion-dom';
|
||||
import { createAnimationsFromSequence } from '../../sequence/create.mjs';
|
||||
import { animateElements } from './animate-elements.mjs';
|
||||
|
||||
function animateSequence(definition, options) {
|
||||
const animations = [];
|
||||
createAnimationsFromSequence(definition, options).forEach(({ keyframes, transition }, element) => {
|
||||
animations.push(...animateElements(element, keyframes, transition));
|
||||
});
|
||||
return new GroupAnimationWithThen(animations);
|
||||
}
|
||||
|
||||
export { animateSequence };
|
||||
12
node_modules/framer-motion/dist/es/animation/animators/waapi/animate-style.mjs
generated
vendored
Normal file
12
node_modules/framer-motion/dist/es/animation/animators/waapi/animate-style.mjs
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { GroupAnimationWithThen } from 'motion-dom';
|
||||
import { animateElements } from './animate-elements.mjs';
|
||||
|
||||
const createScopedWaapiAnimate = (scope) => {
|
||||
function scopedAnimate(elementOrSelector, keyframes, options) {
|
||||
return new GroupAnimationWithThen(animateElements(elementOrSelector, keyframes, options, scope));
|
||||
}
|
||||
return scopedAnimate;
|
||||
};
|
||||
const animateMini = /*@__PURE__*/ createScopedWaapiAnimate();
|
||||
|
||||
export { animateMini, createScopedWaapiAnimate };
|
||||
12
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/get-final-keyframe.mjs
generated
vendored
Normal file
12
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/get-final-keyframe.mjs
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
const isNotNull = (value) => value !== null;
|
||||
function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyframe) {
|
||||
const resolvedKeyframes = keyframes.filter(isNotNull);
|
||||
const index = repeat && repeatType !== "loop" && repeat % 2 === 1
|
||||
? 0
|
||||
: resolvedKeyframes.length - 1;
|
||||
return !index || finalKeyframe === undefined
|
||||
? resolvedKeyframes[index]
|
||||
: finalKeyframe;
|
||||
}
|
||||
|
||||
export { getFinalKeyframe };
|
||||
80
node_modules/framer-motion/dist/es/animation/hooks/animation-controls.mjs
generated
vendored
Normal file
80
node_modules/framer-motion/dist/es/animation/hooks/animation-controls.mjs
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
import { invariant } from 'motion-utils';
|
||||
import { setTarget } from '../../render/utils/setters.mjs';
|
||||
import { animateVisualElement } from '../interfaces/visual-element.mjs';
|
||||
|
||||
function stopAnimation(visualElement) {
|
||||
visualElement.values.forEach((value) => value.stop());
|
||||
}
|
||||
function setVariants(visualElement, variantLabels) {
|
||||
const reversedLabels = [...variantLabels].reverse();
|
||||
reversedLabels.forEach((key) => {
|
||||
const variant = visualElement.getVariant(key);
|
||||
variant && setTarget(visualElement, variant);
|
||||
if (visualElement.variantChildren) {
|
||||
visualElement.variantChildren.forEach((child) => {
|
||||
setVariants(child, variantLabels);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function setValues(visualElement, definition) {
|
||||
if (Array.isArray(definition)) {
|
||||
return setVariants(visualElement, definition);
|
||||
}
|
||||
else if (typeof definition === "string") {
|
||||
return setVariants(visualElement, [definition]);
|
||||
}
|
||||
else {
|
||||
setTarget(visualElement, definition);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
function animationControls() {
|
||||
/**
|
||||
* Track whether the host component has mounted.
|
||||
*/
|
||||
let hasMounted = false;
|
||||
/**
|
||||
* A collection of linked component animation controls.
|
||||
*/
|
||||
const subscribers = new Set();
|
||||
const controls = {
|
||||
subscribe(visualElement) {
|
||||
subscribers.add(visualElement);
|
||||
return () => void subscribers.delete(visualElement);
|
||||
},
|
||||
start(definition, transitionOverride) {
|
||||
invariant(hasMounted, "controls.start() should only be called after a component has mounted. Consider calling within a useEffect hook.");
|
||||
const animations = [];
|
||||
subscribers.forEach((visualElement) => {
|
||||
animations.push(animateVisualElement(visualElement, definition, {
|
||||
transitionOverride,
|
||||
}));
|
||||
});
|
||||
return Promise.all(animations);
|
||||
},
|
||||
set(definition) {
|
||||
invariant(hasMounted, "controls.set() should only be called after a component has mounted. Consider calling within a useEffect hook.");
|
||||
return subscribers.forEach((visualElement) => {
|
||||
setValues(visualElement, definition);
|
||||
});
|
||||
},
|
||||
stop() {
|
||||
subscribers.forEach((visualElement) => {
|
||||
stopAnimation(visualElement);
|
||||
});
|
||||
},
|
||||
mount() {
|
||||
hasMounted = true;
|
||||
return () => {
|
||||
hasMounted = false;
|
||||
controls.stop();
|
||||
};
|
||||
},
|
||||
};
|
||||
return controls;
|
||||
}
|
||||
|
||||
export { animationControls, setValues };
|
||||
18
node_modules/framer-motion/dist/es/animation/hooks/use-animate-style.mjs
generated
vendored
Normal file
18
node_modules/framer-motion/dist/es/animation/hooks/use-animate-style.mjs
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
"use client";
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useUnmountEffect } from '../../utils/use-unmount-effect.mjs';
|
||||
import { createScopedWaapiAnimate } from '../animators/waapi/animate-style.mjs';
|
||||
|
||||
function useAnimateMini() {
|
||||
const scope = useConstant(() => ({
|
||||
current: null, // Will be hydrated by React
|
||||
animations: [],
|
||||
}));
|
||||
const animate = useConstant(() => createScopedWaapiAnimate(scope));
|
||||
useUnmountEffect(() => {
|
||||
scope.animations.forEach((animation) => animation.stop());
|
||||
});
|
||||
return [scope, animate];
|
||||
}
|
||||
|
||||
export { useAnimateMini };
|
||||
19
node_modules/framer-motion/dist/es/animation/hooks/use-animate.mjs
generated
vendored
Normal file
19
node_modules/framer-motion/dist/es/animation/hooks/use-animate.mjs
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
"use client";
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useUnmountEffect } from '../../utils/use-unmount-effect.mjs';
|
||||
import { createScopedAnimate } from '../animate/index.mjs';
|
||||
|
||||
function useAnimate() {
|
||||
const scope = useConstant(() => ({
|
||||
current: null, // Will be hydrated by React
|
||||
animations: [],
|
||||
}));
|
||||
const animate = useConstant(() => createScopedAnimate(scope));
|
||||
useUnmountEffect(() => {
|
||||
scope.animations.forEach((animation) => animation.stop());
|
||||
scope.animations.length = 0;
|
||||
});
|
||||
return [scope, animate];
|
||||
}
|
||||
|
||||
export { useAnimate };
|
||||
65
node_modules/framer-motion/dist/es/animation/hooks/use-animated-state.mjs
generated
vendored
Normal file
65
node_modules/framer-motion/dist/es/animation/hooks/use-animated-state.mjs
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
"use client";
|
||||
import { useState, useLayoutEffect } from 'react';
|
||||
import { makeUseVisualState } from '../../motion/utils/use-visual-state.mjs';
|
||||
import { createBox } from '../../projection/geometry/models.mjs';
|
||||
import { VisualElement } from '../../render/VisualElement.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { animateVisualElement } from '../interfaces/visual-element.mjs';
|
||||
|
||||
const createObject = () => ({});
|
||||
class StateVisualElement extends VisualElement {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.measureInstanceViewportBox = createBox;
|
||||
}
|
||||
build() { }
|
||||
resetTransform() { }
|
||||
restoreTransform() { }
|
||||
removeValueFromRenderState() { }
|
||||
renderInstance() { }
|
||||
scrapeMotionValuesFromProps() {
|
||||
return createObject();
|
||||
}
|
||||
getBaseTargetFromProps() {
|
||||
return undefined;
|
||||
}
|
||||
readValueFromInstance(_state, key, options) {
|
||||
return options.initialState[key] || 0;
|
||||
}
|
||||
sortInstanceNodePosition() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
const useVisualState = makeUseVisualState({
|
||||
scrapeMotionValuesFromProps: createObject,
|
||||
createRenderState: createObject,
|
||||
});
|
||||
/**
|
||||
* This is not an officially supported API and may be removed
|
||||
* on any version.
|
||||
*/
|
||||
function useAnimatedState(initialState) {
|
||||
const [animationState, setAnimationState] = useState(initialState);
|
||||
const visualState = useVisualState({}, false);
|
||||
const element = useConstant(() => {
|
||||
return new StateVisualElement({
|
||||
props: {
|
||||
onUpdate: (v) => {
|
||||
setAnimationState({ ...v });
|
||||
},
|
||||
},
|
||||
visualState,
|
||||
presenceContext: null,
|
||||
}, { initialState });
|
||||
});
|
||||
useLayoutEffect(() => {
|
||||
element.mount({});
|
||||
return () => element.unmount();
|
||||
}, [element]);
|
||||
const startAnimation = useConstant(() => (animationDefinition) => {
|
||||
return animateVisualElement(element, animationDefinition);
|
||||
});
|
||||
return [animationState, startAnimation];
|
||||
}
|
||||
|
||||
export { useAnimatedState };
|
||||
42
node_modules/framer-motion/dist/es/animation/hooks/use-animation.mjs
generated
vendored
Normal file
42
node_modules/framer-motion/dist/es/animation/hooks/use-animation.mjs
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
"use client";
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
|
||||
import { animationControls } from './animation-controls.mjs';
|
||||
|
||||
/**
|
||||
* Creates `LegacyAnimationControls`, which can be used to manually start, stop
|
||||
* and sequence animations on one or more components.
|
||||
*
|
||||
* The returned `LegacyAnimationControls` should be passed to the `animate` property
|
||||
* of the components you want to animate.
|
||||
*
|
||||
* These components can then be animated with the `start` method.
|
||||
*
|
||||
* ```jsx
|
||||
* import * as React from 'react'
|
||||
* import { motion, useAnimation } from 'framer-motion'
|
||||
*
|
||||
* export function MyComponent(props) {
|
||||
* const controls = useAnimation()
|
||||
*
|
||||
* controls.start({
|
||||
* x: 100,
|
||||
* transition: { duration: 0.5 },
|
||||
* })
|
||||
*
|
||||
* return <motion.div animate={controls} />
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @returns Animation controller with `start` and `stop` methods
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function useAnimationControls() {
|
||||
const controls = useConstant(animationControls);
|
||||
useIsomorphicLayoutEffect(controls.mount, []);
|
||||
return controls;
|
||||
}
|
||||
const useAnimation = useAnimationControls;
|
||||
|
||||
export { useAnimation, useAnimationControls };
|
||||
98
node_modules/framer-motion/dist/es/animation/interfaces/motion-value.mjs
generated
vendored
Normal file
98
node_modules/framer-motion/dist/es/animation/interfaces/motion-value.mjs
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
import { getValueTransition, makeAnimationInstant, frame, JSAnimation, AsyncMotionValueAnimation } from 'motion-dom';
|
||||
import { secondsToMilliseconds, MotionGlobalConfig } from 'motion-utils';
|
||||
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);
|
||||
const 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)) {
|
||||
Object.assign(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.
|
||||
*/
|
||||
options.duration && (options.duration = secondsToMilliseconds(options.duration));
|
||||
options.repeatDelay && (options.repeatDelay = secondsToMilliseconds(options.repeatDelay));
|
||||
/**
|
||||
* Support deprecated way to set initial value. Prefer keyframe syntax.
|
||||
*/
|
||||
if (options.from !== undefined) {
|
||||
options.keyframes[0] = options.from;
|
||||
}
|
||||
let shouldSkip = false;
|
||||
if (options.type === false ||
|
||||
(options.duration === 0 && !options.repeatDelay)) {
|
||||
makeAnimationInstant(options);
|
||||
if (options.delay === 0) {
|
||||
shouldSkip = true;
|
||||
}
|
||||
}
|
||||
if (MotionGlobalConfig.instantAnimations ||
|
||||
MotionGlobalConfig.skipAnimations) {
|
||||
shouldSkip = true;
|
||||
makeAnimationInstant(options);
|
||||
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();
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
return valueTransition.isSync
|
||||
? new JSAnimation(options)
|
||||
: new AsyncMotionValueAnimation(options);
|
||||
};
|
||||
|
||||
export { animateMotionValue };
|
||||
83
node_modules/framer-motion/dist/es/animation/interfaces/visual-element-target.mjs
generated
vendored
Normal file
83
node_modules/framer-motion/dist/es/animation/interfaces/visual-element-target.mjs
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
import { getValueTransition, frame, positionalKeys } from 'motion-dom';
|
||||
import { setTarget } from '../../render/utils/setters.mjs';
|
||||
import { addValueToWillChange } from '../../value/use-will-change/add-will-change.mjs';
|
||||
import { getOptimisedAppearId } from '../optimized-appear/get-appear-id.mjs';
|
||||
import { animateMotionValue } from './motion-value.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 = visualElement.getDefaultTransition(), transitionEnd, ...target } = targetAndTransition;
|
||||
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);
|
||||
value.start(animateMotionValue(key, value, valueTarget, visualElement.shouldReduceMotion && positionalKeys.has(key)
|
||||
? { type: false }
|
||||
: valueTransition, visualElement, isHandoff));
|
||||
const animation = value.animation;
|
||||
if (animation) {
|
||||
animations.push(animation);
|
||||
}
|
||||
}
|
||||
if (transitionEnd) {
|
||||
Promise.all(animations).then(() => {
|
||||
frame.update(() => {
|
||||
transitionEnd && setTarget(visualElement, transitionEnd);
|
||||
});
|
||||
});
|
||||
}
|
||||
return animations;
|
||||
}
|
||||
|
||||
export { animateTarget };
|
||||
59
node_modules/framer-motion/dist/es/animation/interfaces/visual-element-variant.mjs
generated
vendored
Normal file
59
node_modules/framer-motion/dist/es/animation/interfaces/visual-element-variant.mjs
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
import { resolveVariant } from '../../render/utils/resolve-dynamic-variants.mjs';
|
||||
import { calcChildStagger } from '../utils/calc-child-stagger.mjs';
|
||||
import { animateTarget } from './visual-element-target.mjs';
|
||||
|
||||
function animateVariant(visualElement, variant, options = {}) {
|
||||
const resolved = resolveVariant(visualElement, variant, options.type === "exit"
|
||||
? visualElement.presenceContext?.custom
|
||||
: undefined);
|
||||
let { transition = visualElement.getDefaultTransition() || {} } = resolved || {};
|
||||
if (options.transitionOverride) {
|
||||
transition = options.transitionOverride;
|
||||
}
|
||||
/**
|
||||
* If we have a variant, create a callback that runs it as an animation.
|
||||
* Otherwise, we resolve a Promise immediately for a composable no-op.
|
||||
*/
|
||||
const getAnimation = resolved
|
||||
? () => Promise.all(animateTarget(visualElement, resolved, options))
|
||||
: () => Promise.resolve();
|
||||
/**
|
||||
* If we have children, create a callback that runs all their animations.
|
||||
* Otherwise, we resolve a Promise immediately for a composable no-op.
|
||||
*/
|
||||
const getChildAnimations = visualElement.variantChildren && visualElement.variantChildren.size
|
||||
? (forwardDelay = 0) => {
|
||||
const { delayChildren = 0, staggerChildren, staggerDirection, } = transition;
|
||||
return animateChildren(visualElement, variant, forwardDelay, delayChildren, staggerChildren, staggerDirection, options);
|
||||
}
|
||||
: () => Promise.resolve();
|
||||
/**
|
||||
* If the transition explicitly defines a "when" option, we need to resolve either
|
||||
* this animation or all children animations before playing the other.
|
||||
*/
|
||||
const { when } = transition;
|
||||
if (when) {
|
||||
const [first, last] = when === "beforeChildren"
|
||||
? [getAnimation, getChildAnimations]
|
||||
: [getChildAnimations, getAnimation];
|
||||
return first().then(() => last());
|
||||
}
|
||||
else {
|
||||
return Promise.all([getAnimation(), getChildAnimations(options.delay)]);
|
||||
}
|
||||
}
|
||||
function animateChildren(visualElement, variant, delay = 0, delayChildren = 0, staggerChildren = 0, staggerDirection = 1, options) {
|
||||
const animations = [];
|
||||
for (const child of visualElement.variantChildren) {
|
||||
child.notify("AnimationStart", variant);
|
||||
animations.push(animateVariant(child, variant, {
|
||||
...options,
|
||||
delay: delay +
|
||||
(typeof delayChildren === "function" ? 0 : delayChildren) +
|
||||
calcChildStagger(visualElement.variantChildren, child, delayChildren, staggerChildren, staggerDirection),
|
||||
}).then(() => child.notify("AnimationComplete", variant)));
|
||||
}
|
||||
return Promise.all(animations);
|
||||
}
|
||||
|
||||
export { animateVariant };
|
||||
26
node_modules/framer-motion/dist/es/animation/interfaces/visual-element.mjs
generated
vendored
Normal file
26
node_modules/framer-motion/dist/es/animation/interfaces/visual-element.mjs
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import { resolveVariant } from '../../render/utils/resolve-dynamic-variants.mjs';
|
||||
import { animateTarget } from './visual-element-target.mjs';
|
||||
import { animateVariant } from './visual-element-variant.mjs';
|
||||
|
||||
function animateVisualElement(visualElement, definition, options = {}) {
|
||||
visualElement.notify("AnimationStart", definition);
|
||||
let animation;
|
||||
if (Array.isArray(definition)) {
|
||||
const animations = definition.map((variant) => animateVariant(visualElement, variant, options));
|
||||
animation = Promise.all(animations);
|
||||
}
|
||||
else if (typeof definition === "string") {
|
||||
animation = animateVariant(visualElement, definition, options);
|
||||
}
|
||||
else {
|
||||
const resolvedDefinition = typeof definition === "function"
|
||||
? resolveVariant(visualElement, definition, options.custom)
|
||||
: definition;
|
||||
animation = Promise.all(animateTarget(visualElement, resolvedDefinition, options));
|
||||
}
|
||||
return animation.then(() => {
|
||||
visualElement.notify("AnimationComplete", definition);
|
||||
});
|
||||
}
|
||||
|
||||
export { animateVisualElement };
|
||||
6
node_modules/framer-motion/dist/es/animation/optimized-appear/data-id.mjs
generated
vendored
Normal file
6
node_modules/framer-motion/dist/es/animation/optimized-appear/data-id.mjs
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { camelToDash } from '../../render/dom/utils/camel-to-dash.mjs';
|
||||
|
||||
const optimizedAppearDataId = "framerAppearId";
|
||||
const optimizedAppearDataAttribute = "data-" + camelToDash(optimizedAppearDataId);
|
||||
|
||||
export { optimizedAppearDataAttribute, optimizedAppearDataId };
|
||||
7
node_modules/framer-motion/dist/es/animation/optimized-appear/get-appear-id.mjs
generated
vendored
Normal file
7
node_modules/framer-motion/dist/es/animation/optimized-appear/get-appear-id.mjs
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { optimizedAppearDataAttribute } from './data-id.mjs';
|
||||
|
||||
function getOptimisedAppearId(visualElement) {
|
||||
return visualElement.props[optimizedAppearDataAttribute];
|
||||
}
|
||||
|
||||
export { getOptimisedAppearId };
|
||||
38
node_modules/framer-motion/dist/es/animation/optimized-appear/handoff.mjs
generated
vendored
Normal file
38
node_modules/framer-motion/dist/es/animation/optimized-appear/handoff.mjs
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import { appearAnimationStore } from './store.mjs';
|
||||
import { appearStoreId } from './store-id.mjs';
|
||||
|
||||
function handoffOptimizedAppearAnimation(elementId, valueName, frame) {
|
||||
const storeId = appearStoreId(elementId, valueName);
|
||||
const optimisedAnimation = appearAnimationStore.get(storeId);
|
||||
if (!optimisedAnimation) {
|
||||
return null;
|
||||
}
|
||||
const { animation, startTime } = optimisedAnimation;
|
||||
function cancelAnimation() {
|
||||
window.MotionCancelOptimisedAnimation?.(elementId, valueName, frame);
|
||||
}
|
||||
/**
|
||||
* We can cancel the animation once it's finished now that we've synced
|
||||
* with Motion.
|
||||
*
|
||||
* Prefer onfinish over finished as onfinish is backwards compatible with
|
||||
* older browsers.
|
||||
*/
|
||||
animation.onfinish = cancelAnimation;
|
||||
if (startTime === null || window.MotionHandoffIsComplete?.(elementId)) {
|
||||
/**
|
||||
* If the startTime is null, this animation is the Paint Ready detection animation
|
||||
* and we can cancel it immediately without handoff.
|
||||
*
|
||||
* Or if we've already handed off the animation then we're now interrupting it.
|
||||
* In which case we need to cancel it.
|
||||
*/
|
||||
cancelAnimation();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return startTime;
|
||||
}
|
||||
}
|
||||
|
||||
export { handoffOptimizedAppearAnimation };
|
||||
171
node_modules/framer-motion/dist/es/animation/optimized-appear/start.mjs
generated
vendored
Normal file
171
node_modules/framer-motion/dist/es/animation/optimized-appear/start.mjs
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
import { startWaapiAnimation } from 'motion-dom';
|
||||
import { noop } from 'motion-utils';
|
||||
import { optimizedAppearDataId } from './data-id.mjs';
|
||||
import { getOptimisedAppearId } from './get-appear-id.mjs';
|
||||
import { handoffOptimizedAppearAnimation } from './handoff.mjs';
|
||||
import { appearAnimationStore, appearComplete } from './store.mjs';
|
||||
import { appearStoreId } from './store-id.mjs';
|
||||
|
||||
/**
|
||||
* A single time to use across all animations to manually set startTime
|
||||
* and ensure they're all in sync.
|
||||
*/
|
||||
let startFrameTime;
|
||||
/**
|
||||
* A dummy animation to detect when Chrome is ready to start
|
||||
* painting the page and hold off from triggering the real animation
|
||||
* until then. We only need one animation to detect paint ready.
|
||||
*
|
||||
* https://bugs.chromium.org/p/chromium/issues/detail?id=1406850
|
||||
*/
|
||||
let readyAnimation;
|
||||
/**
|
||||
* Keep track of animations that were suspended vs cancelled so we
|
||||
* can easily resume them when we're done measuring layout.
|
||||
*/
|
||||
const suspendedAnimations = new Set();
|
||||
function resumeSuspendedAnimations() {
|
||||
suspendedAnimations.forEach((data) => {
|
||||
data.animation.play();
|
||||
data.animation.startTime = data.startTime;
|
||||
});
|
||||
suspendedAnimations.clear();
|
||||
}
|
||||
function startOptimizedAppearAnimation(element, name, keyframes, options, onReady) {
|
||||
// Prevent optimised appear animations if Motion has already started animating.
|
||||
if (window.MotionIsMounted) {
|
||||
return;
|
||||
}
|
||||
const id = element.dataset[optimizedAppearDataId];
|
||||
if (!id)
|
||||
return;
|
||||
window.MotionHandoffAnimation = handoffOptimizedAppearAnimation;
|
||||
const storeId = appearStoreId(id, name);
|
||||
if (!readyAnimation) {
|
||||
readyAnimation = startWaapiAnimation(element, name, [keyframes[0], keyframes[0]],
|
||||
/**
|
||||
* 10 secs is basically just a super-safe duration to give Chrome
|
||||
* long enough to get the animation ready.
|
||||
*/
|
||||
{ duration: 10000, ease: "linear" });
|
||||
appearAnimationStore.set(storeId, {
|
||||
animation: readyAnimation,
|
||||
startTime: null,
|
||||
});
|
||||
/**
|
||||
* If there's no readyAnimation then there's been no instantiation
|
||||
* of handoff animations.
|
||||
*/
|
||||
window.MotionHandoffAnimation = handoffOptimizedAppearAnimation;
|
||||
window.MotionHasOptimisedAnimation = (elementId, valueName) => {
|
||||
if (!elementId)
|
||||
return false;
|
||||
/**
|
||||
* Keep a map of elementIds that have started animating. We check
|
||||
* via ID instead of Element because of hydration errors and
|
||||
* pre-hydration checks. We also actively record IDs as they start
|
||||
* animating rather than simply checking for data-appear-id as
|
||||
* this attrbute might be present but not lead to an animation, for
|
||||
* instance if the element's appear animation is on a different
|
||||
* breakpoint.
|
||||
*/
|
||||
if (!valueName) {
|
||||
return appearComplete.has(elementId);
|
||||
}
|
||||
const animationId = appearStoreId(elementId, valueName);
|
||||
return Boolean(appearAnimationStore.get(animationId));
|
||||
};
|
||||
window.MotionHandoffMarkAsComplete = (elementId) => {
|
||||
if (appearComplete.has(elementId)) {
|
||||
appearComplete.set(elementId, true);
|
||||
}
|
||||
};
|
||||
window.MotionHandoffIsComplete = (elementId) => {
|
||||
return appearComplete.get(elementId) === true;
|
||||
};
|
||||
/**
|
||||
* We only need to cancel transform animations as
|
||||
* they're the ones that will interfere with the
|
||||
* layout animation measurements.
|
||||
*/
|
||||
window.MotionCancelOptimisedAnimation = (elementId, valueName, frame, canResume) => {
|
||||
const animationId = appearStoreId(elementId, valueName);
|
||||
const data = appearAnimationStore.get(animationId);
|
||||
if (!data)
|
||||
return;
|
||||
if (frame && canResume === undefined) {
|
||||
/**
|
||||
* Wait until the end of the subsequent frame to cancel the animation
|
||||
* to ensure we don't remove the animation before the main thread has
|
||||
* had a chance to resolve keyframes and render.
|
||||
*/
|
||||
frame.postRender(() => {
|
||||
frame.postRender(() => {
|
||||
data.animation.cancel();
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
data.animation.cancel();
|
||||
}
|
||||
if (frame && canResume) {
|
||||
suspendedAnimations.add(data);
|
||||
frame.render(resumeSuspendedAnimations);
|
||||
}
|
||||
else {
|
||||
appearAnimationStore.delete(animationId);
|
||||
/**
|
||||
* If there are no more animations left, we can remove the cancel function.
|
||||
* This will let us know when we can stop checking for conflicting layout animations.
|
||||
*/
|
||||
if (!appearAnimationStore.size) {
|
||||
window.MotionCancelOptimisedAnimation = undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
window.MotionCheckAppearSync = (visualElement, valueName, value) => {
|
||||
const appearId = getOptimisedAppearId(visualElement);
|
||||
if (!appearId)
|
||||
return;
|
||||
const valueIsOptimised = window.MotionHasOptimisedAnimation?.(appearId, valueName);
|
||||
const externalAnimationValue = visualElement.props.values?.[valueName];
|
||||
if (!valueIsOptimised || !externalAnimationValue)
|
||||
return;
|
||||
const removeSyncCheck = value.on("change", (latestValue) => {
|
||||
if (externalAnimationValue.get() !== latestValue) {
|
||||
window.MotionCancelOptimisedAnimation?.(appearId, valueName);
|
||||
removeSyncCheck();
|
||||
}
|
||||
});
|
||||
return removeSyncCheck;
|
||||
};
|
||||
}
|
||||
const startAnimation = () => {
|
||||
readyAnimation.cancel();
|
||||
const appearAnimation = startWaapiAnimation(element, name, keyframes, options);
|
||||
/**
|
||||
* Record the time of the first started animation. We call performance.now() once
|
||||
* here and once in handoff to ensure we're getting
|
||||
* close to a frame-locked time. This keeps all animations in sync.
|
||||
*/
|
||||
if (startFrameTime === undefined) {
|
||||
startFrameTime = performance.now();
|
||||
}
|
||||
appearAnimation.startTime = startFrameTime;
|
||||
appearAnimationStore.set(storeId, {
|
||||
animation: appearAnimation,
|
||||
startTime: startFrameTime,
|
||||
});
|
||||
if (onReady)
|
||||
onReady(appearAnimation);
|
||||
};
|
||||
appearComplete.set(id, false);
|
||||
if (readyAnimation.ready) {
|
||||
readyAnimation.ready.then(startAnimation).catch(noop);
|
||||
}
|
||||
else {
|
||||
startAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
export { startOptimizedAppearAnimation };
|
||||
8
node_modules/framer-motion/dist/es/animation/optimized-appear/store-id.mjs
generated
vendored
Normal file
8
node_modules/framer-motion/dist/es/animation/optimized-appear/store-id.mjs
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import { transformProps } from 'motion-dom';
|
||||
|
||||
const appearStoreId = (elementId, valueName) => {
|
||||
const key = transformProps.has(valueName) ? "transform" : valueName;
|
||||
return `${elementId}: ${key}`;
|
||||
};
|
||||
|
||||
export { appearStoreId };
|
||||
4
node_modules/framer-motion/dist/es/animation/optimized-appear/store.mjs
generated
vendored
Normal file
4
node_modules/framer-motion/dist/es/animation/optimized-appear/store.mjs
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
const appearAnimationStore = new Map();
|
||||
const appearComplete = new Map();
|
||||
|
||||
export { appearAnimationStore, appearComplete };
|
||||
249
node_modules/framer-motion/dist/es/animation/sequence/create.mjs
generated
vendored
Normal file
249
node_modules/framer-motion/dist/es/animation/sequence/create.mjs
generated
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
import { isMotionValue, defaultOffset, isGenerator, createGeneratorEasing, fillOffset } from 'motion-dom';
|
||||
import { progress, secondsToMilliseconds, invariant, getEasingForSegment } from 'motion-utils';
|
||||
import { resolveSubjects } from '../animate/resolve-subjects.mjs';
|
||||
import { calculateRepeatDuration } from './utils/calc-repeat-duration.mjs';
|
||||
import { calcNextTime } from './utils/calc-time.mjs';
|
||||
import { addKeyframes } from './utils/edit.mjs';
|
||||
import { normalizeTimes } from './utils/normalize-times.mjs';
|
||||
import { compareByTime } from './utils/sort.mjs';
|
||||
|
||||
const defaultSegmentEasing = "easeInOut";
|
||||
const MAX_REPEAT = 20;
|
||||
function createAnimationsFromSequence(sequence, { defaultTransition = {}, ...sequenceTransition } = {}, scope, generators) {
|
||||
const defaultDuration = defaultTransition.duration || 0.3;
|
||||
const animationDefinitions = new Map();
|
||||
const sequences = new Map();
|
||||
const elementCache = {};
|
||||
const timeLabels = new Map();
|
||||
let prevTime = 0;
|
||||
let currentTime = 0;
|
||||
let totalDuration = 0;
|
||||
/**
|
||||
* Build the timeline by mapping over the sequence array and converting
|
||||
* the definitions into keyframes and offsets with absolute time values.
|
||||
* These will later get converted into relative offsets in a second pass.
|
||||
*/
|
||||
for (let i = 0; i < sequence.length; i++) {
|
||||
const segment = sequence[i];
|
||||
/**
|
||||
* If this is a timeline label, mark it and skip the rest of this iteration.
|
||||
*/
|
||||
if (typeof segment === "string") {
|
||||
timeLabels.set(segment, currentTime);
|
||||
continue;
|
||||
}
|
||||
else if (!Array.isArray(segment)) {
|
||||
timeLabels.set(segment.name, calcNextTime(currentTime, segment.at, prevTime, timeLabels));
|
||||
continue;
|
||||
}
|
||||
let [subject, keyframes, transition = {}] = segment;
|
||||
/**
|
||||
* If a relative or absolute time value has been specified we need to resolve
|
||||
* it in relation to the currentTime.
|
||||
*/
|
||||
if (transition.at !== undefined) {
|
||||
currentTime = calcNextTime(currentTime, transition.at, prevTime, timeLabels);
|
||||
}
|
||||
/**
|
||||
* Keep track of the maximum duration in this definition. This will be
|
||||
* applied to currentTime once the definition has been parsed.
|
||||
*/
|
||||
let maxDuration = 0;
|
||||
const resolveValueSequence = (valueKeyframes, valueTransition, valueSequence, elementIndex = 0, numSubjects = 0) => {
|
||||
const valueKeyframesAsList = keyframesAsList(valueKeyframes);
|
||||
const { delay = 0, times = defaultOffset(valueKeyframesAsList), type = "keyframes", repeat, repeatType, repeatDelay = 0, ...remainingTransition } = valueTransition;
|
||||
let { ease = defaultTransition.ease || "easeOut", duration } = valueTransition;
|
||||
/**
|
||||
* Resolve stagger() if defined.
|
||||
*/
|
||||
const calculatedDelay = typeof delay === "function"
|
||||
? delay(elementIndex, numSubjects)
|
||||
: delay;
|
||||
/**
|
||||
* If this animation should and can use a spring, generate a spring easing function.
|
||||
*/
|
||||
const numKeyframes = valueKeyframesAsList.length;
|
||||
const createGenerator = isGenerator(type)
|
||||
? type
|
||||
: generators?.[type || "keyframes"];
|
||||
if (numKeyframes <= 2 && createGenerator) {
|
||||
/**
|
||||
* As we're creating an easing function from a spring,
|
||||
* ideally we want to generate it using the real distance
|
||||
* between the two keyframes. However this isn't always
|
||||
* possible - in these situations we use 0-100.
|
||||
*/
|
||||
let absoluteDelta = 100;
|
||||
if (numKeyframes === 2 &&
|
||||
isNumberKeyframesArray(valueKeyframesAsList)) {
|
||||
const delta = valueKeyframesAsList[1] - valueKeyframesAsList[0];
|
||||
absoluteDelta = Math.abs(delta);
|
||||
}
|
||||
const springTransition = { ...remainingTransition };
|
||||
if (duration !== undefined) {
|
||||
springTransition.duration = secondsToMilliseconds(duration);
|
||||
}
|
||||
const springEasing = createGeneratorEasing(springTransition, absoluteDelta, createGenerator);
|
||||
ease = springEasing.ease;
|
||||
duration = springEasing.duration;
|
||||
}
|
||||
duration ?? (duration = defaultDuration);
|
||||
const startTime = currentTime + calculatedDelay;
|
||||
/**
|
||||
* If there's only one time offset of 0, fill in a second with length 1
|
||||
*/
|
||||
if (times.length === 1 && times[0] === 0) {
|
||||
times[1] = 1;
|
||||
}
|
||||
/**
|
||||
* Fill out if offset if fewer offsets than keyframes
|
||||
*/
|
||||
const remainder = times.length - valueKeyframesAsList.length;
|
||||
remainder > 0 && fillOffset(times, remainder);
|
||||
/**
|
||||
* If only one value has been set, ie [1], push a null to the start of
|
||||
* the keyframe array. This will let us mark a keyframe at this point
|
||||
* that will later be hydrated with the previous value.
|
||||
*/
|
||||
valueKeyframesAsList.length === 1 &&
|
||||
valueKeyframesAsList.unshift(null);
|
||||
/**
|
||||
* Handle repeat options
|
||||
*/
|
||||
if (repeat) {
|
||||
invariant(repeat < MAX_REPEAT, "Repeat count too high, must be less than 20", "repeat-count-high");
|
||||
duration = calculateRepeatDuration(duration, repeat);
|
||||
const originalKeyframes = [...valueKeyframesAsList];
|
||||
const originalTimes = [...times];
|
||||
ease = Array.isArray(ease) ? [...ease] : [ease];
|
||||
const originalEase = [...ease];
|
||||
for (let repeatIndex = 0; repeatIndex < repeat; repeatIndex++) {
|
||||
valueKeyframesAsList.push(...originalKeyframes);
|
||||
for (let keyframeIndex = 0; keyframeIndex < originalKeyframes.length; keyframeIndex++) {
|
||||
times.push(originalTimes[keyframeIndex] + (repeatIndex + 1));
|
||||
ease.push(keyframeIndex === 0
|
||||
? "linear"
|
||||
: getEasingForSegment(originalEase, keyframeIndex - 1));
|
||||
}
|
||||
}
|
||||
normalizeTimes(times, repeat);
|
||||
}
|
||||
const targetTime = startTime + duration;
|
||||
/**
|
||||
* Add keyframes, mapping offsets to absolute time.
|
||||
*/
|
||||
addKeyframes(valueSequence, valueKeyframesAsList, ease, times, startTime, targetTime);
|
||||
maxDuration = Math.max(calculatedDelay + duration, maxDuration);
|
||||
totalDuration = Math.max(targetTime, totalDuration);
|
||||
};
|
||||
if (isMotionValue(subject)) {
|
||||
const subjectSequence = getSubjectSequence(subject, sequences);
|
||||
resolveValueSequence(keyframes, transition, getValueSequence("default", subjectSequence));
|
||||
}
|
||||
else {
|
||||
const subjects = resolveSubjects(subject, keyframes, scope, elementCache);
|
||||
const numSubjects = subjects.length;
|
||||
/**
|
||||
* For every element in this segment, process the defined values.
|
||||
*/
|
||||
for (let subjectIndex = 0; subjectIndex < numSubjects; subjectIndex++) {
|
||||
/**
|
||||
* Cast necessary, but we know these are of this type
|
||||
*/
|
||||
keyframes = keyframes;
|
||||
transition = transition;
|
||||
const thisSubject = subjects[subjectIndex];
|
||||
const subjectSequence = getSubjectSequence(thisSubject, sequences);
|
||||
for (const key in keyframes) {
|
||||
resolveValueSequence(keyframes[key], getValueTransition(transition, key), getValueSequence(key, subjectSequence), subjectIndex, numSubjects);
|
||||
}
|
||||
}
|
||||
}
|
||||
prevTime = currentTime;
|
||||
currentTime += maxDuration;
|
||||
}
|
||||
/**
|
||||
* For every element and value combination create a new animation.
|
||||
*/
|
||||
sequences.forEach((valueSequences, element) => {
|
||||
for (const key in valueSequences) {
|
||||
const valueSequence = valueSequences[key];
|
||||
/**
|
||||
* Arrange all the keyframes in ascending time order.
|
||||
*/
|
||||
valueSequence.sort(compareByTime);
|
||||
const keyframes = [];
|
||||
const valueOffset = [];
|
||||
const valueEasing = [];
|
||||
/**
|
||||
* For each keyframe, translate absolute times into
|
||||
* relative offsets based on the total duration of the timeline.
|
||||
*/
|
||||
for (let i = 0; i < valueSequence.length; i++) {
|
||||
const { at, value, easing } = valueSequence[i];
|
||||
keyframes.push(value);
|
||||
valueOffset.push(progress(0, totalDuration, at));
|
||||
valueEasing.push(easing || "easeOut");
|
||||
}
|
||||
/**
|
||||
* If the first keyframe doesn't land on offset: 0
|
||||
* provide one by duplicating the initial keyframe. This ensures
|
||||
* it snaps to the first keyframe when the animation starts.
|
||||
*/
|
||||
if (valueOffset[0] !== 0) {
|
||||
valueOffset.unshift(0);
|
||||
keyframes.unshift(keyframes[0]);
|
||||
valueEasing.unshift(defaultSegmentEasing);
|
||||
}
|
||||
/**
|
||||
* If the last keyframe doesn't land on offset: 1
|
||||
* provide one with a null wildcard value. This will ensure it
|
||||
* stays static until the end of the animation.
|
||||
*/
|
||||
if (valueOffset[valueOffset.length - 1] !== 1) {
|
||||
valueOffset.push(1);
|
||||
keyframes.push(null);
|
||||
}
|
||||
if (!animationDefinitions.has(element)) {
|
||||
animationDefinitions.set(element, {
|
||||
keyframes: {},
|
||||
transition: {},
|
||||
});
|
||||
}
|
||||
const definition = animationDefinitions.get(element);
|
||||
definition.keyframes[key] = keyframes;
|
||||
definition.transition[key] = {
|
||||
...defaultTransition,
|
||||
duration: totalDuration,
|
||||
ease: valueEasing,
|
||||
times: valueOffset,
|
||||
...sequenceTransition,
|
||||
};
|
||||
}
|
||||
});
|
||||
return animationDefinitions;
|
||||
}
|
||||
function getSubjectSequence(subject, sequences) {
|
||||
!sequences.has(subject) && sequences.set(subject, {});
|
||||
return sequences.get(subject);
|
||||
}
|
||||
function getValueSequence(name, sequences) {
|
||||
if (!sequences[name])
|
||||
sequences[name] = [];
|
||||
return sequences[name];
|
||||
}
|
||||
function keyframesAsList(keyframes) {
|
||||
return Array.isArray(keyframes) ? keyframes : [keyframes];
|
||||
}
|
||||
function getValueTransition(transition, key) {
|
||||
return transition && transition[key]
|
||||
? {
|
||||
...transition,
|
||||
...transition[key],
|
||||
}
|
||||
: { ...transition };
|
||||
}
|
||||
const isNumber = (keyframe) => typeof keyframe === "number";
|
||||
const isNumberKeyframesArray = (keyframes) => keyframes.every(isNumber);
|
||||
|
||||
export { createAnimationsFromSequence, getValueTransition };
|
||||
5
node_modules/framer-motion/dist/es/animation/sequence/utils/calc-repeat-duration.mjs
generated
vendored
Normal file
5
node_modules/framer-motion/dist/es/animation/sequence/utils/calc-repeat-duration.mjs
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
function calculateRepeatDuration(duration, repeat, _repeatDelay) {
|
||||
return duration * (repeat + 1);
|
||||
}
|
||||
|
||||
export { calculateRepeatDuration };
|
||||
23
node_modules/framer-motion/dist/es/animation/sequence/utils/calc-time.mjs
generated
vendored
Normal file
23
node_modules/framer-motion/dist/es/animation/sequence/utils/calc-time.mjs
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Given a absolute or relative time definition and current/prev time state of the sequence,
|
||||
* calculate an absolute time for the next keyframes.
|
||||
*/
|
||||
function calcNextTime(current, next, prev, labels) {
|
||||
if (typeof next === "number") {
|
||||
return next;
|
||||
}
|
||||
else if (next.startsWith("-") || next.startsWith("+")) {
|
||||
return Math.max(0, current + parseFloat(next));
|
||||
}
|
||||
else if (next === "<") {
|
||||
return prev;
|
||||
}
|
||||
else if (next.startsWith("<")) {
|
||||
return Math.max(0, prev + parseFloat(next.slice(1)));
|
||||
}
|
||||
else {
|
||||
return labels.get(next) ?? current;
|
||||
}
|
||||
}
|
||||
|
||||
export { calcNextTime };
|
||||
30
node_modules/framer-motion/dist/es/animation/sequence/utils/edit.mjs
generated
vendored
Normal file
30
node_modules/framer-motion/dist/es/animation/sequence/utils/edit.mjs
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { mixNumber } from 'motion-dom';
|
||||
import { getEasingForSegment, removeItem } from 'motion-utils';
|
||||
|
||||
function eraseKeyframes(sequence, startTime, endTime) {
|
||||
for (let i = 0; i < sequence.length; i++) {
|
||||
const keyframe = sequence[i];
|
||||
if (keyframe.at > startTime && keyframe.at < endTime) {
|
||||
removeItem(sequence, keyframe);
|
||||
// If we remove this item we have to push the pointer back one
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
function addKeyframes(sequence, keyframes, easing, offset, startTime, endTime) {
|
||||
/**
|
||||
* Erase every existing value between currentTime and targetTime,
|
||||
* this will essentially splice this timeline into any currently
|
||||
* defined ones.
|
||||
*/
|
||||
eraseKeyframes(sequence, startTime, endTime);
|
||||
for (let i = 0; i < keyframes.length; i++) {
|
||||
sequence.push({
|
||||
value: keyframes[i],
|
||||
at: mixNumber(startTime, endTime, offset[i]),
|
||||
easing: getEasingForSegment(easing, i),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export { addKeyframes, eraseKeyframes };
|
||||
13
node_modules/framer-motion/dist/es/animation/sequence/utils/normalize-times.mjs
generated
vendored
Normal file
13
node_modules/framer-motion/dist/es/animation/sequence/utils/normalize-times.mjs
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Take an array of times that represent repeated keyframes. For instance
|
||||
* if we have original times of [0, 0.5, 1] then our repeated times will
|
||||
* be [0, 0.5, 1, 1, 1.5, 2]. Loop over the times and scale them back
|
||||
* down to a 0-1 scale.
|
||||
*/
|
||||
function normalizeTimes(times, repeat) {
|
||||
for (let i = 0; i < times.length; i++) {
|
||||
times[i] = times[i] / (repeat + 1);
|
||||
}
|
||||
}
|
||||
|
||||
export { normalizeTimes };
|
||||
14
node_modules/framer-motion/dist/es/animation/sequence/utils/sort.mjs
generated
vendored
Normal file
14
node_modules/framer-motion/dist/es/animation/sequence/utils/sort.mjs
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
function compareByTime(a, b) {
|
||||
if (a.at === b.at) {
|
||||
if (a.value === null)
|
||||
return 1;
|
||||
if (b.value === null)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return a.at - b.at;
|
||||
}
|
||||
}
|
||||
|
||||
export { compareByTime };
|
||||
15
node_modules/framer-motion/dist/es/animation/utils/calc-child-stagger.mjs
generated
vendored
Normal file
15
node_modules/framer-motion/dist/es/animation/utils/calc-child-stagger.mjs
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
function calcChildStagger(children, child, delayChildren, staggerChildren = 0, staggerDirection = 1) {
|
||||
const index = Array.from(children)
|
||||
.sort((a, b) => a.sortNodePosition(b))
|
||||
.indexOf(child);
|
||||
const numChildren = children.size;
|
||||
const maxStaggerDuration = (numChildren - 1) * staggerChildren;
|
||||
const delayIsFunction = typeof delayChildren === "function";
|
||||
return delayIsFunction
|
||||
? delayChildren(index, numChildren)
|
||||
: staggerDirection === 1
|
||||
? index * staggerChildren
|
||||
: maxStaggerDuration - index * staggerChildren;
|
||||
}
|
||||
|
||||
export { calcChildStagger };
|
||||
44
node_modules/framer-motion/dist/es/animation/utils/create-visual-element.mjs
generated
vendored
Normal file
44
node_modules/framer-motion/dist/es/animation/utils/create-visual-element.mjs
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
import { isSVGElement, isSVGSVGElement } from 'motion-dom';
|
||||
import { HTMLVisualElement } from '../../render/html/HTMLVisualElement.mjs';
|
||||
import { ObjectVisualElement } from '../../render/object/ObjectVisualElement.mjs';
|
||||
import { visualElementStore } from '../../render/store.mjs';
|
||||
import { SVGVisualElement } from '../../render/svg/SVGVisualElement.mjs';
|
||||
|
||||
function createDOMVisualElement(element) {
|
||||
const options = {
|
||||
presenceContext: null,
|
||||
props: {},
|
||||
visualState: {
|
||||
renderState: {
|
||||
transform: {},
|
||||
transformOrigin: {},
|
||||
style: {},
|
||||
vars: {},
|
||||
attrs: {},
|
||||
},
|
||||
latestValues: {},
|
||||
},
|
||||
};
|
||||
const node = isSVGElement(element) && !isSVGSVGElement(element)
|
||||
? new SVGVisualElement(options)
|
||||
: new HTMLVisualElement(options);
|
||||
node.mount(element);
|
||||
visualElementStore.set(element, node);
|
||||
}
|
||||
function createObjectVisualElement(subject) {
|
||||
const options = {
|
||||
presenceContext: null,
|
||||
props: {},
|
||||
visualState: {
|
||||
renderState: {
|
||||
output: {},
|
||||
},
|
||||
latestValues: {},
|
||||
},
|
||||
};
|
||||
const node = new ObjectVisualElement(options);
|
||||
node.mount(subject);
|
||||
visualElementStore.set(subject, node);
|
||||
}
|
||||
|
||||
export { createDOMVisualElement, createObjectVisualElement };
|
||||
40
node_modules/framer-motion/dist/es/animation/utils/default-transitions.mjs
generated
vendored
Normal file
40
node_modules/framer-motion/dist/es/animation/utils/default-transitions.mjs
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import { transformProps } from 'motion-dom';
|
||||
|
||||
const underDampedSpring = {
|
||||
type: "spring",
|
||||
stiffness: 500,
|
||||
damping: 25,
|
||||
restSpeed: 10,
|
||||
};
|
||||
const criticallyDampedSpring = (target) => ({
|
||||
type: "spring",
|
||||
stiffness: 550,
|
||||
damping: target === 0 ? 2 * Math.sqrt(550) : 30,
|
||||
restSpeed: 10,
|
||||
});
|
||||
const keyframesTransition = {
|
||||
type: "keyframes",
|
||||
duration: 0.8,
|
||||
};
|
||||
/**
|
||||
* Default easing curve is a slightly shallower version of
|
||||
* the default browser easing curve.
|
||||
*/
|
||||
const ease = {
|
||||
type: "keyframes",
|
||||
ease: [0.25, 0.1, 0.35, 1],
|
||||
duration: 0.3,
|
||||
};
|
||||
const getDefaultTransition = (valueKey, { keyframes }) => {
|
||||
if (keyframes.length > 2) {
|
||||
return keyframesTransition;
|
||||
}
|
||||
else if (transformProps.has(valueKey)) {
|
||||
return valueKey.startsWith("scale")
|
||||
? criticallyDampedSpring(keyframes[1])
|
||||
: underDampedSpring;
|
||||
}
|
||||
return ease;
|
||||
};
|
||||
|
||||
export { getDefaultTransition };
|
||||
7
node_modules/framer-motion/dist/es/animation/utils/is-animation-controls.mjs
generated
vendored
Normal file
7
node_modules/framer-motion/dist/es/animation/utils/is-animation-controls.mjs
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
function isAnimationControls(v) {
|
||||
return (v !== null &&
|
||||
typeof v === "object" &&
|
||||
typeof v.start === "function");
|
||||
}
|
||||
|
||||
export { isAnimationControls };
|
||||
5
node_modules/framer-motion/dist/es/animation/utils/is-dom-keyframes.mjs
generated
vendored
Normal file
5
node_modules/framer-motion/dist/es/animation/utils/is-dom-keyframes.mjs
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
function isDOMKeyframes(keyframes) {
|
||||
return typeof keyframes === "object" && !Array.isArray(keyframes);
|
||||
}
|
||||
|
||||
export { isDOMKeyframes };
|
||||
5
node_modules/framer-motion/dist/es/animation/utils/is-keyframes-target.mjs
generated
vendored
Normal file
5
node_modules/framer-motion/dist/es/animation/utils/is-keyframes-target.mjs
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const isKeyframesTarget = (v) => {
|
||||
return Array.isArray(v);
|
||||
};
|
||||
|
||||
export { isKeyframesTarget };
|
||||
10
node_modules/framer-motion/dist/es/animation/utils/is-transition-defined.mjs
generated
vendored
Normal file
10
node_modules/framer-motion/dist/es/animation/utils/is-transition-defined.mjs
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Decide whether a transition is defined on a given Transition.
|
||||
* This filters out orchestration options and returns true
|
||||
* if any options are left.
|
||||
*/
|
||||
function isTransitionDefined({ when, delay: _delay, delayChildren, staggerChildren, staggerDirection, repeat, repeatType, repeatDelay, from, elapsed, ...transition }) {
|
||||
return !!Object.keys(transition).length;
|
||||
}
|
||||
|
||||
export { isTransitionDefined };
|
||||
Reference in New Issue
Block a user