Initial commit
This commit is contained in:
21
node_modules/framer-motion/LICENSE.md
generated
vendored
Normal file
21
node_modules/framer-motion/LICENSE.md
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Framer B.V.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
128
node_modules/framer-motion/README.md
generated
vendored
Normal file
128
node_modules/framer-motion/README.md
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
<p align="center">
|
||||
<img width="100" height="100" alt="Motion logo" src="https://user-images.githubusercontent.com/7850794/164965523-3eced4c4-6020-467e-acde-f11b7900ad62.png" />
|
||||
</p>
|
||||
<h1 align="center">Motion for React</h1>
|
||||
|
||||
<br>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/framer-motion" target="_blank">
|
||||
<img src="https://img.shields.io/npm/v/framer-motion.svg?style=flat-square" />
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/framer-motion" target="_blank">
|
||||
<img src="https://img.shields.io/npm/dm/framer-motion.svg?style=flat-square" />
|
||||
</a>
|
||||
<a href="https://twitter.com/motiondotdev" target="_blank">
|
||||
<img src="https://img.shields.io/twitter/follow/framer.svg?style=social&label=Follow" />
|
||||
</a>
|
||||
<a href="https://discord.gg/DfkSpYe" target="_blank">
|
||||
<img src="https://img.shields.io/discord/308323056592486420.svg?logo=discord&logoColor=white" alt="Chat on Discord">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<br>
|
||||
|
||||
Motion for React is an open source, production-ready library that’s designed for all creative developers.
|
||||
|
||||
It's the only animation library with a hybrid engine, combining the power of JavaScript animations with the performance of native browser APIs.
|
||||
|
||||
It looks like this:
|
||||
|
||||
```jsx
|
||||
<motion.div animate={{ x: 0 }} />
|
||||
```
|
||||
|
||||
It does all this:
|
||||
|
||||
- [Springs](https://motion.dev/docs/react-transitions#spring)
|
||||
- [Keyframes](https://motion.dev/docs/react-animation#keyframes)
|
||||
- [Layout animations](https://motion.dev/docs/react-layout-animations)
|
||||
- [Shared layout animations](https://motion.dev/docs/react-layout-animations#shared-layout-animations)
|
||||
- [Gestures (drag/tap/hover)](https://motion.dev/docs/react-gestures)
|
||||
- [Scroll animations](https://motion.dev/docs/react-scroll-animations)
|
||||
- [SVG paths](https://motion.dev/docs/react-animation#svg-line-drawing)
|
||||
- [Exit animations](https://motion.dev/docs/react-animation#exit-animations)
|
||||
- [Server-side rendering](https://motion.dev/docs/react-motion-component#server-side-rendering)
|
||||
- [Independent transforms](https://motion.dev/docs/react-motion-component#style)
|
||||
- [Orchestrate animations across components](https://motion.dev/docs/react-animation#orchestration)
|
||||
- [CSS variables](https://motion.dev/docs/react-animation#css-variables)
|
||||
|
||||
...and a whole lot more.
|
||||
|
||||
## Get started
|
||||
|
||||
### 🐇 Quick start
|
||||
|
||||
Install `motion` via your package manager:
|
||||
|
||||
```
|
||||
npm install motion
|
||||
```
|
||||
|
||||
Then import the `motion` component:
|
||||
|
||||
```jsx
|
||||
import { motion } from "motion/react"
|
||||
|
||||
export function Component({ isVisible }) {
|
||||
return <motion.div animate={{ opacity: isVisible ? 1 : 0 }} />
|
||||
}
|
||||
```
|
||||
|
||||
### 💎 Contribute
|
||||
|
||||
- Want to contribute to Motion? Our [contributing guide](https://github.com/framer/motion/blob/master/CONTRIBUTING.md) has you covered.
|
||||
|
||||
### 👩🏻⚖️ License
|
||||
|
||||
- Motion for React is MIT licensed.
|
||||
|
||||
## ✨ Sponsors
|
||||
|
||||
Motion is sustainable thanks to the kind support of its sponsors.
|
||||
|
||||
### Partners
|
||||
|
||||
#### Framer
|
||||
|
||||
Motion powers Framer animations, the web builder for creative pros. Design and ship your dream site. Zero code, maximum speed.
|
||||
|
||||
<a href="https://www.framer.com?utm_source=motion-readme">
|
||||
<img alt="Framer" src="https://github.com/user-attachments/assets/0404c7a1-c29d-4785-89ae-aae315f3c759" width="300px" height="200px">
|
||||
</a>
|
||||
|
||||
### Platinum
|
||||
|
||||
<a href="https://tailwindcss.com"><img alt="Tailwind" src="https://github.com/user-attachments/assets/c0496f09-b8ee-4bc4-85ab-83a071bbbdec" width="300px" height="200px"></a>
|
||||
|
||||
<a href="https://emilkowal.ski"><img alt="Emil Kowalski" src="https://github.com/user-attachments/assets/29f56b1a-37fb-4695-a6a6-151f6c24864f" width="300px" height="200px"></a>
|
||||
|
||||
<a href="https://linear.app"><img alt="Linear" src="https://github.com/user-attachments/assets/a93710bb-d8ed-40e3-b0fb-1c5b3e2b16bb" width="300px" height="200px"></a>
|
||||
|
||||
### Gold
|
||||
|
||||
<a href="https://liveblocks.io"><img alt="Liveblocks" src="https://github.com/user-attachments/assets/31436a47-951e-4eab-9a68-bdd54ccf9444" width="225px" height="150px"></a>
|
||||
|
||||
### Silver
|
||||
|
||||
<a href="https://www.frontend.fyi/?utm_source=motion"><img alt="Frontend.fyi" src="https://github.com/user-attachments/assets/07d23aa5-69db-44a0-849d-90177e6fc817" width="150px" height="100px"></a>
|
||||
|
||||
<a href="https://statamic.com"><img alt="Statamic" src="https://github.com/user-attachments/assets/5d28f090-bdd9-4b31-b134-fb2b94ca636f" width="150px" height="100px"></a>
|
||||
|
||||
<a href="https://firecrawl.dev"><img alt="Firecrawl" src="https://github.com/user-attachments/assets/cba90e54-1329-4353-8fba-85beef4d2ee9" width="150px" height="100px"></a>
|
||||
|
||||
<a href="https://puzzmo.com"><img alt="Puzzmo" src="https://github.com/user-attachments/assets/aa2d5586-e5e2-43b9-8446-db456e4b0758" width="150px" height="100px"></a>
|
||||
|
||||
<a href="https://buildui.com"><img alt="Build UI" src="https://github.com/user-attachments/assets/024bfcd5-50e8-4b3d-a115-d5c6d6030d1c" width="150px" height="100px"></a>
|
||||
|
||||
<a href="https://hover.dev"><img alt="Hover" src="https://github.com/user-attachments/assets/4715b555-d2ac-4cb7-9f35-d36d708827b3" width="150px" height="100px"></a>
|
||||
|
||||
### Personal
|
||||
|
||||
- [Nusu](https://x.com/nusualabuga)
|
||||
- [OlegWock](https://sinja.io)
|
||||
- [Lambert Weller](https://github.com/l-mbert)
|
||||
- [Jake LeBoeuf](https://jklb.wf)
|
||||
- [Han Lee](https://github.com/hahnlee)
|
||||
1
node_modules/framer-motion/client/README.md
generated
vendored
Normal file
1
node_modules/framer-motion/client/README.md
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
This directory is a fallback for `exports["./client"]` in the root `framer-motion` `package.json`.
|
||||
6
node_modules/framer-motion/client/package.json
generated
vendored
Normal file
6
node_modules/framer-motion/client/package.json
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"types": "../dist/client.d.ts",
|
||||
"main": "../dist/cjs/client.js",
|
||||
"module": "../dist/es/client.mjs"
|
||||
}
|
||||
9998
node_modules/framer-motion/dist/cjs/client.js
generated
vendored
Normal file
9998
node_modules/framer-motion/dist/cjs/client.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
531
node_modules/framer-motion/dist/cjs/dom-mini.js
generated
vendored
Normal file
531
node_modules/framer-motion/dist/cjs/dom-mini.js
generated
vendored
Normal file
@ -0,0 +1,531 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var motionDom = require('motion-dom');
|
||||
var motionUtils = require('motion-utils');
|
||||
|
||||
function memo(callback) {
|
||||
let result;
|
||||
return () => {
|
||||
if (result === undefined)
|
||||
result = callback();
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
const supportsScrollTimeline = memo(() => window.ScrollTimeline !== undefined);
|
||||
|
||||
class GroupPlaybackControls {
|
||||
constructor(animations) {
|
||||
// Bound to accomodate common `return animation.stop` pattern
|
||||
this.stop = () => this.runAll("stop");
|
||||
this.animations = animations.filter(Boolean);
|
||||
}
|
||||
then(onResolve, onReject) {
|
||||
return Promise.all(this.animations).then(onResolve).catch(onReject);
|
||||
}
|
||||
/**
|
||||
* TODO: Filter out cancelled or stopped animations before returning
|
||||
*/
|
||||
getAll(propName) {
|
||||
return this.animations[0][propName];
|
||||
}
|
||||
setAll(propName, newValue) {
|
||||
for (let i = 0; i < this.animations.length; i++) {
|
||||
this.animations[i][propName] = newValue;
|
||||
}
|
||||
}
|
||||
attachTimeline(timeline, fallback) {
|
||||
const subscriptions = this.animations.map((animation) => {
|
||||
if (supportsScrollTimeline() && animation.attachTimeline) {
|
||||
return animation.attachTimeline(timeline);
|
||||
}
|
||||
else {
|
||||
return fallback(animation);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
subscriptions.forEach((cancel, i) => {
|
||||
cancel && cancel();
|
||||
this.animations[i].stop();
|
||||
});
|
||||
};
|
||||
}
|
||||
get time() {
|
||||
return this.getAll("time");
|
||||
}
|
||||
set time(time) {
|
||||
this.setAll("time", time);
|
||||
}
|
||||
get speed() {
|
||||
return this.getAll("speed");
|
||||
}
|
||||
set speed(speed) {
|
||||
this.setAll("speed", speed);
|
||||
}
|
||||
get startTime() {
|
||||
return this.getAll("startTime");
|
||||
}
|
||||
get duration() {
|
||||
let max = 0;
|
||||
for (let i = 0; i < this.animations.length; i++) {
|
||||
max = Math.max(max, this.animations[i].duration);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
runAll(methodName) {
|
||||
this.animations.forEach((controls) => controls[methodName]());
|
||||
}
|
||||
flatten() {
|
||||
this.runAll("flatten");
|
||||
}
|
||||
play() {
|
||||
this.runAll("play");
|
||||
}
|
||||
pause() {
|
||||
this.runAll("pause");
|
||||
}
|
||||
cancel() {
|
||||
this.runAll("cancel");
|
||||
}
|
||||
complete() {
|
||||
this.runAll("complete");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts seconds to milliseconds
|
||||
*
|
||||
* @param seconds - Time in seconds.
|
||||
* @return milliseconds - Converted time in milliseconds.
|
||||
*/
|
||||
const secondsToMilliseconds = (seconds) => seconds * 1000;
|
||||
const millisecondsToSeconds = (milliseconds) => milliseconds / 1000;
|
||||
|
||||
function getValueTransition(transition, key) {
|
||||
return transition
|
||||
? transition[key] ||
|
||||
transition["default"] ||
|
||||
transition
|
||||
: undefined;
|
||||
}
|
||||
|
||||
const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
|
||||
|
||||
/*
|
||||
Progress within given range
|
||||
|
||||
Given a lower limit and an upper limit, we return the progress
|
||||
(expressed as a number 0-1) represented by the given value, and
|
||||
limit that progress to within 0-1.
|
||||
|
||||
@param [number]: Lower limit
|
||||
@param [number]: Upper limit
|
||||
@param [number]: Value to find progress within given range
|
||||
@return [number]: Progress of value within range as expressed 0-1
|
||||
*/
|
||||
const progress = (from, to, value) => {
|
||||
const toFromDifference = to - from;
|
||||
return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
|
||||
};
|
||||
|
||||
const generateLinearEasing = (easing, duration, // as milliseconds
|
||||
resolution = 10 // as milliseconds
|
||||
) => {
|
||||
let points = "";
|
||||
const numPoints = Math.max(Math.round(duration / resolution), 2);
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
points += easing(progress(0, numPoints - 1, i)) + ", ";
|
||||
}
|
||||
return `linear(${points.substring(0, points.length - 2)})`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the ability for test suites to manually set support flags
|
||||
* to better test more environments.
|
||||
*/
|
||||
const supportsFlags = {
|
||||
linearEasing: undefined,
|
||||
};
|
||||
|
||||
function memoSupports(callback, supportsFlag) {
|
||||
const memoized = memo(callback);
|
||||
return () => { var _a; return (_a = supportsFlags[supportsFlag]) !== null && _a !== void 0 ? _a : memoized(); };
|
||||
}
|
||||
|
||||
const supportsLinearEasing = /*@__PURE__*/ memoSupports(() => {
|
||||
try {
|
||||
document
|
||||
.createElement("div")
|
||||
.animate({ opacity: 0 }, { easing: "linear(0, 1)" });
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, "linearEasing");
|
||||
|
||||
const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
|
||||
const supportedWaapiEasing = {
|
||||
linear: "linear",
|
||||
ease: "ease",
|
||||
easeIn: "ease-in",
|
||||
easeOut: "ease-out",
|
||||
easeInOut: "ease-in-out",
|
||||
circIn: /*@__PURE__*/ cubicBezierAsString([0, 0.65, 0.55, 1]),
|
||||
circOut: /*@__PURE__*/ cubicBezierAsString([0.55, 0, 1, 0.45]),
|
||||
backIn: /*@__PURE__*/ cubicBezierAsString([0.31, 0.01, 0.66, -0.59]),
|
||||
backOut: /*@__PURE__*/ cubicBezierAsString([0.33, 1.53, 0.69, 0.99]),
|
||||
};
|
||||
function mapEasingToNativeEasing(easing, duration) {
|
||||
if (!easing) {
|
||||
return undefined;
|
||||
}
|
||||
else if (typeof easing === "function" && supportsLinearEasing()) {
|
||||
return generateLinearEasing(easing, duration);
|
||||
}
|
||||
else if (isBezierDefinition(easing)) {
|
||||
return cubicBezierAsString(easing);
|
||||
}
|
||||
else if (Array.isArray(easing)) {
|
||||
return easing.map((segmentEasing) => mapEasingToNativeEasing(segmentEasing, duration) ||
|
||||
supportedWaapiEasing.easeOut);
|
||||
}
|
||||
else {
|
||||
return supportedWaapiEasing[easing];
|
||||
}
|
||||
}
|
||||
|
||||
function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duration = 300, repeat = 0, repeatType = "loop", ease = "easeInOut", times, } = {}) {
|
||||
const keyframeOptions = { [valueName]: keyframes };
|
||||
if (times)
|
||||
keyframeOptions.offset = times;
|
||||
const easing = mapEasingToNativeEasing(ease, duration);
|
||||
/**
|
||||
* If this is an easing array, apply to keyframes, not animation as a whole
|
||||
*/
|
||||
if (Array.isArray(easing))
|
||||
keyframeOptions.easing = easing;
|
||||
return element.animate(keyframeOptions, {
|
||||
delay,
|
||||
duration,
|
||||
easing: !Array.isArray(easing) ? easing : "linear",
|
||||
fill: "both",
|
||||
iterations: repeat + 1,
|
||||
direction: repeatType === "reverse" ? "alternate" : "normal",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement a practical max duration for keyframe generation
|
||||
* to prevent infinite loops
|
||||
*/
|
||||
const maxGeneratorDuration = 20000;
|
||||
function calcGeneratorDuration(generator) {
|
||||
let duration = 0;
|
||||
const timeStep = 50;
|
||||
let state = generator.next(duration);
|
||||
while (!state.done && duration < maxGeneratorDuration) {
|
||||
duration += timeStep;
|
||||
state = generator.next(duration);
|
||||
}
|
||||
return duration >= maxGeneratorDuration ? Infinity : duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a progress => progress easing function from a generator.
|
||||
*/
|
||||
function createGeneratorEasing(options, scale = 100, createGenerator) {
|
||||
const generator = createGenerator({ ...options, keyframes: [0, scale] });
|
||||
const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
|
||||
return {
|
||||
type: "keyframes",
|
||||
ease: (progress) => generator.next(duration * progress).value / scale,
|
||||
duration: millisecondsToSeconds(duration),
|
||||
};
|
||||
}
|
||||
|
||||
const createUnitType = (unit) => ({
|
||||
test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
|
||||
parse: parseFloat,
|
||||
transform: (v) => `${v}${unit}`,
|
||||
});
|
||||
const px = /*@__PURE__*/ createUnitType("px");
|
||||
|
||||
const browserNumberValueTypes = {
|
||||
// Border props
|
||||
borderWidth: px,
|
||||
borderTopWidth: px,
|
||||
borderRightWidth: px,
|
||||
borderBottomWidth: px,
|
||||
borderLeftWidth: px,
|
||||
borderRadius: px,
|
||||
radius: px,
|
||||
borderTopLeftRadius: px,
|
||||
borderTopRightRadius: px,
|
||||
borderBottomRightRadius: px,
|
||||
borderBottomLeftRadius: px,
|
||||
// Positioning props
|
||||
width: px,
|
||||
maxWidth: px,
|
||||
height: px,
|
||||
maxHeight: px,
|
||||
top: px,
|
||||
right: px,
|
||||
bottom: px,
|
||||
left: px,
|
||||
// Spacing props
|
||||
padding: px,
|
||||
paddingTop: px,
|
||||
paddingRight: px,
|
||||
paddingBottom: px,
|
||||
paddingLeft: px,
|
||||
margin: px,
|
||||
marginTop: px,
|
||||
marginRight: px,
|
||||
marginBottom: px,
|
||||
marginLeft: px,
|
||||
// Misc
|
||||
backgroundPositionX: px,
|
||||
backgroundPositionY: px,
|
||||
};
|
||||
|
||||
function isGenerator(type) {
|
||||
return typeof type === "function";
|
||||
}
|
||||
|
||||
function attachTimeline(animation, timeline) {
|
||||
animation.timeline = timeline;
|
||||
animation.onfinish = null;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function setCSSVar(element, name, value) {
|
||||
element.style.setProperty(`--${name}`, value);
|
||||
}
|
||||
function setStyle(element, name, value) {
|
||||
element.style[name] = value;
|
||||
}
|
||||
|
||||
const supportsPartialKeyframes = /*@__PURE__*/ memo(() => {
|
||||
try {
|
||||
document.createElement("div").animate({ opacity: [1] });
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const supportsWaapi = /*@__PURE__*/ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
|
||||
|
||||
const state = new WeakMap();
|
||||
function hydrateKeyframes(valueName, keyframes, read) {
|
||||
for (let i = 0; i < keyframes.length; i++) {
|
||||
if (keyframes[i] === null) {
|
||||
keyframes[i] = i === 0 ? read() : keyframes[i - 1];
|
||||
}
|
||||
if (typeof keyframes[i] === "number" &&
|
||||
browserNumberValueTypes[valueName]) {
|
||||
keyframes[i] = browserNumberValueTypes[valueName].transform(keyframes[i]);
|
||||
}
|
||||
}
|
||||
if (!supportsPartialKeyframes() && keyframes.length < 2) {
|
||||
keyframes.unshift(read());
|
||||
}
|
||||
}
|
||||
const defaultEasing = "easeOut";
|
||||
function getElementAnimationState(element) {
|
||||
const animationState = state.get(element) || new Map();
|
||||
state.set(element, animationState);
|
||||
return state.get(element);
|
||||
}
|
||||
class NativeAnimation {
|
||||
constructor(element, valueName, valueKeyframes, options) {
|
||||
const isCSSVar = valueName.startsWith("--");
|
||||
this.setValue = isCSSVar ? setCSSVar : setStyle;
|
||||
this.options = options;
|
||||
this.updateFinishedPromise();
|
||||
motionUtils.invariant(typeof options.type !== "string", `animateMini doesn't support "type" as a string. Did you mean to import { spring } from "framer-motion"?`);
|
||||
const existingAnimation = getElementAnimationState(element).get(valueName);
|
||||
existingAnimation && existingAnimation.stop();
|
||||
const readInitialKeyframe = () => {
|
||||
return valueName.startsWith("--")
|
||||
? element.style.getPropertyValue(valueName)
|
||||
: window.getComputedStyle(element)[valueName];
|
||||
};
|
||||
if (!Array.isArray(valueKeyframes)) {
|
||||
valueKeyframes = [valueKeyframes];
|
||||
}
|
||||
hydrateKeyframes(valueName, valueKeyframes, readInitialKeyframe);
|
||||
// TODO: Replace this with toString()?
|
||||
if (isGenerator(options.type)) {
|
||||
const generatorOptions = createGeneratorEasing(options, 100, options.type);
|
||||
options.ease = supportsLinearEasing()
|
||||
? generatorOptions.ease
|
||||
: defaultEasing;
|
||||
options.duration = secondsToMilliseconds(generatorOptions.duration);
|
||||
options.type = "keyframes";
|
||||
}
|
||||
else {
|
||||
options.ease = options.ease || defaultEasing;
|
||||
}
|
||||
this.removeAnimation = () => { var _a; return (_a = state.get(element)) === null || _a === void 0 ? void 0 : _a.delete(valueName); };
|
||||
const onFinish = () => {
|
||||
this.setValue(element, valueName, getFinalKeyframe(valueKeyframes, this.options));
|
||||
this.cancel();
|
||||
this.resolveFinishedPromise();
|
||||
};
|
||||
if (!supportsWaapi()) {
|
||||
onFinish();
|
||||
}
|
||||
else {
|
||||
this.animation = startWaapiAnimation(element, valueName, valueKeyframes, options);
|
||||
if (options.autoplay === false) {
|
||||
this.animation.pause();
|
||||
}
|
||||
this.animation.onfinish = onFinish;
|
||||
if (this.pendingTimeline) {
|
||||
attachTimeline(this.animation, this.pendingTimeline);
|
||||
}
|
||||
getElementAnimationState(element).set(valueName, this);
|
||||
}
|
||||
}
|
||||
get duration() {
|
||||
return millisecondsToSeconds(this.options.duration || 300);
|
||||
}
|
||||
get time() {
|
||||
var _a;
|
||||
if (this.animation) {
|
||||
return millisecondsToSeconds(((_a = this.animation) === null || _a === void 0 ? void 0 : _a.currentTime) || 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
set time(newTime) {
|
||||
if (this.animation) {
|
||||
this.animation.currentTime = secondsToMilliseconds(newTime);
|
||||
}
|
||||
}
|
||||
get speed() {
|
||||
return this.animation ? this.animation.playbackRate : 1;
|
||||
}
|
||||
set speed(newSpeed) {
|
||||
if (this.animation) {
|
||||
this.animation.playbackRate = newSpeed;
|
||||
}
|
||||
}
|
||||
get state() {
|
||||
return this.animation ? this.animation.playState : "finished";
|
||||
}
|
||||
get startTime() {
|
||||
return this.animation ? this.animation.startTime : null;
|
||||
}
|
||||
flatten() {
|
||||
var _a;
|
||||
if (!this.animation)
|
||||
return;
|
||||
(_a = this.animation.effect) === null || _a === void 0 ? void 0 : _a.updateTiming({ easing: "linear" });
|
||||
}
|
||||
play() {
|
||||
if (this.state === "finished") {
|
||||
this.updateFinishedPromise();
|
||||
}
|
||||
this.animation && this.animation.play();
|
||||
}
|
||||
pause() {
|
||||
this.animation && this.animation.pause();
|
||||
}
|
||||
stop() {
|
||||
if (!this.animation ||
|
||||
this.state === "idle" ||
|
||||
this.state === "finished") {
|
||||
return;
|
||||
}
|
||||
if (this.animation.commitStyles) {
|
||||
this.animation.commitStyles();
|
||||
}
|
||||
this.cancel();
|
||||
}
|
||||
complete() {
|
||||
this.animation && this.animation.finish();
|
||||
}
|
||||
cancel() {
|
||||
this.removeAnimation();
|
||||
try {
|
||||
this.animation && this.animation.cancel();
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
/**
|
||||
* Allows the returned animation to be awaited or promise-chained. Currently
|
||||
* resolves when the animation finishes at all but in a future update could/should
|
||||
* reject if its cancels.
|
||||
*/
|
||||
then(resolve, reject) {
|
||||
return this.currentFinishedPromise.then(resolve, reject);
|
||||
}
|
||||
updateFinishedPromise() {
|
||||
this.currentFinishedPromise = new Promise((resolve) => {
|
||||
this.resolveFinishedPromise = resolve;
|
||||
});
|
||||
}
|
||||
attachTimeline(timeline) {
|
||||
if (!this.animation) {
|
||||
this.pendingTimeline = timeline;
|
||||
}
|
||||
else {
|
||||
attachTimeline(this.animation, timeline);
|
||||
}
|
||||
return motionUtils.noop;
|
||||
}
|
||||
}
|
||||
|
||||
function animateElements(elementOrSelector, keyframes, options, scope) {
|
||||
const elements = motionDom.resolveElements(elementOrSelector, scope);
|
||||
const numElements = elements.length;
|
||||
motionUtils.invariant(Boolean(numElements), "No valid element provided.");
|
||||
const animations = [];
|
||||
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) {
|
||||
const valueKeyframes = keyframes[valueName];
|
||||
const valueOptions = {
|
||||
...getValueTransition(elementTransition, valueName),
|
||||
};
|
||||
valueOptions.duration = valueOptions.duration
|
||||
? secondsToMilliseconds(valueOptions.duration)
|
||||
: valueOptions.duration;
|
||||
valueOptions.delay = secondsToMilliseconds(valueOptions.delay || 0);
|
||||
animations.push(new NativeAnimation(element, valueName, valueKeyframes, valueOptions));
|
||||
}
|
||||
}
|
||||
return animations;
|
||||
}
|
||||
|
||||
const createScopedWaapiAnimate = (scope) => {
|
||||
function scopedAnimate(elementOrSelector, keyframes, options) {
|
||||
return new GroupPlaybackControls(animateElements(elementOrSelector, keyframes, options, scope));
|
||||
}
|
||||
return scopedAnimate;
|
||||
};
|
||||
const animateMini = /*@__PURE__*/ createScopedWaapiAnimate();
|
||||
|
||||
exports.animate = animateMini;
|
||||
6171
node_modules/framer-motion/dist/cjs/dom.js
generated
vendored
Normal file
6171
node_modules/framer-motion/dist/cjs/dom.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12956
node_modules/framer-motion/dist/cjs/index.js
generated
vendored
Normal file
12956
node_modules/framer-motion/dist/cjs/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1836
node_modules/framer-motion/dist/cjs/m.js
generated
vendored
Normal file
1836
node_modules/framer-motion/dist/cjs/m.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
562
node_modules/framer-motion/dist/cjs/mini.js
generated
vendored
Normal file
562
node_modules/framer-motion/dist/cjs/mini.js
generated
vendored
Normal file
@ -0,0 +1,562 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var react = require('react');
|
||||
var motionDom = require('motion-dom');
|
||||
var motionUtils = require('motion-utils');
|
||||
|
||||
/**
|
||||
* Creates a constant value over the lifecycle of a component.
|
||||
*
|
||||
* Even if `useMemo` is provided an empty array as its final argument, it doesn't offer
|
||||
* a guarantee that it won't re-run for performance reasons later on. By using `useConstant`
|
||||
* you can ensure that initialisers don't execute twice or more.
|
||||
*/
|
||||
function useConstant(init) {
|
||||
const ref = react.useRef(null);
|
||||
if (ref.current === null) {
|
||||
ref.current = init();
|
||||
}
|
||||
return ref.current;
|
||||
}
|
||||
|
||||
function useUnmountEffect(callback) {
|
||||
return react.useEffect(() => () => callback(), []);
|
||||
}
|
||||
|
||||
function memo(callback) {
|
||||
let result;
|
||||
return () => {
|
||||
if (result === undefined)
|
||||
result = callback();
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
const supportsScrollTimeline = memo(() => window.ScrollTimeline !== undefined);
|
||||
|
||||
class GroupPlaybackControls {
|
||||
constructor(animations) {
|
||||
// Bound to accomodate common `return animation.stop` pattern
|
||||
this.stop = () => this.runAll("stop");
|
||||
this.animations = animations.filter(Boolean);
|
||||
}
|
||||
then(onResolve, onReject) {
|
||||
return Promise.all(this.animations).then(onResolve).catch(onReject);
|
||||
}
|
||||
/**
|
||||
* TODO: Filter out cancelled or stopped animations before returning
|
||||
*/
|
||||
getAll(propName) {
|
||||
return this.animations[0][propName];
|
||||
}
|
||||
setAll(propName, newValue) {
|
||||
for (let i = 0; i < this.animations.length; i++) {
|
||||
this.animations[i][propName] = newValue;
|
||||
}
|
||||
}
|
||||
attachTimeline(timeline, fallback) {
|
||||
const subscriptions = this.animations.map((animation) => {
|
||||
if (supportsScrollTimeline() && animation.attachTimeline) {
|
||||
return animation.attachTimeline(timeline);
|
||||
}
|
||||
else {
|
||||
return fallback(animation);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
subscriptions.forEach((cancel, i) => {
|
||||
cancel && cancel();
|
||||
this.animations[i].stop();
|
||||
});
|
||||
};
|
||||
}
|
||||
get time() {
|
||||
return this.getAll("time");
|
||||
}
|
||||
set time(time) {
|
||||
this.setAll("time", time);
|
||||
}
|
||||
get speed() {
|
||||
return this.getAll("speed");
|
||||
}
|
||||
set speed(speed) {
|
||||
this.setAll("speed", speed);
|
||||
}
|
||||
get startTime() {
|
||||
return this.getAll("startTime");
|
||||
}
|
||||
get duration() {
|
||||
let max = 0;
|
||||
for (let i = 0; i < this.animations.length; i++) {
|
||||
max = Math.max(max, this.animations[i].duration);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
runAll(methodName) {
|
||||
this.animations.forEach((controls) => controls[methodName]());
|
||||
}
|
||||
flatten() {
|
||||
this.runAll("flatten");
|
||||
}
|
||||
play() {
|
||||
this.runAll("play");
|
||||
}
|
||||
pause() {
|
||||
this.runAll("pause");
|
||||
}
|
||||
cancel() {
|
||||
this.runAll("cancel");
|
||||
}
|
||||
complete() {
|
||||
this.runAll("complete");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts seconds to milliseconds
|
||||
*
|
||||
* @param seconds - Time in seconds.
|
||||
* @return milliseconds - Converted time in milliseconds.
|
||||
*/
|
||||
const secondsToMilliseconds = (seconds) => seconds * 1000;
|
||||
const millisecondsToSeconds = (milliseconds) => milliseconds / 1000;
|
||||
|
||||
function getValueTransition(transition, key) {
|
||||
return transition
|
||||
? transition[key] ||
|
||||
transition["default"] ||
|
||||
transition
|
||||
: undefined;
|
||||
}
|
||||
|
||||
const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
|
||||
|
||||
/*
|
||||
Progress within given range
|
||||
|
||||
Given a lower limit and an upper limit, we return the progress
|
||||
(expressed as a number 0-1) represented by the given value, and
|
||||
limit that progress to within 0-1.
|
||||
|
||||
@param [number]: Lower limit
|
||||
@param [number]: Upper limit
|
||||
@param [number]: Value to find progress within given range
|
||||
@return [number]: Progress of value within range as expressed 0-1
|
||||
*/
|
||||
const progress = (from, to, value) => {
|
||||
const toFromDifference = to - from;
|
||||
return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
|
||||
};
|
||||
|
||||
const generateLinearEasing = (easing, duration, // as milliseconds
|
||||
resolution = 10 // as milliseconds
|
||||
) => {
|
||||
let points = "";
|
||||
const numPoints = Math.max(Math.round(duration / resolution), 2);
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
points += easing(progress(0, numPoints - 1, i)) + ", ";
|
||||
}
|
||||
return `linear(${points.substring(0, points.length - 2)})`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the ability for test suites to manually set support flags
|
||||
* to better test more environments.
|
||||
*/
|
||||
const supportsFlags = {
|
||||
linearEasing: undefined,
|
||||
};
|
||||
|
||||
function memoSupports(callback, supportsFlag) {
|
||||
const memoized = memo(callback);
|
||||
return () => { var _a; return (_a = supportsFlags[supportsFlag]) !== null && _a !== void 0 ? _a : memoized(); };
|
||||
}
|
||||
|
||||
const supportsLinearEasing = /*@__PURE__*/ memoSupports(() => {
|
||||
try {
|
||||
document
|
||||
.createElement("div")
|
||||
.animate({ opacity: 0 }, { easing: "linear(0, 1)" });
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, "linearEasing");
|
||||
|
||||
const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
|
||||
const supportedWaapiEasing = {
|
||||
linear: "linear",
|
||||
ease: "ease",
|
||||
easeIn: "ease-in",
|
||||
easeOut: "ease-out",
|
||||
easeInOut: "ease-in-out",
|
||||
circIn: /*@__PURE__*/ cubicBezierAsString([0, 0.65, 0.55, 1]),
|
||||
circOut: /*@__PURE__*/ cubicBezierAsString([0.55, 0, 1, 0.45]),
|
||||
backIn: /*@__PURE__*/ cubicBezierAsString([0.31, 0.01, 0.66, -0.59]),
|
||||
backOut: /*@__PURE__*/ cubicBezierAsString([0.33, 1.53, 0.69, 0.99]),
|
||||
};
|
||||
function mapEasingToNativeEasing(easing, duration) {
|
||||
if (!easing) {
|
||||
return undefined;
|
||||
}
|
||||
else if (typeof easing === "function" && supportsLinearEasing()) {
|
||||
return generateLinearEasing(easing, duration);
|
||||
}
|
||||
else if (isBezierDefinition(easing)) {
|
||||
return cubicBezierAsString(easing);
|
||||
}
|
||||
else if (Array.isArray(easing)) {
|
||||
return easing.map((segmentEasing) => mapEasingToNativeEasing(segmentEasing, duration) ||
|
||||
supportedWaapiEasing.easeOut);
|
||||
}
|
||||
else {
|
||||
return supportedWaapiEasing[easing];
|
||||
}
|
||||
}
|
||||
|
||||
function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duration = 300, repeat = 0, repeatType = "loop", ease = "easeInOut", times, } = {}) {
|
||||
const keyframeOptions = { [valueName]: keyframes };
|
||||
if (times)
|
||||
keyframeOptions.offset = times;
|
||||
const easing = mapEasingToNativeEasing(ease, duration);
|
||||
/**
|
||||
* If this is an easing array, apply to keyframes, not animation as a whole
|
||||
*/
|
||||
if (Array.isArray(easing))
|
||||
keyframeOptions.easing = easing;
|
||||
return element.animate(keyframeOptions, {
|
||||
delay,
|
||||
duration,
|
||||
easing: !Array.isArray(easing) ? easing : "linear",
|
||||
fill: "both",
|
||||
iterations: repeat + 1,
|
||||
direction: repeatType === "reverse" ? "alternate" : "normal",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement a practical max duration for keyframe generation
|
||||
* to prevent infinite loops
|
||||
*/
|
||||
const maxGeneratorDuration = 20000;
|
||||
function calcGeneratorDuration(generator) {
|
||||
let duration = 0;
|
||||
const timeStep = 50;
|
||||
let state = generator.next(duration);
|
||||
while (!state.done && duration < maxGeneratorDuration) {
|
||||
duration += timeStep;
|
||||
state = generator.next(duration);
|
||||
}
|
||||
return duration >= maxGeneratorDuration ? Infinity : duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a progress => progress easing function from a generator.
|
||||
*/
|
||||
function createGeneratorEasing(options, scale = 100, createGenerator) {
|
||||
const generator = createGenerator({ ...options, keyframes: [0, scale] });
|
||||
const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
|
||||
return {
|
||||
type: "keyframes",
|
||||
ease: (progress) => generator.next(duration * progress).value / scale,
|
||||
duration: millisecondsToSeconds(duration),
|
||||
};
|
||||
}
|
||||
|
||||
const createUnitType = (unit) => ({
|
||||
test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
|
||||
parse: parseFloat,
|
||||
transform: (v) => `${v}${unit}`,
|
||||
});
|
||||
const px = /*@__PURE__*/ createUnitType("px");
|
||||
|
||||
const browserNumberValueTypes = {
|
||||
// Border props
|
||||
borderWidth: px,
|
||||
borderTopWidth: px,
|
||||
borderRightWidth: px,
|
||||
borderBottomWidth: px,
|
||||
borderLeftWidth: px,
|
||||
borderRadius: px,
|
||||
radius: px,
|
||||
borderTopLeftRadius: px,
|
||||
borderTopRightRadius: px,
|
||||
borderBottomRightRadius: px,
|
||||
borderBottomLeftRadius: px,
|
||||
// Positioning props
|
||||
width: px,
|
||||
maxWidth: px,
|
||||
height: px,
|
||||
maxHeight: px,
|
||||
top: px,
|
||||
right: px,
|
||||
bottom: px,
|
||||
left: px,
|
||||
// Spacing props
|
||||
padding: px,
|
||||
paddingTop: px,
|
||||
paddingRight: px,
|
||||
paddingBottom: px,
|
||||
paddingLeft: px,
|
||||
margin: px,
|
||||
marginTop: px,
|
||||
marginRight: px,
|
||||
marginBottom: px,
|
||||
marginLeft: px,
|
||||
// Misc
|
||||
backgroundPositionX: px,
|
||||
backgroundPositionY: px,
|
||||
};
|
||||
|
||||
function isGenerator(type) {
|
||||
return typeof type === "function";
|
||||
}
|
||||
|
||||
function attachTimeline(animation, timeline) {
|
||||
animation.timeline = timeline;
|
||||
animation.onfinish = null;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function setCSSVar(element, name, value) {
|
||||
element.style.setProperty(`--${name}`, value);
|
||||
}
|
||||
function setStyle(element, name, value) {
|
||||
element.style[name] = value;
|
||||
}
|
||||
|
||||
const supportsPartialKeyframes = /*@__PURE__*/ memo(() => {
|
||||
try {
|
||||
document.createElement("div").animate({ opacity: [1] });
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const supportsWaapi = /*@__PURE__*/ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
|
||||
|
||||
const state = new WeakMap();
|
||||
function hydrateKeyframes(valueName, keyframes, read) {
|
||||
for (let i = 0; i < keyframes.length; i++) {
|
||||
if (keyframes[i] === null) {
|
||||
keyframes[i] = i === 0 ? read() : keyframes[i - 1];
|
||||
}
|
||||
if (typeof keyframes[i] === "number" &&
|
||||
browserNumberValueTypes[valueName]) {
|
||||
keyframes[i] = browserNumberValueTypes[valueName].transform(keyframes[i]);
|
||||
}
|
||||
}
|
||||
if (!supportsPartialKeyframes() && keyframes.length < 2) {
|
||||
keyframes.unshift(read());
|
||||
}
|
||||
}
|
||||
const defaultEasing = "easeOut";
|
||||
function getElementAnimationState(element) {
|
||||
const animationState = state.get(element) || new Map();
|
||||
state.set(element, animationState);
|
||||
return state.get(element);
|
||||
}
|
||||
class NativeAnimation {
|
||||
constructor(element, valueName, valueKeyframes, options) {
|
||||
const isCSSVar = valueName.startsWith("--");
|
||||
this.setValue = isCSSVar ? setCSSVar : setStyle;
|
||||
this.options = options;
|
||||
this.updateFinishedPromise();
|
||||
motionUtils.invariant(typeof options.type !== "string", `animateMini doesn't support "type" as a string. Did you mean to import { spring } from "framer-motion"?`);
|
||||
const existingAnimation = getElementAnimationState(element).get(valueName);
|
||||
existingAnimation && existingAnimation.stop();
|
||||
const readInitialKeyframe = () => {
|
||||
return valueName.startsWith("--")
|
||||
? element.style.getPropertyValue(valueName)
|
||||
: window.getComputedStyle(element)[valueName];
|
||||
};
|
||||
if (!Array.isArray(valueKeyframes)) {
|
||||
valueKeyframes = [valueKeyframes];
|
||||
}
|
||||
hydrateKeyframes(valueName, valueKeyframes, readInitialKeyframe);
|
||||
// TODO: Replace this with toString()?
|
||||
if (isGenerator(options.type)) {
|
||||
const generatorOptions = createGeneratorEasing(options, 100, options.type);
|
||||
options.ease = supportsLinearEasing()
|
||||
? generatorOptions.ease
|
||||
: defaultEasing;
|
||||
options.duration = secondsToMilliseconds(generatorOptions.duration);
|
||||
options.type = "keyframes";
|
||||
}
|
||||
else {
|
||||
options.ease = options.ease || defaultEasing;
|
||||
}
|
||||
this.removeAnimation = () => { var _a; return (_a = state.get(element)) === null || _a === void 0 ? void 0 : _a.delete(valueName); };
|
||||
const onFinish = () => {
|
||||
this.setValue(element, valueName, getFinalKeyframe(valueKeyframes, this.options));
|
||||
this.cancel();
|
||||
this.resolveFinishedPromise();
|
||||
};
|
||||
if (!supportsWaapi()) {
|
||||
onFinish();
|
||||
}
|
||||
else {
|
||||
this.animation = startWaapiAnimation(element, valueName, valueKeyframes, options);
|
||||
if (options.autoplay === false) {
|
||||
this.animation.pause();
|
||||
}
|
||||
this.animation.onfinish = onFinish;
|
||||
if (this.pendingTimeline) {
|
||||
attachTimeline(this.animation, this.pendingTimeline);
|
||||
}
|
||||
getElementAnimationState(element).set(valueName, this);
|
||||
}
|
||||
}
|
||||
get duration() {
|
||||
return millisecondsToSeconds(this.options.duration || 300);
|
||||
}
|
||||
get time() {
|
||||
var _a;
|
||||
if (this.animation) {
|
||||
return millisecondsToSeconds(((_a = this.animation) === null || _a === void 0 ? void 0 : _a.currentTime) || 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
set time(newTime) {
|
||||
if (this.animation) {
|
||||
this.animation.currentTime = secondsToMilliseconds(newTime);
|
||||
}
|
||||
}
|
||||
get speed() {
|
||||
return this.animation ? this.animation.playbackRate : 1;
|
||||
}
|
||||
set speed(newSpeed) {
|
||||
if (this.animation) {
|
||||
this.animation.playbackRate = newSpeed;
|
||||
}
|
||||
}
|
||||
get state() {
|
||||
return this.animation ? this.animation.playState : "finished";
|
||||
}
|
||||
get startTime() {
|
||||
return this.animation ? this.animation.startTime : null;
|
||||
}
|
||||
flatten() {
|
||||
var _a;
|
||||
if (!this.animation)
|
||||
return;
|
||||
(_a = this.animation.effect) === null || _a === void 0 ? void 0 : _a.updateTiming({ easing: "linear" });
|
||||
}
|
||||
play() {
|
||||
if (this.state === "finished") {
|
||||
this.updateFinishedPromise();
|
||||
}
|
||||
this.animation && this.animation.play();
|
||||
}
|
||||
pause() {
|
||||
this.animation && this.animation.pause();
|
||||
}
|
||||
stop() {
|
||||
if (!this.animation ||
|
||||
this.state === "idle" ||
|
||||
this.state === "finished") {
|
||||
return;
|
||||
}
|
||||
if (this.animation.commitStyles) {
|
||||
this.animation.commitStyles();
|
||||
}
|
||||
this.cancel();
|
||||
}
|
||||
complete() {
|
||||
this.animation && this.animation.finish();
|
||||
}
|
||||
cancel() {
|
||||
this.removeAnimation();
|
||||
try {
|
||||
this.animation && this.animation.cancel();
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
/**
|
||||
* Allows the returned animation to be awaited or promise-chained. Currently
|
||||
* resolves when the animation finishes at all but in a future update could/should
|
||||
* reject if its cancels.
|
||||
*/
|
||||
then(resolve, reject) {
|
||||
return this.currentFinishedPromise.then(resolve, reject);
|
||||
}
|
||||
updateFinishedPromise() {
|
||||
this.currentFinishedPromise = new Promise((resolve) => {
|
||||
this.resolveFinishedPromise = resolve;
|
||||
});
|
||||
}
|
||||
attachTimeline(timeline) {
|
||||
if (!this.animation) {
|
||||
this.pendingTimeline = timeline;
|
||||
}
|
||||
else {
|
||||
attachTimeline(this.animation, timeline);
|
||||
}
|
||||
return motionUtils.noop;
|
||||
}
|
||||
}
|
||||
|
||||
function animateElements(elementOrSelector, keyframes, options, scope) {
|
||||
const elements = motionDom.resolveElements(elementOrSelector, scope);
|
||||
const numElements = elements.length;
|
||||
motionUtils.invariant(Boolean(numElements), "No valid element provided.");
|
||||
const animations = [];
|
||||
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) {
|
||||
const valueKeyframes = keyframes[valueName];
|
||||
const valueOptions = {
|
||||
...getValueTransition(elementTransition, valueName),
|
||||
};
|
||||
valueOptions.duration = valueOptions.duration
|
||||
? secondsToMilliseconds(valueOptions.duration)
|
||||
: valueOptions.duration;
|
||||
valueOptions.delay = secondsToMilliseconds(valueOptions.delay || 0);
|
||||
animations.push(new NativeAnimation(element, valueName, valueKeyframes, valueOptions));
|
||||
}
|
||||
}
|
||||
return animations;
|
||||
}
|
||||
|
||||
const createScopedWaapiAnimate = (scope) => {
|
||||
function scopedAnimate(elementOrSelector, keyframes, options) {
|
||||
return new GroupPlaybackControls(animateElements(elementOrSelector, keyframes, options, scope));
|
||||
}
|
||||
return scopedAnimate;
|
||||
};
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
exports.useAnimate = useAnimateMini;
|
||||
2603
node_modules/framer-motion/dist/client.d.ts
generated
vendored
Normal file
2603
node_modules/framer-motion/dist/client.d.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
433
node_modules/framer-motion/dist/dom-mini.d.ts
generated
vendored
Normal file
433
node_modules/framer-motion/dist/dom-mini.d.ts
generated
vendored
Normal file
@ -0,0 +1,433 @@
|
||||
import { ElementOrSelector } from 'motion-dom';
|
||||
|
||||
type EasingFunction = (v: number) => number;
|
||||
type BezierDefinition = readonly [number, number, number, number];
|
||||
type EasingDefinition = BezierDefinition | "linear" | "easeIn" | "easeOut" | "easeInOut" | "circIn" | "circOut" | "circInOut" | "backIn" | "backOut" | "backInOut" | "anticipate";
|
||||
/**
|
||||
* The easing function to use. Set as one of:
|
||||
*
|
||||
* - The name of an in-built easing function.
|
||||
* - An array of four numbers to define a cubic bezier curve.
|
||||
* - An easing function, that accepts and returns a progress value between `0` and `1`.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
type Easing = EasingDefinition | EasingFunction;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
interface SVGPathProperties {
|
||||
pathLength?: number;
|
||||
pathOffset?: number;
|
||||
pathSpacing?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* An update function. It accepts a timestamp used to advance the animation.
|
||||
*/
|
||||
type Update = (timestamp: number) => void;
|
||||
/**
|
||||
* Drivers accept a update function and call it at an interval. This interval
|
||||
* could be a synchronous loop, a setInterval, or tied to the device's framerate.
|
||||
*/
|
||||
interface DriverControls {
|
||||
start: () => void;
|
||||
stop: () => void;
|
||||
now: () => number;
|
||||
}
|
||||
type Driver = (update: Update) => DriverControls;
|
||||
|
||||
interface SVGAttributes {
|
||||
accentHeight?: number | string | undefined;
|
||||
accumulate?: "none" | "sum" | undefined;
|
||||
additive?: "replace" | "sum" | undefined;
|
||||
alignmentBaseline?: "auto" | "baseline" | "before-edge" | "text-before-edge" | "middle" | "central" | "after-edge" | "text-after-edge" | "ideographic" | "alphabetic" | "hanging" | "mathematical" | "inherit" | undefined;
|
||||
allowReorder?: "no" | "yes" | undefined;
|
||||
alphabetic?: number | string | undefined;
|
||||
amplitude?: number | string | undefined;
|
||||
arabicForm?: "initial" | "medial" | "terminal" | "isolated" | undefined;
|
||||
ascent?: number | string | undefined;
|
||||
attributeName?: string | undefined;
|
||||
attributeType?: string | undefined;
|
||||
autoReverse?: boolean | undefined;
|
||||
azimuth?: number | string | undefined;
|
||||
baseFrequency?: number | string | undefined;
|
||||
baselineShift?: number | string | undefined;
|
||||
baseProfile?: number | string | undefined;
|
||||
bbox?: number | string | undefined;
|
||||
begin?: number | string | undefined;
|
||||
bias?: number | string | undefined;
|
||||
by?: number | string | undefined;
|
||||
calcMode?: number | string | undefined;
|
||||
capHeight?: number | string | undefined;
|
||||
clip?: number | string | undefined;
|
||||
clipPath?: string | undefined;
|
||||
clipPathUnits?: number | string | undefined;
|
||||
clipRule?: number | string | undefined;
|
||||
colorInterpolation?: number | string | undefined;
|
||||
colorInterpolationFilters?: "auto" | "sRGB" | "linearRGB" | "inherit" | undefined;
|
||||
colorProfile?: number | string | undefined;
|
||||
colorRendering?: number | string | undefined;
|
||||
contentScriptType?: number | string | undefined;
|
||||
contentStyleType?: number | string | undefined;
|
||||
cursor?: number | string | undefined;
|
||||
cx?: number | string | undefined;
|
||||
cy?: number | string | undefined;
|
||||
d?: string | undefined;
|
||||
decelerate?: number | string | undefined;
|
||||
descent?: number | string | undefined;
|
||||
diffuseConstant?: number | string | undefined;
|
||||
direction?: number | string | undefined;
|
||||
display?: number | string | undefined;
|
||||
divisor?: number | string | undefined;
|
||||
dominantBaseline?: number | string | undefined;
|
||||
dur?: number | string | undefined;
|
||||
dx?: number | string | undefined;
|
||||
dy?: number | string | undefined;
|
||||
edgeMode?: number | string | undefined;
|
||||
elevation?: number | string | undefined;
|
||||
enableBackground?: number | string | undefined;
|
||||
end?: number | string | undefined;
|
||||
exponent?: number | string | undefined;
|
||||
externalResourcesRequired?: boolean | undefined;
|
||||
fill?: string | undefined;
|
||||
fillOpacity?: number | string | undefined;
|
||||
fillRule?: "nonzero" | "evenodd" | "inherit" | undefined;
|
||||
filter?: string | undefined;
|
||||
filterRes?: number | string | undefined;
|
||||
filterUnits?: number | string | undefined;
|
||||
floodColor?: number | string | undefined;
|
||||
floodOpacity?: number | string | undefined;
|
||||
focusable?: boolean | "auto" | undefined;
|
||||
fontFamily?: string | undefined;
|
||||
fontSize?: number | string | undefined;
|
||||
fontSizeAdjust?: number | string | undefined;
|
||||
fontStretch?: number | string | undefined;
|
||||
fontStyle?: number | string | undefined;
|
||||
fontVariant?: number | string | undefined;
|
||||
fontWeight?: number | string | undefined;
|
||||
format?: number | string | undefined;
|
||||
fr?: number | string | undefined;
|
||||
from?: number | string | undefined;
|
||||
fx?: number | string | undefined;
|
||||
fy?: number | string | undefined;
|
||||
g1?: number | string | undefined;
|
||||
g2?: number | string | undefined;
|
||||
glyphName?: number | string | undefined;
|
||||
glyphOrientationHorizontal?: number | string | undefined;
|
||||
glyphOrientationVertical?: number | string | undefined;
|
||||
glyphRef?: number | string | undefined;
|
||||
gradientTransform?: string | undefined;
|
||||
gradientUnits?: string | undefined;
|
||||
hanging?: number | string | undefined;
|
||||
horizAdvX?: number | string | undefined;
|
||||
horizOriginX?: number | string | undefined;
|
||||
href?: string | undefined;
|
||||
ideographic?: number | string | undefined;
|
||||
imageRendering?: number | string | undefined;
|
||||
in2?: number | string | undefined;
|
||||
in?: string | undefined;
|
||||
intercept?: number | string | undefined;
|
||||
k1?: number | string | undefined;
|
||||
k2?: number | string | undefined;
|
||||
k3?: number | string | undefined;
|
||||
k4?: number | string | undefined;
|
||||
k?: number | string | undefined;
|
||||
kernelMatrix?: number | string | undefined;
|
||||
kernelUnitLength?: number | string | undefined;
|
||||
kerning?: number | string | undefined;
|
||||
keyPoints?: number | string | undefined;
|
||||
keySplines?: number | string | undefined;
|
||||
keyTimes?: number | string | undefined;
|
||||
lengthAdjust?: number | string | undefined;
|
||||
letterSpacing?: number | string | undefined;
|
||||
lightingColor?: number | string | undefined;
|
||||
limitingConeAngle?: number | string | undefined;
|
||||
local?: number | string | undefined;
|
||||
markerEnd?: string | undefined;
|
||||
markerHeight?: number | string | undefined;
|
||||
markerMid?: string | undefined;
|
||||
markerStart?: string | undefined;
|
||||
markerUnits?: number | string | undefined;
|
||||
markerWidth?: number | string | undefined;
|
||||
mask?: string | undefined;
|
||||
maskContentUnits?: number | string | undefined;
|
||||
maskUnits?: number | string | undefined;
|
||||
mathematical?: number | string | undefined;
|
||||
mode?: number | string | undefined;
|
||||
numOctaves?: number | string | undefined;
|
||||
offset?: number | string | undefined;
|
||||
opacity?: number | string | undefined;
|
||||
operator?: number | string | undefined;
|
||||
order?: number | string | undefined;
|
||||
orient?: number | string | undefined;
|
||||
orientation?: number | string | undefined;
|
||||
origin?: number | string | undefined;
|
||||
overflow?: number | string | undefined;
|
||||
overlinePosition?: number | string | undefined;
|
||||
overlineThickness?: number | string | undefined;
|
||||
paintOrder?: number | string | undefined;
|
||||
panose1?: number | string | undefined;
|
||||
path?: string | undefined;
|
||||
pathLength?: number | string | undefined;
|
||||
patternContentUnits?: string | undefined;
|
||||
patternTransform?: number | string | undefined;
|
||||
patternUnits?: string | undefined;
|
||||
pointerEvents?: number | string | undefined;
|
||||
points?: string | undefined;
|
||||
pointsAtX?: number | string | undefined;
|
||||
pointsAtY?: number | string | undefined;
|
||||
pointsAtZ?: number | string | undefined;
|
||||
preserveAlpha?: boolean | undefined;
|
||||
preserveAspectRatio?: string | undefined;
|
||||
primitiveUnits?: number | string | undefined;
|
||||
r?: number | string | undefined;
|
||||
radius?: number | string | undefined;
|
||||
refX?: number | string | undefined;
|
||||
refY?: number | string | undefined;
|
||||
renderingIntent?: number | string | undefined;
|
||||
repeatCount?: number | string | undefined;
|
||||
repeatDur?: number | string | undefined;
|
||||
requiredExtensions?: number | string | undefined;
|
||||
requiredFeatures?: number | string | undefined;
|
||||
restart?: number | string | undefined;
|
||||
result?: string | undefined;
|
||||
rotate?: number | string | undefined;
|
||||
rx?: number | string | undefined;
|
||||
ry?: number | string | undefined;
|
||||
scale?: number | string | undefined;
|
||||
seed?: number | string | undefined;
|
||||
shapeRendering?: number | string | undefined;
|
||||
slope?: number | string | undefined;
|
||||
spacing?: number | string | undefined;
|
||||
specularConstant?: number | string | undefined;
|
||||
specularExponent?: number | string | undefined;
|
||||
speed?: number | string | undefined;
|
||||
spreadMethod?: string | undefined;
|
||||
startOffset?: number | string | undefined;
|
||||
stdDeviation?: number | string | undefined;
|
||||
stemh?: number | string | undefined;
|
||||
stemv?: number | string | undefined;
|
||||
stitchTiles?: number | string | undefined;
|
||||
stopColor?: string | undefined;
|
||||
stopOpacity?: number | string | undefined;
|
||||
strikethroughPosition?: number | string | undefined;
|
||||
strikethroughThickness?: number | string | undefined;
|
||||
string?: number | string | undefined;
|
||||
stroke?: string | undefined;
|
||||
strokeDasharray?: string | number | undefined;
|
||||
strokeDashoffset?: string | number | undefined;
|
||||
strokeLinecap?: "butt" | "round" | "square" | "inherit" | undefined;
|
||||
strokeLinejoin?: "miter" | "round" | "bevel" | "inherit" | undefined;
|
||||
strokeMiterlimit?: number | string | undefined;
|
||||
strokeOpacity?: number | string | undefined;
|
||||
strokeWidth?: number | string | undefined;
|
||||
surfaceScale?: number | string | undefined;
|
||||
systemLanguage?: number | string | undefined;
|
||||
tableValues?: number | string | undefined;
|
||||
targetX?: number | string | undefined;
|
||||
targetY?: number | string | undefined;
|
||||
textAnchor?: string | undefined;
|
||||
textDecoration?: number | string | undefined;
|
||||
textLength?: number | string | undefined;
|
||||
textRendering?: number | string | undefined;
|
||||
to?: number | string | undefined;
|
||||
transform?: string | undefined;
|
||||
u1?: number | string | undefined;
|
||||
u2?: number | string | undefined;
|
||||
underlinePosition?: number | string | undefined;
|
||||
underlineThickness?: number | string | undefined;
|
||||
unicode?: number | string | undefined;
|
||||
unicodeBidi?: number | string | undefined;
|
||||
unicodeRange?: number | string | undefined;
|
||||
unitsPerEm?: number | string | undefined;
|
||||
vAlphabetic?: number | string | undefined;
|
||||
values?: string | undefined;
|
||||
vectorEffect?: number | string | undefined;
|
||||
version?: string | undefined;
|
||||
vertAdvY?: number | string | undefined;
|
||||
vertOriginX?: number | string | undefined;
|
||||
vertOriginY?: number | string | undefined;
|
||||
vHanging?: number | string | undefined;
|
||||
vIdeographic?: number | string | undefined;
|
||||
viewBox?: string | undefined;
|
||||
viewTarget?: number | string | undefined;
|
||||
visibility?: number | string | undefined;
|
||||
vMathematical?: number | string | undefined;
|
||||
widths?: number | string | undefined;
|
||||
wordSpacing?: number | string | undefined;
|
||||
writingMode?: number | string | undefined;
|
||||
x1?: number | string | undefined;
|
||||
x2?: number | string | undefined;
|
||||
x?: number | string | undefined;
|
||||
xChannelSelector?: string | undefined;
|
||||
xHeight?: number | string | undefined;
|
||||
xlinkActuate?: string | undefined;
|
||||
xlinkArcrole?: string | undefined;
|
||||
xlinkHref?: string | undefined;
|
||||
xlinkRole?: string | undefined;
|
||||
xlinkShow?: string | undefined;
|
||||
xlinkTitle?: string | undefined;
|
||||
xlinkType?: string | undefined;
|
||||
xmlBase?: string | undefined;
|
||||
xmlLang?: string | undefined;
|
||||
xmlns?: string | undefined;
|
||||
xmlnsXlink?: string | undefined;
|
||||
xmlSpace?: string | undefined;
|
||||
y1?: number | string | undefined;
|
||||
y2?: number | string | undefined;
|
||||
y?: number | string | undefined;
|
||||
yChannelSelector?: string | undefined;
|
||||
z?: number | string | undefined;
|
||||
zoomAndPan?: string | undefined;
|
||||
}
|
||||
|
||||
interface ProgressTimeline {
|
||||
currentTime: null | {
|
||||
value: number;
|
||||
};
|
||||
cancel?: VoidFunction;
|
||||
}
|
||||
|
||||
interface AnimationState<V> {
|
||||
value: V;
|
||||
done: boolean;
|
||||
}
|
||||
interface KeyframeGenerator<V> {
|
||||
calculatedDuration: null | number;
|
||||
next: (t: number) => AnimationState<V>;
|
||||
toString: () => string;
|
||||
}
|
||||
|
||||
interface AnimationPlaybackLifecycles<V> {
|
||||
onUpdate?: (latest: V) => void;
|
||||
onPlay?: () => void;
|
||||
onComplete?: () => void;
|
||||
onRepeat?: () => void;
|
||||
onStop?: () => void;
|
||||
}
|
||||
type GeneratorFactory = (options: ValueAnimationOptions<any>) => KeyframeGenerator<any>;
|
||||
type AnimationGeneratorType = GeneratorFactory | "decay" | "spring" | "keyframes" | "tween" | "inertia";
|
||||
interface Transition extends AnimationPlaybackOptions, Omit<SpringOptions, "keyframes">, Omit<InertiaOptions, "keyframes">, KeyframeOptions {
|
||||
delay?: number;
|
||||
elapsed?: number;
|
||||
driver?: Driver;
|
||||
type?: AnimationGeneratorType;
|
||||
duration?: number;
|
||||
autoplay?: boolean;
|
||||
startTime?: number;
|
||||
}
|
||||
interface ValueAnimationTransition<V = any> extends Transition, AnimationPlaybackLifecycles<V> {
|
||||
}
|
||||
interface ValueAnimationOptions<V extends string | number = number> extends ValueAnimationTransition {
|
||||
keyframes: V[];
|
||||
name?: string;
|
||||
from?: V;
|
||||
isGenerator?: boolean;
|
||||
}
|
||||
type StyleTransitions = {
|
||||
[K in keyof CSSStyleDeclarationWithTransform]?: Transition;
|
||||
};
|
||||
type SVGPathTransitions = {
|
||||
[K in keyof SVGPathProperties]: Transition;
|
||||
};
|
||||
type SVGTransitions = {
|
||||
[K in keyof SVGAttributes]: Transition;
|
||||
};
|
||||
type VariableTransitions = {
|
||||
[key: `--${string}`]: Transition;
|
||||
};
|
||||
type AnimationOptionsWithValueOverrides<V = any> = StyleTransitions & SVGPathTransitions & SVGTransitions & VariableTransitions & ValueAnimationTransition<V>;
|
||||
interface DynamicAnimationOptions extends Omit<AnimationOptionsWithValueOverrides, "delay"> {
|
||||
delay?: number | DynamicOption<number>;
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
interface AnimationPlaybackControls {
|
||||
time: number;
|
||||
speed: number;
|
||||
startTime: number | null;
|
||||
state?: AnimationPlayState;
|
||||
duration: number;
|
||||
stop: () => void;
|
||||
play: () => void;
|
||||
pause: () => void;
|
||||
complete: () => void;
|
||||
cancel: () => void;
|
||||
then: (onResolve: VoidFunction, onReject?: VoidFunction) => Promise<void>;
|
||||
attachTimeline?: (timeline: ProgressTimeline, fallback?: (animation: AnimationPlaybackControls) => VoidFunction) => VoidFunction;
|
||||
flatten: () => void;
|
||||
}
|
||||
type DynamicOption<T> = (i: number, total: number) => T;
|
||||
interface CSSStyleDeclarationWithTransform extends Omit<CSSStyleDeclaration, "direction" | "transition" | "x" | "y" | "z"> {
|
||||
x: number | string;
|
||||
y: number | string;
|
||||
z: number | string;
|
||||
rotateX: number | string;
|
||||
rotateY: number | string;
|
||||
rotateZ: number | string;
|
||||
scaleX: number;
|
||||
scaleY: number;
|
||||
scaleZ: number;
|
||||
skewX: number | string;
|
||||
skewY: number | string;
|
||||
}
|
||||
type ValueKeyframe = string | number;
|
||||
type UnresolvedValueKeyframe = ValueKeyframe | null;
|
||||
type ValueKeyframesDefinition = ValueKeyframe | ValueKeyframe[] | UnresolvedValueKeyframe[];
|
||||
type StyleKeyframesDefinition = {
|
||||
[K in keyof CSSStyleDeclarationWithTransform]?: ValueKeyframesDefinition;
|
||||
};
|
||||
type SVGKeyframesDefinition = {
|
||||
[K in keyof SVGAttributes]?: ValueKeyframesDefinition;
|
||||
};
|
||||
type VariableKeyframesDefinition = {
|
||||
[key: `--${string}`]: ValueKeyframesDefinition;
|
||||
};
|
||||
type SVGPathKeyframesDefinition = {
|
||||
[K in keyof SVGPathProperties]?: ValueKeyframesDefinition;
|
||||
};
|
||||
type DOMKeyframesDefinition = StyleKeyframesDefinition & SVGKeyframesDefinition & SVGPathKeyframesDefinition & VariableKeyframesDefinition;
|
||||
interface VelocityOptions {
|
||||
velocity?: number;
|
||||
restSpeed?: number;
|
||||
restDelta?: number;
|
||||
}
|
||||
type RepeatType = "loop" | "reverse" | "mirror";
|
||||
interface AnimationPlaybackOptions {
|
||||
repeat?: number;
|
||||
repeatType?: RepeatType;
|
||||
repeatDelay?: number;
|
||||
}
|
||||
interface DurationSpringOptions {
|
||||
duration?: number;
|
||||
visualDuration?: number;
|
||||
bounce?: number;
|
||||
}
|
||||
interface SpringOptions extends DurationSpringOptions, VelocityOptions {
|
||||
stiffness?: number;
|
||||
damping?: number;
|
||||
mass?: number;
|
||||
}
|
||||
interface DecayOptions extends VelocityOptions {
|
||||
keyframes?: number[];
|
||||
power?: number;
|
||||
timeConstant?: number;
|
||||
modifyTarget?: (v: number) => number;
|
||||
}
|
||||
interface InertiaOptions extends DecayOptions {
|
||||
bounceStiffness?: number;
|
||||
bounceDamping?: number;
|
||||
min?: number;
|
||||
max?: number;
|
||||
}
|
||||
interface KeyframeOptions {
|
||||
ease?: Easing | Easing[];
|
||||
times?: number[];
|
||||
}
|
||||
|
||||
declare const animateMini: (elementOrSelector: ElementOrSelector, keyframes: DOMKeyframesDefinition, options?: DynamicAnimationOptions) => AnimationPlaybackControls;
|
||||
|
||||
export { animateMini as animate };
|
||||
1
node_modules/framer-motion/dist/dom-mini.js
generated
vendored
Normal file
1
node_modules/framer-motion/dist/dom-mini.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1007
node_modules/framer-motion/dist/dom.d.ts
generated
vendored
Normal file
1007
node_modules/framer-motion/dist/dom.d.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/framer-motion/dist/dom.js
generated
vendored
Normal file
1
node_modules/framer-motion/dist/dom.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
81
node_modules/framer-motion/dist/es/animation/GroupPlaybackControls.mjs
generated
vendored
Normal file
81
node_modules/framer-motion/dist/es/animation/GroupPlaybackControls.mjs
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
import { supportsScrollTimeline } from '../render/dom/scroll/supports.mjs';
|
||||
|
||||
class GroupPlaybackControls {
|
||||
constructor(animations) {
|
||||
// Bound to accomodate common `return animation.stop` pattern
|
||||
this.stop = () => this.runAll("stop");
|
||||
this.animations = animations.filter(Boolean);
|
||||
}
|
||||
then(onResolve, onReject) {
|
||||
return Promise.all(this.animations).then(onResolve).catch(onReject);
|
||||
}
|
||||
/**
|
||||
* TODO: Filter out cancelled or stopped animations before returning
|
||||
*/
|
||||
getAll(propName) {
|
||||
return this.animations[0][propName];
|
||||
}
|
||||
setAll(propName, newValue) {
|
||||
for (let i = 0; i < this.animations.length; i++) {
|
||||
this.animations[i][propName] = newValue;
|
||||
}
|
||||
}
|
||||
attachTimeline(timeline, fallback) {
|
||||
const subscriptions = this.animations.map((animation) => {
|
||||
if (supportsScrollTimeline() && animation.attachTimeline) {
|
||||
return animation.attachTimeline(timeline);
|
||||
}
|
||||
else {
|
||||
return fallback(animation);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
subscriptions.forEach((cancel, i) => {
|
||||
cancel && cancel();
|
||||
this.animations[i].stop();
|
||||
});
|
||||
};
|
||||
}
|
||||
get time() {
|
||||
return this.getAll("time");
|
||||
}
|
||||
set time(time) {
|
||||
this.setAll("time", time);
|
||||
}
|
||||
get speed() {
|
||||
return this.getAll("speed");
|
||||
}
|
||||
set speed(speed) {
|
||||
this.setAll("speed", speed);
|
||||
}
|
||||
get startTime() {
|
||||
return this.getAll("startTime");
|
||||
}
|
||||
get duration() {
|
||||
let max = 0;
|
||||
for (let i = 0; i < this.animations.length; i++) {
|
||||
max = Math.max(max, this.animations[i].duration);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
runAll(methodName) {
|
||||
this.animations.forEach((controls) => controls[methodName]());
|
||||
}
|
||||
flatten() {
|
||||
this.runAll("flatten");
|
||||
}
|
||||
play() {
|
||||
this.runAll("play");
|
||||
}
|
||||
pause() {
|
||||
this.runAll("pause");
|
||||
}
|
||||
cancel() {
|
||||
this.runAll("cancel");
|
||||
}
|
||||
complete() {
|
||||
this.runAll("complete");
|
||||
}
|
||||
}
|
||||
|
||||
export { GroupPlaybackControls };
|
||||
34
node_modules/framer-motion/dist/es/animation/animate/index.mjs
generated
vendored
Normal file
34
node_modules/framer-motion/dist/es/animation/animate/index.mjs
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
import { GroupPlaybackControls } from '../GroupPlaybackControls.mjs';
|
||||
import { animateSequence } from './sequence.mjs';
|
||||
import { animateSubject } from './subject.mjs';
|
||||
|
||||
function isSequence(value) {
|
||||
return Array.isArray(value) && Array.isArray(value[0]);
|
||||
}
|
||||
/**
|
||||
* Creates an animation function that is optionally scoped
|
||||
* to a specific element.
|
||||
*/
|
||||
function createScopedAnimate(scope) {
|
||||
/**
|
||||
* Implementation
|
||||
*/
|
||||
function scopedAnimate(subjectOrSequence, optionsOrKeyframes, options) {
|
||||
let animations = [];
|
||||
if (isSequence(subjectOrSequence)) {
|
||||
animations = animateSequence(subjectOrSequence, optionsOrKeyframes, scope);
|
||||
}
|
||||
else {
|
||||
animations = animateSubject(subjectOrSequence, optionsOrKeyframes, options, scope);
|
||||
}
|
||||
const animation = new GroupPlaybackControls(animations);
|
||||
if (scope) {
|
||||
scope.animations.push(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 '../generators/spring/index.mjs';
|
||||
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 };
|
||||
11
node_modules/framer-motion/dist/es/animation/animate/single-value.mjs
generated
vendored
Normal file
11
node_modules/framer-motion/dist/es/animation/animate/single-value.mjs
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { animateMotionValue } from '../interfaces/motion-value.mjs';
|
||||
import { motionValue } from '../../value/index.mjs';
|
||||
import { isMotionValue } from '../../value/utils/is-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 };
|
||||
52
node_modules/framer-motion/dist/es/animation/animate/subject.mjs
generated
vendored
Normal file
52
node_modules/framer-motion/dist/es/animation/animate/subject.mjs
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
import { invariant } from 'motion-utils';
|
||||
import { visualElementStore } from '../../render/store.mjs';
|
||||
import { isMotionValue } from '../../value/utils/is-motion-value.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.");
|
||||
for (let i = 0; i < numSubjects; i++) {
|
||||
const thisSubject = subjects[i];
|
||||
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 };
|
||||
318
node_modules/framer-motion/dist/es/animation/animators/AcceleratedAnimation.mjs
generated
vendored
Normal file
318
node_modules/framer-motion/dist/es/animation/animators/AcceleratedAnimation.mjs
generated
vendored
Normal file
@ -0,0 +1,318 @@
|
||||
import { anticipate } from '../../easing/anticipate.mjs';
|
||||
import { backInOut } from '../../easing/back.mjs';
|
||||
import { circInOut } from '../../easing/circ.mjs';
|
||||
import { DOMKeyframesResolver } from '../../render/dom/DOMKeyframesResolver.mjs';
|
||||
import { noop } from 'motion-utils';
|
||||
import { millisecondsToSeconds, secondsToMilliseconds } from '../../utils/time-conversion.mjs';
|
||||
import { isGenerator } from '../generators/utils/is-generator.mjs';
|
||||
import { BaseAnimation } from './BaseAnimation.mjs';
|
||||
import { MainThreadAnimation } from './MainThreadAnimation.mjs';
|
||||
import { acceleratedValues } from './utils/accelerated-values.mjs';
|
||||
import { startWaapiAnimation } from './waapi/index.mjs';
|
||||
import { isWaapiSupportedEasing } from './waapi/easing.mjs';
|
||||
import { attachTimeline } from './waapi/utils/attach-timeline.mjs';
|
||||
import { getFinalKeyframe } from './waapi/utils/get-final-keyframe.mjs';
|
||||
import { supportsLinearEasing } from './waapi/utils/supports-linear-easing.mjs';
|
||||
import { supportsWaapi } from './waapi/utils/supports-waapi.mjs';
|
||||
|
||||
/**
|
||||
* 10ms is chosen here as it strikes a balance between smooth
|
||||
* results (more than one keyframe per frame at 60fps) and
|
||||
* keyframe quantity.
|
||||
*/
|
||||
const sampleDelta = 10; //ms
|
||||
/**
|
||||
* Implement a practical max duration for keyframe generation
|
||||
* to prevent infinite loops
|
||||
*/
|
||||
const maxDuration = 20000;
|
||||
/**
|
||||
* Check if an animation can run natively via WAAPI or requires pregenerated keyframes.
|
||||
* WAAPI doesn't support spring or function easings so we run these as JS animation before
|
||||
* handing off.
|
||||
*/
|
||||
function requiresPregeneratedKeyframes(options) {
|
||||
return (isGenerator(options.type) ||
|
||||
options.type === "spring" ||
|
||||
!isWaapiSupportedEasing(options.ease));
|
||||
}
|
||||
function pregenerateKeyframes(keyframes, options) {
|
||||
/**
|
||||
* Create a main-thread animation to pregenerate keyframes.
|
||||
* We sample this at regular intervals to generate keyframes that we then
|
||||
* linearly interpolate between.
|
||||
*/
|
||||
const sampleAnimation = new MainThreadAnimation({
|
||||
...options,
|
||||
keyframes,
|
||||
repeat: 0,
|
||||
delay: 0,
|
||||
isGenerator: true,
|
||||
});
|
||||
let state = { done: false, value: keyframes[0] };
|
||||
const pregeneratedKeyframes = [];
|
||||
/**
|
||||
* Bail after 20 seconds of pre-generated keyframes as it's likely
|
||||
* we're heading for an infinite loop.
|
||||
*/
|
||||
let t = 0;
|
||||
while (!state.done && t < maxDuration) {
|
||||
state = sampleAnimation.sample(t);
|
||||
pregeneratedKeyframes.push(state.value);
|
||||
t += sampleDelta;
|
||||
}
|
||||
return {
|
||||
times: undefined,
|
||||
keyframes: pregeneratedKeyframes,
|
||||
duration: t - sampleDelta,
|
||||
ease: "linear",
|
||||
};
|
||||
}
|
||||
const unsupportedEasingFunctions = {
|
||||
anticipate,
|
||||
backInOut,
|
||||
circInOut,
|
||||
};
|
||||
function isUnsupportedEase(key) {
|
||||
return key in unsupportedEasingFunctions;
|
||||
}
|
||||
class AcceleratedAnimation extends BaseAnimation {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
const { name, motionValue, element, keyframes } = this.options;
|
||||
this.resolver = new DOMKeyframesResolver(keyframes, (resolvedKeyframes, finalKeyframe) => this.onKeyframesResolved(resolvedKeyframes, finalKeyframe), name, motionValue, element);
|
||||
this.resolver.scheduleResolve();
|
||||
}
|
||||
initPlayback(keyframes, finalKeyframe) {
|
||||
var _a;
|
||||
let { duration = 300, times, ease, type, motionValue, name, startTime, } = this.options;
|
||||
/**
|
||||
* If element has since been unmounted, return false to indicate
|
||||
* the animation failed to initialised.
|
||||
*/
|
||||
if (!((_a = motionValue.owner) === null || _a === void 0 ? void 0 : _a.current)) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* If the user has provided an easing function name that isn't supported
|
||||
* by WAAPI (like "anticipate"), we need to provide the corressponding
|
||||
* function. This will later get converted to a linear() easing function.
|
||||
*/
|
||||
if (typeof ease === "string" &&
|
||||
supportsLinearEasing() &&
|
||||
isUnsupportedEase(ease)) {
|
||||
ease = unsupportedEasingFunctions[ease];
|
||||
}
|
||||
/**
|
||||
* If this animation needs pre-generated keyframes then generate.
|
||||
*/
|
||||
if (requiresPregeneratedKeyframes(this.options)) {
|
||||
const { onComplete, onUpdate, motionValue, element, ...options } = this.options;
|
||||
const pregeneratedAnimation = pregenerateKeyframes(keyframes, options);
|
||||
keyframes = pregeneratedAnimation.keyframes;
|
||||
// If this is a very short animation, ensure we have
|
||||
// at least two keyframes to animate between as older browsers
|
||||
// can't animate between a single keyframe.
|
||||
if (keyframes.length === 1) {
|
||||
keyframes[1] = keyframes[0];
|
||||
}
|
||||
duration = pregeneratedAnimation.duration;
|
||||
times = pregeneratedAnimation.times;
|
||||
ease = pregeneratedAnimation.ease;
|
||||
type = "keyframes";
|
||||
}
|
||||
const animation = startWaapiAnimation(motionValue.owner.current, name, keyframes, { ...this.options, duration, times, ease });
|
||||
// Override the browser calculated startTime with one synchronised to other JS
|
||||
// and WAAPI animations starting this event loop.
|
||||
animation.startTime = startTime !== null && startTime !== void 0 ? startTime : this.calcStartTime();
|
||||
if (this.pendingTimeline) {
|
||||
attachTimeline(animation, this.pendingTimeline);
|
||||
this.pendingTimeline = undefined;
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* Prefer the `onfinish` prop as it's more widely supported than
|
||||
* the `finished` promise.
|
||||
*
|
||||
* Here, we synchronously set the provided MotionValue to the end
|
||||
* keyframe. If we didn't, when the WAAPI animation is finished it would
|
||||
* be removed from the element which would then revert to its old styles.
|
||||
*/
|
||||
animation.onfinish = () => {
|
||||
const { onComplete } = this.options;
|
||||
motionValue.set(getFinalKeyframe(keyframes, this.options, finalKeyframe));
|
||||
onComplete && onComplete();
|
||||
this.cancel();
|
||||
this.resolveFinishedPromise();
|
||||
};
|
||||
}
|
||||
return {
|
||||
animation,
|
||||
duration,
|
||||
times,
|
||||
type,
|
||||
ease,
|
||||
keyframes: keyframes,
|
||||
};
|
||||
}
|
||||
get duration() {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return 0;
|
||||
const { duration } = resolved;
|
||||
return millisecondsToSeconds(duration);
|
||||
}
|
||||
get time() {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return 0;
|
||||
const { animation } = resolved;
|
||||
return millisecondsToSeconds(animation.currentTime || 0);
|
||||
}
|
||||
set time(newTime) {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return;
|
||||
const { animation } = resolved;
|
||||
animation.currentTime = secondsToMilliseconds(newTime);
|
||||
}
|
||||
get speed() {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return 1;
|
||||
const { animation } = resolved;
|
||||
return animation.playbackRate;
|
||||
}
|
||||
set speed(newSpeed) {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return;
|
||||
const { animation } = resolved;
|
||||
animation.playbackRate = newSpeed;
|
||||
}
|
||||
get state() {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return "idle";
|
||||
const { animation } = resolved;
|
||||
return animation.playState;
|
||||
}
|
||||
get startTime() {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return null;
|
||||
const { animation } = resolved;
|
||||
// Coerce to number as TypeScript incorrectly types this
|
||||
// as CSSNumberish
|
||||
return animation.startTime;
|
||||
}
|
||||
/**
|
||||
* Replace the default DocumentTimeline with another AnimationTimeline.
|
||||
* Currently used for scroll animations.
|
||||
*/
|
||||
attachTimeline(timeline) {
|
||||
if (!this._resolved) {
|
||||
this.pendingTimeline = timeline;
|
||||
}
|
||||
else {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return noop;
|
||||
const { animation } = resolved;
|
||||
attachTimeline(animation, timeline);
|
||||
}
|
||||
return noop;
|
||||
}
|
||||
play() {
|
||||
if (this.isStopped)
|
||||
return;
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return;
|
||||
const { animation } = resolved;
|
||||
if (animation.playState === "finished") {
|
||||
this.updateFinishedPromise();
|
||||
}
|
||||
animation.play();
|
||||
}
|
||||
pause() {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return;
|
||||
const { animation } = resolved;
|
||||
animation.pause();
|
||||
}
|
||||
stop() {
|
||||
this.resolver.cancel();
|
||||
this.isStopped = true;
|
||||
if (this.state === "idle")
|
||||
return;
|
||||
this.resolveFinishedPromise();
|
||||
this.updateFinishedPromise();
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return;
|
||||
const { animation, keyframes, duration, type, ease, times } = resolved;
|
||||
if (animation.playState === "idle" ||
|
||||
animation.playState === "finished") {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* WAAPI doesn't natively have any interruption capabilities.
|
||||
*
|
||||
* Rather than read commited styles back out of the DOM, we can
|
||||
* create a renderless JS animation and sample it twice to calculate
|
||||
* its current value, "previous" value, and therefore allow
|
||||
* Motion to calculate velocity for any subsequent animation.
|
||||
*/
|
||||
if (this.time) {
|
||||
const { motionValue, onUpdate, onComplete, element, ...options } = this.options;
|
||||
const sampleAnimation = new MainThreadAnimation({
|
||||
...options,
|
||||
keyframes,
|
||||
duration,
|
||||
type,
|
||||
ease,
|
||||
times,
|
||||
isGenerator: true,
|
||||
});
|
||||
const sampleTime = secondsToMilliseconds(this.time);
|
||||
motionValue.setWithVelocity(sampleAnimation.sample(sampleTime - sampleDelta).value, sampleAnimation.sample(sampleTime).value, sampleDelta);
|
||||
}
|
||||
const { onStop } = this.options;
|
||||
onStop && onStop();
|
||||
this.cancel();
|
||||
}
|
||||
complete() {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return;
|
||||
resolved.animation.finish();
|
||||
}
|
||||
cancel() {
|
||||
const { resolved } = this;
|
||||
if (!resolved)
|
||||
return;
|
||||
resolved.animation.cancel();
|
||||
}
|
||||
static supports(options) {
|
||||
const { motionValue, name, repeatDelay, repeatType, damping, type } = options;
|
||||
return (supportsWaapi() &&
|
||||
name &&
|
||||
acceleratedValues.has(name) &&
|
||||
motionValue &&
|
||||
motionValue.owner &&
|
||||
motionValue.owner.current instanceof HTMLElement &&
|
||||
/**
|
||||
* If we're outputting values to onUpdate then we can't use WAAPI as there's
|
||||
* no way to read the value from WAAPI every frame.
|
||||
*/
|
||||
!motionValue.owner.getProps().onUpdate &&
|
||||
!repeatDelay &&
|
||||
repeatType !== "mirror" &&
|
||||
damping !== 0 &&
|
||||
type !== "inertia");
|
||||
}
|
||||
}
|
||||
|
||||
export { AcceleratedAnimation };
|
||||
117
node_modules/framer-motion/dist/es/animation/animators/BaseAnimation.mjs
generated
vendored
Normal file
117
node_modules/framer-motion/dist/es/animation/animators/BaseAnimation.mjs
generated
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
import { time } from '../../frameloop/sync-time.mjs';
|
||||
import { flushKeyframeResolvers } from '../../render/utils/KeyframesResolver.mjs';
|
||||
import { instantAnimationState } from '../../utils/use-instant-transition-state.mjs';
|
||||
import { canAnimate } from './utils/can-animate.mjs';
|
||||
import { getFinalKeyframe } from './waapi/utils/get-final-keyframe.mjs';
|
||||
|
||||
/**
|
||||
* Maximum time allowed between an animation being created and it being
|
||||
* resolved for us to use the latter as the start time.
|
||||
*
|
||||
* This is to ensure that while we prefer to "start" an animation as soon
|
||||
* as it's triggered, we also want to avoid a visual jump if there's a big delay
|
||||
* between these two moments.
|
||||
*/
|
||||
const MAX_RESOLVE_DELAY = 40;
|
||||
class BaseAnimation {
|
||||
constructor({ autoplay = true, delay = 0, type = "keyframes", repeat = 0, repeatDelay = 0, repeatType = "loop", ...options }) {
|
||||
// Track whether the animation has been stopped. Stopped animations won't restart.
|
||||
this.isStopped = false;
|
||||
this.hasAttemptedResolve = false;
|
||||
this.createdAt = time.now();
|
||||
this.options = {
|
||||
autoplay,
|
||||
delay,
|
||||
type,
|
||||
repeat,
|
||||
repeatDelay,
|
||||
repeatType,
|
||||
...options,
|
||||
};
|
||||
this.updateFinishedPromise();
|
||||
}
|
||||
/**
|
||||
* This method uses the createdAt and resolvedAt to calculate the
|
||||
* animation startTime. *Ideally*, we would use the createdAt time as t=0
|
||||
* as the following frame would then be the first frame of the animation in
|
||||
* progress, which would feel snappier.
|
||||
*
|
||||
* However, if there's a delay (main thread work) between the creation of
|
||||
* the animation and the first commited frame, we prefer to use resolvedAt
|
||||
* to avoid a sudden jump into the animation.
|
||||
*/
|
||||
calcStartTime() {
|
||||
if (!this.resolvedAt)
|
||||
return this.createdAt;
|
||||
return this.resolvedAt - this.createdAt > MAX_RESOLVE_DELAY
|
||||
? this.resolvedAt
|
||||
: this.createdAt;
|
||||
}
|
||||
/**
|
||||
* A getter for resolved data. If keyframes are not yet resolved, accessing
|
||||
* this.resolved will synchronously flush all pending keyframe resolvers.
|
||||
* This is a deoptimisation, but at its worst still batches read/writes.
|
||||
*/
|
||||
get resolved() {
|
||||
if (!this._resolved && !this.hasAttemptedResolve) {
|
||||
flushKeyframeResolvers();
|
||||
}
|
||||
return this._resolved;
|
||||
}
|
||||
/**
|
||||
* A method to be called when the keyframes resolver completes. This method
|
||||
* will check if its possible to run the animation and, if not, skip it.
|
||||
* Otherwise, it will call initPlayback on the implementing class.
|
||||
*/
|
||||
onKeyframesResolved(keyframes, finalKeyframe) {
|
||||
this.resolvedAt = time.now();
|
||||
this.hasAttemptedResolve = true;
|
||||
const { name, type, velocity, delay, onComplete, onUpdate, isGenerator, } = this.options;
|
||||
/**
|
||||
* If we can't animate this value with the resolved keyframes
|
||||
* then we should complete it immediately.
|
||||
*/
|
||||
if (!isGenerator && !canAnimate(keyframes, name, type, velocity)) {
|
||||
// Finish immediately
|
||||
if (instantAnimationState.current || !delay) {
|
||||
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(getFinalKeyframe(keyframes, this.options, finalKeyframe));
|
||||
onComplete === null || onComplete === void 0 ? void 0 : onComplete();
|
||||
this.resolveFinishedPromise();
|
||||
return;
|
||||
}
|
||||
// Finish after a delay
|
||||
else {
|
||||
this.options.duration = 0;
|
||||
}
|
||||
}
|
||||
const resolvedAnimation = this.initPlayback(keyframes, finalKeyframe);
|
||||
if (resolvedAnimation === false)
|
||||
return;
|
||||
this._resolved = {
|
||||
keyframes,
|
||||
finalKeyframe,
|
||||
...resolvedAnimation,
|
||||
};
|
||||
this.onPostResolved();
|
||||
}
|
||||
onPostResolved() { }
|
||||
/**
|
||||
* Allows the returned animation to be awaited or promise-chained. Currently
|
||||
* resolves when the animation finishes at all but in a future update could/should
|
||||
* reject if its cancels.
|
||||
*/
|
||||
then(resolve, reject) {
|
||||
return this.currentFinishedPromise.then(resolve, reject);
|
||||
}
|
||||
flatten() {
|
||||
this.options.type = "keyframes";
|
||||
this.options.ease = "linear";
|
||||
}
|
||||
updateFinishedPromise() {
|
||||
this.currentFinishedPromise = new Promise((resolve) => {
|
||||
this.resolveFinishedPromise = resolve;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export { BaseAnimation };
|
||||
391
node_modules/framer-motion/dist/es/animation/animators/MainThreadAnimation.mjs
generated
vendored
Normal file
391
node_modules/framer-motion/dist/es/animation/animators/MainThreadAnimation.mjs
generated
vendored
Normal file
@ -0,0 +1,391 @@
|
||||
import { KeyframeResolver } from '../../render/utils/KeyframesResolver.mjs';
|
||||
import { spring } from '../generators/spring/index.mjs';
|
||||
import { inertia } from '../generators/inertia.mjs';
|
||||
import { keyframes } from '../generators/keyframes.mjs';
|
||||
import { BaseAnimation } from './BaseAnimation.mjs';
|
||||
import { pipe } from '../../utils/pipe.mjs';
|
||||
import { mix } from '../../utils/mix/index.mjs';
|
||||
import { calcGeneratorDuration } from '../generators/utils/calc-duration.mjs';
|
||||
import { millisecondsToSeconds, secondsToMilliseconds } from '../../utils/time-conversion.mjs';
|
||||
import { clamp } from '../../utils/clamp.mjs';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { frameloopDriver } from './drivers/driver-frameloop.mjs';
|
||||
import { getFinalKeyframe } from './waapi/utils/get-final-keyframe.mjs';
|
||||
import { isGenerator } from '../generators/utils/is-generator.mjs';
|
||||
|
||||
const generators = {
|
||||
decay: inertia,
|
||||
inertia,
|
||||
tween: keyframes,
|
||||
keyframes: keyframes,
|
||||
spring,
|
||||
};
|
||||
const percentToProgress = (percent) => percent / 100;
|
||||
/**
|
||||
* Animation that runs on the main thread. Designed to be WAAPI-spec in the subset of
|
||||
* features we expose publically. Mostly the compatibility is to ensure visual identity
|
||||
* between both WAAPI and main thread animations.
|
||||
*/
|
||||
class MainThreadAnimation extends BaseAnimation {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
/**
|
||||
* The time at which the animation was paused.
|
||||
*/
|
||||
this.holdTime = null;
|
||||
/**
|
||||
* The time at which the animation was cancelled.
|
||||
*/
|
||||
this.cancelTime = null;
|
||||
/**
|
||||
* The current time of the animation.
|
||||
*/
|
||||
this.currentTime = 0;
|
||||
/**
|
||||
* Playback speed as a factor. 0 would be stopped, -1 reverse and 2 double speed.
|
||||
*/
|
||||
this.playbackSpeed = 1;
|
||||
/**
|
||||
* The state of the animation to apply when the animation is resolved. This
|
||||
* allows calls to the public API to control the animation before it is resolved,
|
||||
* without us having to resolve it first.
|
||||
*/
|
||||
this.pendingPlayState = "running";
|
||||
/**
|
||||
* The time at which the animation was started.
|
||||
*/
|
||||
this.startTime = null;
|
||||
this.state = "idle";
|
||||
/**
|
||||
* This method is bound to the instance to fix a pattern where
|
||||
* animation.stop is returned as a reference from a useEffect.
|
||||
*/
|
||||
this.stop = () => {
|
||||
this.resolver.cancel();
|
||||
this.isStopped = true;
|
||||
if (this.state === "idle")
|
||||
return;
|
||||
this.teardown();
|
||||
const { onStop } = this.options;
|
||||
onStop && onStop();
|
||||
};
|
||||
const { name, motionValue, element, keyframes } = this.options;
|
||||
const KeyframeResolver$1 = (element === null || element === void 0 ? void 0 : element.KeyframeResolver) || KeyframeResolver;
|
||||
const onResolved = (resolvedKeyframes, finalKeyframe) => this.onKeyframesResolved(resolvedKeyframes, finalKeyframe);
|
||||
this.resolver = new KeyframeResolver$1(keyframes, onResolved, name, motionValue, element);
|
||||
this.resolver.scheduleResolve();
|
||||
}
|
||||
flatten() {
|
||||
super.flatten();
|
||||
// If we've already resolved the animation, re-initialise it
|
||||
if (this._resolved) {
|
||||
Object.assign(this._resolved, this.initPlayback(this._resolved.keyframes));
|
||||
}
|
||||
}
|
||||
initPlayback(keyframes$1) {
|
||||
const { type = "keyframes", repeat = 0, repeatDelay = 0, repeatType, velocity = 0, } = this.options;
|
||||
const generatorFactory = isGenerator(type)
|
||||
? type
|
||||
: generators[type] || keyframes;
|
||||
/**
|
||||
* If our generator doesn't support mixing numbers, we need to replace keyframes with
|
||||
* [0, 100] and then make a function that maps that to the actual keyframes.
|
||||
*
|
||||
* 100 is chosen instead of 1 as it works nicer with spring animations.
|
||||
*/
|
||||
let mapPercentToKeyframes;
|
||||
let mirroredGenerator;
|
||||
if (generatorFactory !== keyframes &&
|
||||
typeof keyframes$1[0] !== "number") {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
invariant(keyframes$1.length === 2, `Only two keyframes currently supported with spring and inertia animations. Trying to animate ${keyframes$1}`);
|
||||
}
|
||||
mapPercentToKeyframes = pipe(percentToProgress, mix(keyframes$1[0], keyframes$1[1]));
|
||||
keyframes$1 = [0, 100];
|
||||
}
|
||||
const generator = generatorFactory({ ...this.options, keyframes: keyframes$1 });
|
||||
/**
|
||||
* If we have a mirror repeat type we need to create a second generator that outputs the
|
||||
* mirrored (not reversed) animation and later ping pong between the two generators.
|
||||
*/
|
||||
if (repeatType === "mirror") {
|
||||
mirroredGenerator = generatorFactory({
|
||||
...this.options,
|
||||
keyframes: [...keyframes$1].reverse(),
|
||||
velocity: -velocity,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* If duration is undefined and we have repeat options,
|
||||
* we need to calculate a duration from the generator.
|
||||
*
|
||||
* We set it to the generator itself to cache the duration.
|
||||
* Any timeline resolver will need to have already precalculated
|
||||
* the duration by this step.
|
||||
*/
|
||||
if (generator.calculatedDuration === null) {
|
||||
generator.calculatedDuration = calcGeneratorDuration(generator);
|
||||
}
|
||||
const { calculatedDuration } = generator;
|
||||
const resolvedDuration = calculatedDuration + repeatDelay;
|
||||
const totalDuration = resolvedDuration * (repeat + 1) - repeatDelay;
|
||||
return {
|
||||
generator,
|
||||
mirroredGenerator,
|
||||
mapPercentToKeyframes,
|
||||
calculatedDuration,
|
||||
resolvedDuration,
|
||||
totalDuration,
|
||||
};
|
||||
}
|
||||
onPostResolved() {
|
||||
const { autoplay = true } = this.options;
|
||||
this.play();
|
||||
if (this.pendingPlayState === "paused" || !autoplay) {
|
||||
this.pause();
|
||||
}
|
||||
else {
|
||||
this.state = this.pendingPlayState;
|
||||
}
|
||||
}
|
||||
tick(timestamp, sample = false) {
|
||||
const { resolved } = this;
|
||||
// If the animations has failed to resolve, return the final keyframe.
|
||||
if (!resolved) {
|
||||
const { keyframes } = this.options;
|
||||
return { done: true, value: keyframes[keyframes.length - 1] };
|
||||
}
|
||||
const { finalKeyframe, generator, mirroredGenerator, mapPercentToKeyframes, keyframes, calculatedDuration, totalDuration, resolvedDuration, } = resolved;
|
||||
if (this.startTime === null)
|
||||
return generator.next(0);
|
||||
const { delay, repeat, repeatType, repeatDelay, onUpdate } = this.options;
|
||||
/**
|
||||
* requestAnimationFrame timestamps can come through as lower than
|
||||
* the startTime as set by performance.now(). Here we prevent this,
|
||||
* though in the future it could be possible to make setting startTime
|
||||
* a pending operation that gets resolved here.
|
||||
*/
|
||||
if (this.speed > 0) {
|
||||
this.startTime = Math.min(this.startTime, timestamp);
|
||||
}
|
||||
else if (this.speed < 0) {
|
||||
this.startTime = Math.min(timestamp - totalDuration / this.speed, this.startTime);
|
||||
}
|
||||
// Update currentTime
|
||||
if (sample) {
|
||||
this.currentTime = timestamp;
|
||||
}
|
||||
else if (this.holdTime !== null) {
|
||||
this.currentTime = this.holdTime;
|
||||
}
|
||||
else {
|
||||
// Rounding the time because floating point arithmetic is not always accurate, e.g. 3000.367 - 1000.367 =
|
||||
// 2000.0000000000002. This is a problem when we are comparing the currentTime with the duration, for
|
||||
// example.
|
||||
this.currentTime =
|
||||
Math.round(timestamp - this.startTime) * this.speed;
|
||||
}
|
||||
// Rebase on delay
|
||||
const timeWithoutDelay = this.currentTime - delay * (this.speed >= 0 ? 1 : -1);
|
||||
const isInDelayPhase = this.speed >= 0
|
||||
? timeWithoutDelay < 0
|
||||
: timeWithoutDelay > totalDuration;
|
||||
this.currentTime = Math.max(timeWithoutDelay, 0);
|
||||
// If this animation has finished, set the current time to the total duration.
|
||||
if (this.state === "finished" && this.holdTime === null) {
|
||||
this.currentTime = totalDuration;
|
||||
}
|
||||
let elapsed = this.currentTime;
|
||||
let frameGenerator = generator;
|
||||
if (repeat) {
|
||||
/**
|
||||
* Get the current progress (0-1) of the animation. If t is >
|
||||
* than duration we'll get values like 2.5 (midway through the
|
||||
* third iteration)
|
||||
*/
|
||||
const progress = Math.min(this.currentTime, totalDuration) / resolvedDuration;
|
||||
/**
|
||||
* Get the current iteration (0 indexed). For instance the floor of
|
||||
* 2.5 is 2.
|
||||
*/
|
||||
let currentIteration = Math.floor(progress);
|
||||
/**
|
||||
* Get the current progress of the iteration by taking the remainder
|
||||
* so 2.5 is 0.5 through iteration 2
|
||||
*/
|
||||
let iterationProgress = progress % 1.0;
|
||||
/**
|
||||
* If iteration progress is 1 we count that as the end
|
||||
* of the previous iteration.
|
||||
*/
|
||||
if (!iterationProgress && progress >= 1) {
|
||||
iterationProgress = 1;
|
||||
}
|
||||
iterationProgress === 1 && currentIteration--;
|
||||
currentIteration = Math.min(currentIteration, repeat + 1);
|
||||
/**
|
||||
* Reverse progress if we're not running in "normal" direction
|
||||
*/
|
||||
const isOddIteration = Boolean(currentIteration % 2);
|
||||
if (isOddIteration) {
|
||||
if (repeatType === "reverse") {
|
||||
iterationProgress = 1 - iterationProgress;
|
||||
if (repeatDelay) {
|
||||
iterationProgress -= repeatDelay / resolvedDuration;
|
||||
}
|
||||
}
|
||||
else if (repeatType === "mirror") {
|
||||
frameGenerator = mirroredGenerator;
|
||||
}
|
||||
}
|
||||
elapsed = clamp(0, 1, iterationProgress) * resolvedDuration;
|
||||
}
|
||||
/**
|
||||
* If we're in negative time, set state as the initial keyframe.
|
||||
* This prevents delay: x, duration: 0 animations from finishing
|
||||
* instantly.
|
||||
*/
|
||||
const state = isInDelayPhase
|
||||
? { done: false, value: keyframes[0] }
|
||||
: frameGenerator.next(elapsed);
|
||||
if (mapPercentToKeyframes) {
|
||||
state.value = mapPercentToKeyframes(state.value);
|
||||
}
|
||||
let { done } = state;
|
||||
if (!isInDelayPhase && calculatedDuration !== null) {
|
||||
done =
|
||||
this.speed >= 0
|
||||
? this.currentTime >= totalDuration
|
||||
: this.currentTime <= 0;
|
||||
}
|
||||
const isAnimationFinished = this.holdTime === null &&
|
||||
(this.state === "finished" || (this.state === "running" && done));
|
||||
if (isAnimationFinished && finalKeyframe !== undefined) {
|
||||
state.value = getFinalKeyframe(keyframes, this.options, finalKeyframe);
|
||||
}
|
||||
if (onUpdate) {
|
||||
onUpdate(state.value);
|
||||
}
|
||||
if (isAnimationFinished) {
|
||||
this.finish();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
get duration() {
|
||||
const { resolved } = this;
|
||||
return resolved ? millisecondsToSeconds(resolved.calculatedDuration) : 0;
|
||||
}
|
||||
get time() {
|
||||
return millisecondsToSeconds(this.currentTime);
|
||||
}
|
||||
set time(newTime) {
|
||||
newTime = secondsToMilliseconds(newTime);
|
||||
this.currentTime = newTime;
|
||||
if (this.holdTime !== null || this.speed === 0) {
|
||||
this.holdTime = newTime;
|
||||
}
|
||||
else if (this.driver) {
|
||||
this.startTime = this.driver.now() - newTime / this.speed;
|
||||
}
|
||||
}
|
||||
get speed() {
|
||||
return this.playbackSpeed;
|
||||
}
|
||||
set speed(newSpeed) {
|
||||
const hasChanged = this.playbackSpeed !== newSpeed;
|
||||
this.playbackSpeed = newSpeed;
|
||||
if (hasChanged) {
|
||||
this.time = millisecondsToSeconds(this.currentTime);
|
||||
}
|
||||
}
|
||||
play() {
|
||||
if (!this.resolver.isScheduled) {
|
||||
this.resolver.resume();
|
||||
}
|
||||
if (!this._resolved) {
|
||||
this.pendingPlayState = "running";
|
||||
return;
|
||||
}
|
||||
if (this.isStopped)
|
||||
return;
|
||||
const { driver = frameloopDriver, onPlay, startTime } = this.options;
|
||||
if (!this.driver) {
|
||||
this.driver = driver((timestamp) => this.tick(timestamp));
|
||||
}
|
||||
onPlay && onPlay();
|
||||
const now = this.driver.now();
|
||||
if (this.holdTime !== null) {
|
||||
this.startTime = now - this.holdTime;
|
||||
}
|
||||
else if (!this.startTime) {
|
||||
this.startTime = startTime !== null && startTime !== void 0 ? startTime : this.calcStartTime();
|
||||
}
|
||||
else if (this.state === "finished") {
|
||||
this.startTime = now;
|
||||
}
|
||||
if (this.state === "finished") {
|
||||
this.updateFinishedPromise();
|
||||
}
|
||||
this.cancelTime = this.startTime;
|
||||
this.holdTime = null;
|
||||
/**
|
||||
* Set playState to running only after we've used it in
|
||||
* the previous logic.
|
||||
*/
|
||||
this.state = "running";
|
||||
this.driver.start();
|
||||
}
|
||||
pause() {
|
||||
var _a;
|
||||
if (!this._resolved) {
|
||||
this.pendingPlayState = "paused";
|
||||
return;
|
||||
}
|
||||
this.state = "paused";
|
||||
this.holdTime = (_a = this.currentTime) !== null && _a !== void 0 ? _a : 0;
|
||||
}
|
||||
complete() {
|
||||
if (this.state !== "running") {
|
||||
this.play();
|
||||
}
|
||||
this.pendingPlayState = this.state = "finished";
|
||||
this.holdTime = null;
|
||||
}
|
||||
finish() {
|
||||
this.teardown();
|
||||
this.state = "finished";
|
||||
const { onComplete } = this.options;
|
||||
onComplete && onComplete();
|
||||
}
|
||||
cancel() {
|
||||
if (this.cancelTime !== null) {
|
||||
this.tick(this.cancelTime);
|
||||
}
|
||||
this.teardown();
|
||||
this.updateFinishedPromise();
|
||||
}
|
||||
teardown() {
|
||||
this.state = "idle";
|
||||
this.stopDriver();
|
||||
this.resolveFinishedPromise();
|
||||
this.updateFinishedPromise();
|
||||
this.startTime = this.cancelTime = null;
|
||||
this.resolver.cancel();
|
||||
}
|
||||
stopDriver() {
|
||||
if (!this.driver)
|
||||
return;
|
||||
this.driver.stop();
|
||||
this.driver = undefined;
|
||||
}
|
||||
sample(time) {
|
||||
this.startTime = 0;
|
||||
return this.tick(time, true);
|
||||
}
|
||||
}
|
||||
// Legacy interface
|
||||
function animateValue(options) {
|
||||
return new MainThreadAnimation(options);
|
||||
}
|
||||
|
||||
export { MainThreadAnimation, animateValue };
|
||||
17
node_modules/framer-motion/dist/es/animation/animators/drivers/driver-frameloop.mjs
generated
vendored
Normal file
17
node_modules/framer-motion/dist/es/animation/animators/drivers/driver-frameloop.mjs
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
import { time } from '../../../frameloop/sync-time.mjs';
|
||||
import { frame, cancelFrame, frameData } from '../../../frameloop/frame.mjs';
|
||||
|
||||
const frameloopDriver = (update) => {
|
||||
const passTimestamp = ({ timestamp }) => update(timestamp);
|
||||
return {
|
||||
start: () => frame.update(passTimestamp, true),
|
||||
stop: () => cancelFrame(passTimestamp),
|
||||
/**
|
||||
* If we're processing this frame we can use the
|
||||
* framelocked timestamp to keep things in sync.
|
||||
*/
|
||||
now: () => (frameData.isProcessing ? frameData.timestamp : time.now()),
|
||||
};
|
||||
};
|
||||
|
||||
export { frameloopDriver };
|
||||
14
node_modules/framer-motion/dist/es/animation/animators/utils/accelerated-values.mjs
generated
vendored
Normal file
14
node_modules/framer-motion/dist/es/animation/animators/utils/accelerated-values.mjs
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* A list of values that can be hardware-accelerated.
|
||||
*/
|
||||
const acceleratedValues = new Set([
|
||||
"opacity",
|
||||
"clipPath",
|
||||
"filter",
|
||||
"transform",
|
||||
// TODO: Can be accelerated but currently disabled until https://issues.chromium.org/issues/41491098 is resolved
|
||||
// or until we implement support for linear() easing.
|
||||
// "background-color"
|
||||
]);
|
||||
|
||||
export { acceleratedValues };
|
||||
42
node_modules/framer-motion/dist/es/animation/animators/utils/can-animate.mjs
generated
vendored
Normal file
42
node_modules/framer-motion/dist/es/animation/animators/utils/can-animate.mjs
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
import { warning } from 'motion-utils';
|
||||
import { isGenerator } from '../../generators/utils/is-generator.mjs';
|
||||
import { isAnimatable } from '../../utils/is-animatable.mjs';
|
||||
|
||||
function hasKeyframesChanged(keyframes) {
|
||||
const current = keyframes[0];
|
||||
if (keyframes.length === 1)
|
||||
return true;
|
||||
for (let i = 0; i < keyframes.length; i++) {
|
||||
if (keyframes[i] !== current)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function canAnimate(keyframes, name, type, velocity) {
|
||||
/**
|
||||
* Check if we're able to animate between the start and end keyframes,
|
||||
* and throw a warning if we're attempting to animate between one that's
|
||||
* animatable and another that isn't.
|
||||
*/
|
||||
const originKeyframe = keyframes[0];
|
||||
if (originKeyframe === null)
|
||||
return false;
|
||||
/**
|
||||
* These aren't traditionally animatable but we do support them.
|
||||
* In future we could look into making this more generic or replacing
|
||||
* this function with mix() === mixImmediate
|
||||
*/
|
||||
if (name === "display" || name === "visibility")
|
||||
return true;
|
||||
const targetKeyframe = keyframes[keyframes.length - 1];
|
||||
const isOriginAnimatable = isAnimatable(originKeyframe, name);
|
||||
const isTargetAnimatable = isAnimatable(targetKeyframe, name);
|
||||
warning(isOriginAnimatable === isTargetAnimatable, `You are trying to animate ${name} from "${originKeyframe}" to "${targetKeyframe}". ${originKeyframe} is not an animatable value - to enable this animation set ${originKeyframe} to a value animatable to ${targetKeyframe} via the \`style\` property.`);
|
||||
// Always skip if any of these are true
|
||||
if (!isOriginAnimatable || !isTargetAnimatable) {
|
||||
return false;
|
||||
}
|
||||
return (hasKeyframesChanged(keyframes) ||
|
||||
((type === "spring" || isGenerator(type)) && velocity));
|
||||
}
|
||||
|
||||
export { canAnimate };
|
||||
175
node_modules/framer-motion/dist/es/animation/animators/waapi/NativeAnimation.mjs
generated
vendored
Normal file
175
node_modules/framer-motion/dist/es/animation/animators/waapi/NativeAnimation.mjs
generated
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
import { startWaapiAnimation } from './index.mjs';
|
||||
import { createGeneratorEasing } from '../../../easing/utils/create-generator-easing.mjs';
|
||||
import { browserNumberValueTypes } from '../../../render/dom/value-types/number-browser.mjs';
|
||||
import { invariant, noop } from 'motion-utils';
|
||||
import { secondsToMilliseconds, millisecondsToSeconds } from '../../../utils/time-conversion.mjs';
|
||||
import { isGenerator } from '../../generators/utils/is-generator.mjs';
|
||||
import { attachTimeline } from './utils/attach-timeline.mjs';
|
||||
import { getFinalKeyframe } from './utils/get-final-keyframe.mjs';
|
||||
import { setCSSVar, setStyle } from './utils/style.mjs';
|
||||
import { supportsLinearEasing } from './utils/supports-linear-easing.mjs';
|
||||
import { supportsPartialKeyframes } from './utils/supports-partial-keyframes.mjs';
|
||||
import { supportsWaapi } from './utils/supports-waapi.mjs';
|
||||
|
||||
const state = new WeakMap();
|
||||
function hydrateKeyframes(valueName, keyframes, read) {
|
||||
for (let i = 0; i < keyframes.length; i++) {
|
||||
if (keyframes[i] === null) {
|
||||
keyframes[i] = i === 0 ? read() : keyframes[i - 1];
|
||||
}
|
||||
if (typeof keyframes[i] === "number" &&
|
||||
browserNumberValueTypes[valueName]) {
|
||||
keyframes[i] = browserNumberValueTypes[valueName].transform(keyframes[i]);
|
||||
}
|
||||
}
|
||||
if (!supportsPartialKeyframes() && keyframes.length < 2) {
|
||||
keyframes.unshift(read());
|
||||
}
|
||||
}
|
||||
const defaultEasing = "easeOut";
|
||||
function getElementAnimationState(element) {
|
||||
const animationState = state.get(element) || new Map();
|
||||
state.set(element, animationState);
|
||||
return state.get(element);
|
||||
}
|
||||
class NativeAnimation {
|
||||
constructor(element, valueName, valueKeyframes, options) {
|
||||
const isCSSVar = valueName.startsWith("--");
|
||||
this.setValue = isCSSVar ? setCSSVar : setStyle;
|
||||
this.options = options;
|
||||
this.updateFinishedPromise();
|
||||
invariant(typeof options.type !== "string", `animateMini doesn't support "type" as a string. Did you mean to import { spring } from "framer-motion"?`);
|
||||
const existingAnimation = getElementAnimationState(element).get(valueName);
|
||||
existingAnimation && existingAnimation.stop();
|
||||
const readInitialKeyframe = () => {
|
||||
return valueName.startsWith("--")
|
||||
? element.style.getPropertyValue(valueName)
|
||||
: window.getComputedStyle(element)[valueName];
|
||||
};
|
||||
if (!Array.isArray(valueKeyframes)) {
|
||||
valueKeyframes = [valueKeyframes];
|
||||
}
|
||||
hydrateKeyframes(valueName, valueKeyframes, readInitialKeyframe);
|
||||
// TODO: Replace this with toString()?
|
||||
if (isGenerator(options.type)) {
|
||||
const generatorOptions = createGeneratorEasing(options, 100, options.type);
|
||||
options.ease = supportsLinearEasing()
|
||||
? generatorOptions.ease
|
||||
: defaultEasing;
|
||||
options.duration = secondsToMilliseconds(generatorOptions.duration);
|
||||
options.type = "keyframes";
|
||||
}
|
||||
else {
|
||||
options.ease = options.ease || defaultEasing;
|
||||
}
|
||||
this.removeAnimation = () => { var _a; return (_a = state.get(element)) === null || _a === void 0 ? void 0 : _a.delete(valueName); };
|
||||
const onFinish = () => {
|
||||
this.setValue(element, valueName, getFinalKeyframe(valueKeyframes, this.options));
|
||||
this.cancel();
|
||||
this.resolveFinishedPromise();
|
||||
};
|
||||
if (!supportsWaapi()) {
|
||||
onFinish();
|
||||
}
|
||||
else {
|
||||
this.animation = startWaapiAnimation(element, valueName, valueKeyframes, options);
|
||||
if (options.autoplay === false) {
|
||||
this.animation.pause();
|
||||
}
|
||||
this.animation.onfinish = onFinish;
|
||||
if (this.pendingTimeline) {
|
||||
attachTimeline(this.animation, this.pendingTimeline);
|
||||
}
|
||||
getElementAnimationState(element).set(valueName, this);
|
||||
}
|
||||
}
|
||||
get duration() {
|
||||
return millisecondsToSeconds(this.options.duration || 300);
|
||||
}
|
||||
get time() {
|
||||
var _a;
|
||||
if (this.animation) {
|
||||
return millisecondsToSeconds(((_a = this.animation) === null || _a === void 0 ? void 0 : _a.currentTime) || 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
set time(newTime) {
|
||||
if (this.animation) {
|
||||
this.animation.currentTime = secondsToMilliseconds(newTime);
|
||||
}
|
||||
}
|
||||
get speed() {
|
||||
return this.animation ? this.animation.playbackRate : 1;
|
||||
}
|
||||
set speed(newSpeed) {
|
||||
if (this.animation) {
|
||||
this.animation.playbackRate = newSpeed;
|
||||
}
|
||||
}
|
||||
get state() {
|
||||
return this.animation ? this.animation.playState : "finished";
|
||||
}
|
||||
get startTime() {
|
||||
return this.animation ? this.animation.startTime : null;
|
||||
}
|
||||
flatten() {
|
||||
var _a;
|
||||
if (!this.animation)
|
||||
return;
|
||||
(_a = this.animation.effect) === null || _a === void 0 ? void 0 : _a.updateTiming({ easing: "linear" });
|
||||
}
|
||||
play() {
|
||||
if (this.state === "finished") {
|
||||
this.updateFinishedPromise();
|
||||
}
|
||||
this.animation && this.animation.play();
|
||||
}
|
||||
pause() {
|
||||
this.animation && this.animation.pause();
|
||||
}
|
||||
stop() {
|
||||
if (!this.animation ||
|
||||
this.state === "idle" ||
|
||||
this.state === "finished") {
|
||||
return;
|
||||
}
|
||||
if (this.animation.commitStyles) {
|
||||
this.animation.commitStyles();
|
||||
}
|
||||
this.cancel();
|
||||
}
|
||||
complete() {
|
||||
this.animation && this.animation.finish();
|
||||
}
|
||||
cancel() {
|
||||
this.removeAnimation();
|
||||
try {
|
||||
this.animation && this.animation.cancel();
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
/**
|
||||
* Allows the returned animation to be awaited or promise-chained. Currently
|
||||
* resolves when the animation finishes at all but in a future update could/should
|
||||
* reject if its cancels.
|
||||
*/
|
||||
then(resolve, reject) {
|
||||
return this.currentFinishedPromise.then(resolve, reject);
|
||||
}
|
||||
updateFinishedPromise() {
|
||||
this.currentFinishedPromise = new Promise((resolve) => {
|
||||
this.resolveFinishedPromise = resolve;
|
||||
});
|
||||
}
|
||||
attachTimeline(timeline) {
|
||||
if (!this.animation) {
|
||||
this.pendingTimeline = timeline;
|
||||
}
|
||||
else {
|
||||
attachTimeline(this.animation, timeline);
|
||||
}
|
||||
return noop;
|
||||
}
|
||||
}
|
||||
|
||||
export { NativeAnimation };
|
||||
36
node_modules/framer-motion/dist/es/animation/animators/waapi/animate-elements.mjs
generated
vendored
Normal file
36
node_modules/framer-motion/dist/es/animation/animators/waapi/animate-elements.mjs
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
import { resolveElements } from 'motion-dom';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { secondsToMilliseconds } from '../../../utils/time-conversion.mjs';
|
||||
import { getValueTransition } from '../../utils/get-value-transition.mjs';
|
||||
import { NativeAnimation } from './NativeAnimation.mjs';
|
||||
|
||||
function animateElements(elementOrSelector, keyframes, options, scope) {
|
||||
const elements = resolveElements(elementOrSelector, scope);
|
||||
const numElements = elements.length;
|
||||
invariant(Boolean(numElements), "No valid element provided.");
|
||||
const animations = [];
|
||||
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) {
|
||||
const valueKeyframes = keyframes[valueName];
|
||||
const valueOptions = {
|
||||
...getValueTransition(elementTransition, valueName),
|
||||
};
|
||||
valueOptions.duration = valueOptions.duration
|
||||
? secondsToMilliseconds(valueOptions.duration)
|
||||
: valueOptions.duration;
|
||||
valueOptions.delay = secondsToMilliseconds(valueOptions.delay || 0);
|
||||
animations.push(new NativeAnimation(element, valueName, valueKeyframes, valueOptions));
|
||||
}
|
||||
}
|
||||
return animations;
|
||||
}
|
||||
|
||||
export { animateElements };
|
||||
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 { GroupPlaybackControls } from '../../GroupPlaybackControls.mjs';
|
||||
import { animateElements } from './animate-elements.mjs';
|
||||
|
||||
const createScopedWaapiAnimate = (scope) => {
|
||||
function scopedAnimate(elementOrSelector, keyframes, options) {
|
||||
return new GroupPlaybackControls(animateElements(elementOrSelector, keyframes, options, scope));
|
||||
}
|
||||
return scopedAnimate;
|
||||
};
|
||||
const animateMini = /*@__PURE__*/ createScopedWaapiAnimate();
|
||||
|
||||
export { animateMini, createScopedWaapiAnimate };
|
||||
44
node_modules/framer-motion/dist/es/animation/animators/waapi/easing.mjs
generated
vendored
Normal file
44
node_modules/framer-motion/dist/es/animation/animators/waapi/easing.mjs
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
import { isBezierDefinition } from '../../../easing/utils/is-bezier-definition.mjs';
|
||||
import { generateLinearEasing } from './utils/linear.mjs';
|
||||
import { supportsLinearEasing } from './utils/supports-linear-easing.mjs';
|
||||
|
||||
function isWaapiSupportedEasing(easing) {
|
||||
return Boolean((typeof easing === "function" && supportsLinearEasing()) ||
|
||||
!easing ||
|
||||
(typeof easing === "string" &&
|
||||
(easing in supportedWaapiEasing || supportsLinearEasing())) ||
|
||||
isBezierDefinition(easing) ||
|
||||
(Array.isArray(easing) && easing.every(isWaapiSupportedEasing)));
|
||||
}
|
||||
const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
|
||||
const supportedWaapiEasing = {
|
||||
linear: "linear",
|
||||
ease: "ease",
|
||||
easeIn: "ease-in",
|
||||
easeOut: "ease-out",
|
||||
easeInOut: "ease-in-out",
|
||||
circIn: /*@__PURE__*/ cubicBezierAsString([0, 0.65, 0.55, 1]),
|
||||
circOut: /*@__PURE__*/ cubicBezierAsString([0.55, 0, 1, 0.45]),
|
||||
backIn: /*@__PURE__*/ cubicBezierAsString([0.31, 0.01, 0.66, -0.59]),
|
||||
backOut: /*@__PURE__*/ cubicBezierAsString([0.33, 1.53, 0.69, 0.99]),
|
||||
};
|
||||
function mapEasingToNativeEasing(easing, duration) {
|
||||
if (!easing) {
|
||||
return undefined;
|
||||
}
|
||||
else if (typeof easing === "function" && supportsLinearEasing()) {
|
||||
return generateLinearEasing(easing, duration);
|
||||
}
|
||||
else if (isBezierDefinition(easing)) {
|
||||
return cubicBezierAsString(easing);
|
||||
}
|
||||
else if (Array.isArray(easing)) {
|
||||
return easing.map((segmentEasing) => mapEasingToNativeEasing(segmentEasing, duration) ||
|
||||
supportedWaapiEasing.easeOut);
|
||||
}
|
||||
else {
|
||||
return supportedWaapiEasing[easing];
|
||||
}
|
||||
}
|
||||
|
||||
export { cubicBezierAsString, isWaapiSupportedEasing, mapEasingToNativeEasing, supportedWaapiEasing };
|
||||
23
node_modules/framer-motion/dist/es/animation/animators/waapi/index.mjs
generated
vendored
Normal file
23
node_modules/framer-motion/dist/es/animation/animators/waapi/index.mjs
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import { mapEasingToNativeEasing } from './easing.mjs';
|
||||
|
||||
function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duration = 300, repeat = 0, repeatType = "loop", ease = "easeInOut", times, } = {}) {
|
||||
const keyframeOptions = { [valueName]: keyframes };
|
||||
if (times)
|
||||
keyframeOptions.offset = times;
|
||||
const easing = mapEasingToNativeEasing(ease, duration);
|
||||
/**
|
||||
* If this is an easing array, apply to keyframes, not animation as a whole
|
||||
*/
|
||||
if (Array.isArray(easing))
|
||||
keyframeOptions.easing = easing;
|
||||
return element.animate(keyframeOptions, {
|
||||
delay,
|
||||
duration,
|
||||
easing: !Array.isArray(easing) ? easing : "linear",
|
||||
fill: "both",
|
||||
iterations: repeat + 1,
|
||||
direction: repeatType === "reverse" ? "alternate" : "normal",
|
||||
});
|
||||
}
|
||||
|
||||
export { startWaapiAnimation };
|
||||
6
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/attach-timeline.mjs
generated
vendored
Normal file
6
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/attach-timeline.mjs
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
function attachTimeline(animation, timeline) {
|
||||
animation.timeline = timeline;
|
||||
animation.onfinish = null;
|
||||
}
|
||||
|
||||
export { attachTimeline };
|
||||
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 };
|
||||
14
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/linear.mjs
generated
vendored
Normal file
14
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/linear.mjs
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import { progress } from '../../../../utils/progress.mjs';
|
||||
|
||||
const generateLinearEasing = (easing, duration, // as milliseconds
|
||||
resolution = 10 // as milliseconds
|
||||
) => {
|
||||
let points = "";
|
||||
const numPoints = Math.max(Math.round(duration / resolution), 2);
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
points += easing(progress(0, numPoints - 1, i)) + ", ";
|
||||
}
|
||||
return `linear(${points.substring(0, points.length - 2)})`;
|
||||
};
|
||||
|
||||
export { generateLinearEasing };
|
||||
9
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/memo-supports.mjs
generated
vendored
Normal file
9
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/memo-supports.mjs
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import { memo } from '../../../../utils/memo.mjs';
|
||||
import { supportsFlags } from './supports-flags.mjs';
|
||||
|
||||
function memoSupports(callback, supportsFlag) {
|
||||
const memoized = memo(callback);
|
||||
return () => { var _a; return (_a = supportsFlags[supportsFlag]) !== null && _a !== void 0 ? _a : memoized(); };
|
||||
}
|
||||
|
||||
export { memoSupports };
|
||||
8
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/style.mjs
generated
vendored
Normal file
8
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/style.mjs
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
function setCSSVar(element, name, value) {
|
||||
element.style.setProperty(`--${name}`, value);
|
||||
}
|
||||
function setStyle(element, name, value) {
|
||||
element.style[name] = value;
|
||||
}
|
||||
|
||||
export { setCSSVar, setStyle };
|
||||
9
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/supports-flags.mjs
generated
vendored
Normal file
9
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/supports-flags.mjs
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Add the ability for test suites to manually set support flags
|
||||
* to better test more environments.
|
||||
*/
|
||||
const supportsFlags = {
|
||||
linearEasing: undefined,
|
||||
};
|
||||
|
||||
export { supportsFlags };
|
||||
15
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/supports-linear-easing.mjs
generated
vendored
Normal file
15
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/supports-linear-easing.mjs
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { memoSupports } from './memo-supports.mjs';
|
||||
|
||||
const supportsLinearEasing = /*@__PURE__*/ memoSupports(() => {
|
||||
try {
|
||||
document
|
||||
.createElement("div")
|
||||
.animate({ opacity: 0 }, { easing: "linear(0, 1)" });
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, "linearEasing");
|
||||
|
||||
export { supportsLinearEasing };
|
||||
13
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/supports-partial-keyframes.mjs
generated
vendored
Normal file
13
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/supports-partial-keyframes.mjs
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
import { memo } from '../../../../utils/memo.mjs';
|
||||
|
||||
const supportsPartialKeyframes = /*@__PURE__*/ memo(() => {
|
||||
try {
|
||||
document.createElement("div").animate({ opacity: [1] });
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
export { supportsPartialKeyframes };
|
||||
5
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/supports-waapi.mjs
generated
vendored
Normal file
5
node_modules/framer-motion/dist/es/animation/animators/waapi/utils/supports-waapi.mjs
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { memo } from '../../../../utils/memo.mjs';
|
||||
|
||||
const supportsWaapi = /*@__PURE__*/ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
|
||||
|
||||
export { supportsWaapi };
|
||||
87
node_modules/framer-motion/dist/es/animation/generators/inertia.mjs
generated
vendored
Normal file
87
node_modules/framer-motion/dist/es/animation/generators/inertia.mjs
generated
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
import { spring } from './spring/index.mjs';
|
||||
import { calcGeneratorVelocity } from './utils/velocity.mjs';
|
||||
|
||||
function inertia({ keyframes, velocity = 0.0, power = 0.8, timeConstant = 325, bounceDamping = 10, bounceStiffness = 500, modifyTarget, min, max, restDelta = 0.5, restSpeed, }) {
|
||||
const origin = keyframes[0];
|
||||
const state = {
|
||||
done: false,
|
||||
value: origin,
|
||||
};
|
||||
const isOutOfBounds = (v) => (min !== undefined && v < min) || (max !== undefined && v > max);
|
||||
const nearestBoundary = (v) => {
|
||||
if (min === undefined)
|
||||
return max;
|
||||
if (max === undefined)
|
||||
return min;
|
||||
return Math.abs(min - v) < Math.abs(max - v) ? min : max;
|
||||
};
|
||||
let amplitude = power * velocity;
|
||||
const ideal = origin + amplitude;
|
||||
const target = modifyTarget === undefined ? ideal : modifyTarget(ideal);
|
||||
/**
|
||||
* If the target has changed we need to re-calculate the amplitude, otherwise
|
||||
* the animation will start from the wrong position.
|
||||
*/
|
||||
if (target !== ideal)
|
||||
amplitude = target - origin;
|
||||
const calcDelta = (t) => -amplitude * Math.exp(-t / timeConstant);
|
||||
const calcLatest = (t) => target + calcDelta(t);
|
||||
const applyFriction = (t) => {
|
||||
const delta = calcDelta(t);
|
||||
const latest = calcLatest(t);
|
||||
state.done = Math.abs(delta) <= restDelta;
|
||||
state.value = state.done ? target : latest;
|
||||
};
|
||||
/**
|
||||
* Ideally this would resolve for t in a stateless way, we could
|
||||
* do that by always precalculating the animation but as we know
|
||||
* this will be done anyway we can assume that spring will
|
||||
* be discovered during that.
|
||||
*/
|
||||
let timeReachedBoundary;
|
||||
let spring$1;
|
||||
const checkCatchBoundary = (t) => {
|
||||
if (!isOutOfBounds(state.value))
|
||||
return;
|
||||
timeReachedBoundary = t;
|
||||
spring$1 = spring({
|
||||
keyframes: [state.value, nearestBoundary(state.value)],
|
||||
velocity: calcGeneratorVelocity(calcLatest, t, state.value), // TODO: This should be passing * 1000
|
||||
damping: bounceDamping,
|
||||
stiffness: bounceStiffness,
|
||||
restDelta,
|
||||
restSpeed,
|
||||
});
|
||||
};
|
||||
checkCatchBoundary(0);
|
||||
return {
|
||||
calculatedDuration: null,
|
||||
next: (t) => {
|
||||
/**
|
||||
* We need to resolve the friction to figure out if we need a
|
||||
* spring but we don't want to do this twice per frame. So here
|
||||
* we flag if we updated for this frame and later if we did
|
||||
* we can skip doing it again.
|
||||
*/
|
||||
let hasUpdatedFrame = false;
|
||||
if (!spring$1 && timeReachedBoundary === undefined) {
|
||||
hasUpdatedFrame = true;
|
||||
applyFriction(t);
|
||||
checkCatchBoundary(t);
|
||||
}
|
||||
/**
|
||||
* If we have a spring and the provided t is beyond the moment the friction
|
||||
* animation crossed the min/max boundary, use the spring.
|
||||
*/
|
||||
if (timeReachedBoundary !== undefined && t >= timeReachedBoundary) {
|
||||
return spring$1.next(t - timeReachedBoundary);
|
||||
}
|
||||
else {
|
||||
!hasUpdatedFrame && applyFriction(t);
|
||||
return state;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export { inertia };
|
||||
51
node_modules/framer-motion/dist/es/animation/generators/keyframes.mjs
generated
vendored
Normal file
51
node_modules/framer-motion/dist/es/animation/generators/keyframes.mjs
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
import { easeInOut } from '../../easing/ease.mjs';
|
||||
import { isEasingArray } from '../../easing/utils/is-easing-array.mjs';
|
||||
import { easingDefinitionToFunction } from '../../easing/utils/map.mjs';
|
||||
import { interpolate } from '../../utils/interpolate.mjs';
|
||||
import { defaultOffset } from '../../utils/offsets/default.mjs';
|
||||
import { convertOffsetToTimes } from '../../utils/offsets/time.mjs';
|
||||
|
||||
function defaultEasing(values, easing) {
|
||||
return values.map(() => easing || easeInOut).splice(0, values.length - 1);
|
||||
}
|
||||
function keyframes({ duration = 300, keyframes: keyframeValues, times, ease = "easeInOut", }) {
|
||||
/**
|
||||
* Easing functions can be externally defined as strings. Here we convert them
|
||||
* into actual functions.
|
||||
*/
|
||||
const easingFunctions = isEasingArray(ease)
|
||||
? ease.map(easingDefinitionToFunction)
|
||||
: easingDefinitionToFunction(ease);
|
||||
/**
|
||||
* This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
|
||||
* to reduce GC during animation.
|
||||
*/
|
||||
const state = {
|
||||
done: false,
|
||||
value: keyframeValues[0],
|
||||
};
|
||||
/**
|
||||
* Create a times array based on the provided 0-1 offsets
|
||||
*/
|
||||
const absoluteTimes = convertOffsetToTimes(
|
||||
// Only use the provided offsets if they're the correct length
|
||||
// TODO Maybe we should warn here if there's a length mismatch
|
||||
times && times.length === keyframeValues.length
|
||||
? times
|
||||
: defaultOffset(keyframeValues), duration);
|
||||
const mapTimeToKeyframe = interpolate(absoluteTimes, keyframeValues, {
|
||||
ease: Array.isArray(easingFunctions)
|
||||
? easingFunctions
|
||||
: defaultEasing(keyframeValues, easingFunctions),
|
||||
});
|
||||
return {
|
||||
calculatedDuration: duration,
|
||||
next: (t) => {
|
||||
state.value = mapTimeToKeyframe(t);
|
||||
state.done = t >= duration;
|
||||
return state;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export { defaultEasing, keyframes };
|
||||
27
node_modules/framer-motion/dist/es/animation/generators/spring/defaults.mjs
generated
vendored
Normal file
27
node_modules/framer-motion/dist/es/animation/generators/spring/defaults.mjs
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
const springDefaults = {
|
||||
// Default spring physics
|
||||
stiffness: 100,
|
||||
damping: 10,
|
||||
mass: 1.0,
|
||||
velocity: 0.0,
|
||||
// Default duration/bounce-based options
|
||||
duration: 800, // in ms
|
||||
bounce: 0.3,
|
||||
visualDuration: 0.3, // in seconds
|
||||
// Rest thresholds
|
||||
restSpeed: {
|
||||
granular: 0.01,
|
||||
default: 2,
|
||||
},
|
||||
restDelta: {
|
||||
granular: 0.005,
|
||||
default: 0.5,
|
||||
},
|
||||
// Limits
|
||||
minDuration: 0.01, // in seconds
|
||||
maxDuration: 10.0, // in seconds
|
||||
minDamping: 0.05,
|
||||
maxDamping: 1,
|
||||
};
|
||||
|
||||
export { springDefaults };
|
||||
86
node_modules/framer-motion/dist/es/animation/generators/spring/find.mjs
generated
vendored
Normal file
86
node_modules/framer-motion/dist/es/animation/generators/spring/find.mjs
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
import { warning } from 'motion-utils';
|
||||
import { clamp } from '../../../utils/clamp.mjs';
|
||||
import { secondsToMilliseconds, millisecondsToSeconds } from '../../../utils/time-conversion.mjs';
|
||||
import { springDefaults } from './defaults.mjs';
|
||||
|
||||
const safeMin = 0.001;
|
||||
function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass, }) {
|
||||
let envelope;
|
||||
let derivative;
|
||||
warning(duration <= secondsToMilliseconds(springDefaults.maxDuration), "Spring duration must be 10 seconds or less");
|
||||
let dampingRatio = 1 - bounce;
|
||||
/**
|
||||
* Restrict dampingRatio and duration to within acceptable ranges.
|
||||
*/
|
||||
dampingRatio = clamp(springDefaults.minDamping, springDefaults.maxDamping, dampingRatio);
|
||||
duration = clamp(springDefaults.minDuration, springDefaults.maxDuration, millisecondsToSeconds(duration));
|
||||
if (dampingRatio < 1) {
|
||||
/**
|
||||
* Underdamped spring
|
||||
*/
|
||||
envelope = (undampedFreq) => {
|
||||
const exponentialDecay = undampedFreq * dampingRatio;
|
||||
const delta = exponentialDecay * duration;
|
||||
const a = exponentialDecay - velocity;
|
||||
const b = calcAngularFreq(undampedFreq, dampingRatio);
|
||||
const c = Math.exp(-delta);
|
||||
return safeMin - (a / b) * c;
|
||||
};
|
||||
derivative = (undampedFreq) => {
|
||||
const exponentialDecay = undampedFreq * dampingRatio;
|
||||
const delta = exponentialDecay * duration;
|
||||
const d = delta * velocity + velocity;
|
||||
const e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq, 2) * duration;
|
||||
const f = Math.exp(-delta);
|
||||
const g = calcAngularFreq(Math.pow(undampedFreq, 2), dampingRatio);
|
||||
const factor = -envelope(undampedFreq) + safeMin > 0 ? -1 : 1;
|
||||
return (factor * ((d - e) * f)) / g;
|
||||
};
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* Critically-damped spring
|
||||
*/
|
||||
envelope = (undampedFreq) => {
|
||||
const a = Math.exp(-undampedFreq * duration);
|
||||
const b = (undampedFreq - velocity) * duration + 1;
|
||||
return -safeMin + a * b;
|
||||
};
|
||||
derivative = (undampedFreq) => {
|
||||
const a = Math.exp(-undampedFreq * duration);
|
||||
const b = (velocity - undampedFreq) * (duration * duration);
|
||||
return a * b;
|
||||
};
|
||||
}
|
||||
const initialGuess = 5 / duration;
|
||||
const undampedFreq = approximateRoot(envelope, derivative, initialGuess);
|
||||
duration = secondsToMilliseconds(duration);
|
||||
if (isNaN(undampedFreq)) {
|
||||
return {
|
||||
stiffness: springDefaults.stiffness,
|
||||
damping: springDefaults.damping,
|
||||
duration,
|
||||
};
|
||||
}
|
||||
else {
|
||||
const stiffness = Math.pow(undampedFreq, 2) * mass;
|
||||
return {
|
||||
stiffness,
|
||||
damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),
|
||||
duration,
|
||||
};
|
||||
}
|
||||
}
|
||||
const rootIterations = 12;
|
||||
function approximateRoot(envelope, derivative, initialGuess) {
|
||||
let result = initialGuess;
|
||||
for (let i = 1; i < rootIterations; i++) {
|
||||
result = result - envelope(result) / derivative(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function calcAngularFreq(undampedFreq, dampingRatio) {
|
||||
return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
|
||||
}
|
||||
|
||||
export { calcAngularFreq, findSpring };
|
||||
165
node_modules/framer-motion/dist/es/animation/generators/spring/index.mjs
generated
vendored
Normal file
165
node_modules/framer-motion/dist/es/animation/generators/spring/index.mjs
generated
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
import { generateLinearEasing } from '../../animators/waapi/utils/linear.mjs';
|
||||
import { millisecondsToSeconds, secondsToMilliseconds } from '../../../utils/time-conversion.mjs';
|
||||
import { calcGeneratorVelocity } from '../utils/velocity.mjs';
|
||||
import { findSpring, calcAngularFreq } from './find.mjs';
|
||||
import { calcGeneratorDuration, maxGeneratorDuration } from '../utils/calc-duration.mjs';
|
||||
import { clamp } from '../../../utils/clamp.mjs';
|
||||
import { springDefaults } from './defaults.mjs';
|
||||
|
||||
const durationKeys = ["duration", "bounce"];
|
||||
const physicsKeys = ["stiffness", "damping", "mass"];
|
||||
function isSpringType(options, keys) {
|
||||
return keys.some((key) => options[key] !== undefined);
|
||||
}
|
||||
function getSpringOptions(options) {
|
||||
let springOptions = {
|
||||
velocity: springDefaults.velocity,
|
||||
stiffness: springDefaults.stiffness,
|
||||
damping: springDefaults.damping,
|
||||
mass: springDefaults.mass,
|
||||
isResolvedFromDuration: false,
|
||||
...options,
|
||||
};
|
||||
// stiffness/damping/mass overrides duration/bounce
|
||||
if (!isSpringType(options, physicsKeys) &&
|
||||
isSpringType(options, durationKeys)) {
|
||||
if (options.visualDuration) {
|
||||
const visualDuration = options.visualDuration;
|
||||
const root = (2 * Math.PI) / (visualDuration * 1.2);
|
||||
const stiffness = root * root;
|
||||
const damping = 2 * clamp(0.05, 1, 1 - options.bounce) * Math.sqrt(stiffness);
|
||||
springOptions = {
|
||||
...springOptions,
|
||||
mass: springDefaults.mass,
|
||||
stiffness,
|
||||
damping,
|
||||
};
|
||||
}
|
||||
else {
|
||||
const derived = findSpring(options);
|
||||
springOptions = {
|
||||
...springOptions,
|
||||
...derived,
|
||||
mass: springDefaults.mass,
|
||||
};
|
||||
springOptions.isResolvedFromDuration = true;
|
||||
}
|
||||
}
|
||||
return springOptions;
|
||||
}
|
||||
function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce = springDefaults.bounce) {
|
||||
const options = typeof optionsOrVisualDuration !== "object"
|
||||
? {
|
||||
visualDuration: optionsOrVisualDuration,
|
||||
keyframes: [0, 1],
|
||||
bounce,
|
||||
}
|
||||
: optionsOrVisualDuration;
|
||||
let { restSpeed, restDelta } = options;
|
||||
const origin = options.keyframes[0];
|
||||
const target = options.keyframes[options.keyframes.length - 1];
|
||||
/**
|
||||
* This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
|
||||
* to reduce GC during animation.
|
||||
*/
|
||||
const state = { done: false, value: origin };
|
||||
const { stiffness, damping, mass, duration, velocity, isResolvedFromDuration, } = getSpringOptions({
|
||||
...options,
|
||||
velocity: -millisecondsToSeconds(options.velocity || 0),
|
||||
});
|
||||
const initialVelocity = velocity || 0.0;
|
||||
const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass));
|
||||
const initialDelta = target - origin;
|
||||
const undampedAngularFreq = millisecondsToSeconds(Math.sqrt(stiffness / mass));
|
||||
/**
|
||||
* If we're working on a granular scale, use smaller defaults for determining
|
||||
* when the spring is finished.
|
||||
*
|
||||
* These defaults have been selected emprically based on what strikes a good
|
||||
* ratio between feeling good and finishing as soon as changes are imperceptible.
|
||||
*/
|
||||
const isGranularScale = Math.abs(initialDelta) < 5;
|
||||
restSpeed || (restSpeed = isGranularScale
|
||||
? springDefaults.restSpeed.granular
|
||||
: springDefaults.restSpeed.default);
|
||||
restDelta || (restDelta = isGranularScale
|
||||
? springDefaults.restDelta.granular
|
||||
: springDefaults.restDelta.default);
|
||||
let resolveSpring;
|
||||
if (dampingRatio < 1) {
|
||||
const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
|
||||
// Underdamped spring
|
||||
resolveSpring = (t) => {
|
||||
const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
|
||||
return (target -
|
||||
envelope *
|
||||
(((initialVelocity +
|
||||
dampingRatio * undampedAngularFreq * initialDelta) /
|
||||
angularFreq) *
|
||||
Math.sin(angularFreq * t) +
|
||||
initialDelta * Math.cos(angularFreq * t)));
|
||||
};
|
||||
}
|
||||
else if (dampingRatio === 1) {
|
||||
// Critically damped spring
|
||||
resolveSpring = (t) => target -
|
||||
Math.exp(-undampedAngularFreq * t) *
|
||||
(initialDelta +
|
||||
(initialVelocity + undampedAngularFreq * initialDelta) * t);
|
||||
}
|
||||
else {
|
||||
// Overdamped spring
|
||||
const dampedAngularFreq = undampedAngularFreq * Math.sqrt(dampingRatio * dampingRatio - 1);
|
||||
resolveSpring = (t) => {
|
||||
const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
|
||||
// When performing sinh or cosh values can hit Infinity so we cap them here
|
||||
const freqForT = Math.min(dampedAngularFreq * t, 300);
|
||||
return (target -
|
||||
(envelope *
|
||||
((initialVelocity +
|
||||
dampingRatio * undampedAngularFreq * initialDelta) *
|
||||
Math.sinh(freqForT) +
|
||||
dampedAngularFreq *
|
||||
initialDelta *
|
||||
Math.cosh(freqForT))) /
|
||||
dampedAngularFreq);
|
||||
};
|
||||
}
|
||||
const generator = {
|
||||
calculatedDuration: isResolvedFromDuration ? duration || null : null,
|
||||
next: (t) => {
|
||||
const current = resolveSpring(t);
|
||||
if (!isResolvedFromDuration) {
|
||||
let currentVelocity = 0.0;
|
||||
/**
|
||||
* We only need to calculate velocity for under-damped springs
|
||||
* as over- and critically-damped springs can't overshoot, so
|
||||
* checking only for displacement is enough.
|
||||
*/
|
||||
if (dampingRatio < 1) {
|
||||
currentVelocity =
|
||||
t === 0
|
||||
? secondsToMilliseconds(initialVelocity)
|
||||
: calcGeneratorVelocity(resolveSpring, t, current);
|
||||
}
|
||||
const isBelowVelocityThreshold = Math.abs(currentVelocity) <= restSpeed;
|
||||
const isBelowDisplacementThreshold = Math.abs(target - current) <= restDelta;
|
||||
state.done =
|
||||
isBelowVelocityThreshold && isBelowDisplacementThreshold;
|
||||
}
|
||||
else {
|
||||
state.done = t >= duration;
|
||||
}
|
||||
state.value = state.done ? target : current;
|
||||
return state;
|
||||
},
|
||||
toString: () => {
|
||||
const calculatedDuration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
|
||||
const easing = generateLinearEasing((progress) => generator.next(calculatedDuration * progress).value, calculatedDuration, 30);
|
||||
return calculatedDuration + "ms " + easing;
|
||||
},
|
||||
};
|
||||
return generator;
|
||||
}
|
||||
|
||||
export { spring };
|
||||
17
node_modules/framer-motion/dist/es/animation/generators/utils/calc-duration.mjs
generated
vendored
Normal file
17
node_modules/framer-motion/dist/es/animation/generators/utils/calc-duration.mjs
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Implement a practical max duration for keyframe generation
|
||||
* to prevent infinite loops
|
||||
*/
|
||||
const maxGeneratorDuration = 20000;
|
||||
function calcGeneratorDuration(generator) {
|
||||
let duration = 0;
|
||||
const timeStep = 50;
|
||||
let state = generator.next(duration);
|
||||
while (!state.done && duration < maxGeneratorDuration) {
|
||||
duration += timeStep;
|
||||
state = generator.next(duration);
|
||||
}
|
||||
return duration >= maxGeneratorDuration ? Infinity : duration;
|
||||
}
|
||||
|
||||
export { calcGeneratorDuration, maxGeneratorDuration };
|
||||
5
node_modules/framer-motion/dist/es/animation/generators/utils/is-generator.mjs
generated
vendored
Normal file
5
node_modules/framer-motion/dist/es/animation/generators/utils/is-generator.mjs
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
function isGenerator(type) {
|
||||
return typeof type === "function";
|
||||
}
|
||||
|
||||
export { isGenerator };
|
||||
9
node_modules/framer-motion/dist/es/animation/generators/utils/velocity.mjs
generated
vendored
Normal file
9
node_modules/framer-motion/dist/es/animation/generators/utils/velocity.mjs
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import { velocityPerSecond } from '../../../utils/velocity-per-second.mjs';
|
||||
|
||||
const velocitySampleDuration = 5; // ms
|
||||
function calcGeneratorVelocity(resolveValue, t, current) {
|
||||
const prevT = Math.max(t - velocitySampleDuration, 0);
|
||||
return velocityPerSecond(current - resolveValue(prevT), t - prevT);
|
||||
}
|
||||
|
||||
export { calcGeneratorVelocity };
|
||||
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 };
|
||||
17
node_modules/framer-motion/dist/es/animation/hooks/use-animate-style.mjs
generated
vendored
Normal file
17
node_modules/framer-motion/dist/es/animation/hooks/use-animate-style.mjs
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
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 };
|
||||
17
node_modules/framer-motion/dist/es/animation/hooks/use-animate.mjs
generated
vendored
Normal file
17
node_modules/framer-motion/dist/es/animation/hooks/use-animate.mjs
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
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());
|
||||
});
|
||||
return [scope, animate];
|
||||
}
|
||||
|
||||
export { useAnimate };
|
||||
64
node_modules/framer-motion/dist/es/animation/hooks/use-animated-state.mjs
generated
vendored
Normal file
64
node_modules/framer-motion/dist/es/animation/hooks/use-animated-state.mjs
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
import { useState, useLayoutEffect } from 'react';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { makeUseVisualState } from '../../motion/utils/use-visual-state.mjs';
|
||||
import { createBox } from '../../projection/geometry/models.mjs';
|
||||
import { VisualElement } from '../../render/VisualElement.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 };
|
||||
41
node_modules/framer-motion/dist/es/animation/hooks/use-animation.mjs
generated
vendored
Normal file
41
node_modules/framer-motion/dist/es/animation/hooks/use-animation.mjs
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
import { animationControls } from './animation-controls.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
|
||||
|
||||
/**
|
||||
* Creates `AnimationControls`, which can be used to manually start, stop
|
||||
* and sequence animations on one or more components.
|
||||
*
|
||||
* The returned `AnimationControls` 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 };
|
||||
113
node_modules/framer-motion/dist/es/animation/interfaces/motion-value.mjs
generated
vendored
Normal file
113
node_modules/framer-motion/dist/es/animation/interfaces/motion-value.mjs
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
import { secondsToMilliseconds } from '../../utils/time-conversion.mjs';
|
||||
import { getDefaultTransition } from '../utils/default-transitions.mjs';
|
||||
import { getValueTransition } from '../utils/get-value-transition.mjs';
|
||||
import { MotionGlobalConfig } from '../../utils/GlobalConfig.mjs';
|
||||
import { instantAnimationState } from '../../utils/use-instant-transition-state.mjs';
|
||||
import { getFinalKeyframe } from '../animators/waapi/utils/get-final-keyframe.mjs';
|
||||
import { frame } from '../../frameloop/frame.mjs';
|
||||
import { AcceleratedAnimation } from '../animators/AcceleratedAnimation.mjs';
|
||||
import { MainThreadAnimation } from '../animators/MainThreadAnimation.mjs';
|
||||
import { GroupPlaybackControls } from '../GroupPlaybackControls.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
|
||||
* unqiue 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 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 GroupPlaybackControls([]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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 };
|
||||
75
node_modules/framer-motion/dist/es/animation/interfaces/visual-element-target.mjs
generated
vendored
Normal file
75
node_modules/framer-motion/dist/es/animation/interfaces/visual-element-target.mjs
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
import { transformProps } from '../../render/html/utils/transform.mjs';
|
||||
import { animateMotionValue } from './motion-value.mjs';
|
||||
import { setTarget } from '../../render/utils/setters.mjs';
|
||||
import { getValueTransition } from '../utils/get-value-transition.mjs';
|
||||
import { getOptimisedAppearId } from '../optimized-appear/get-appear-id.mjs';
|
||||
import { addValueToWillChange } from '../../value/use-will-change/add-will-change.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 } = {}) {
|
||||
var _a;
|
||||
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, (_a = visualElement.latestValues[key]) !== null && _a !== void 0 ? _a : null);
|
||||
const valueTarget = target[key];
|
||||
if (valueTarget === undefined ||
|
||||
(animationTypeState &&
|
||||
shouldBlockAnimation(animationTypeState, key))) {
|
||||
continue;
|
||||
}
|
||||
const valueTransition = {
|
||||
delay,
|
||||
...getValueTransition(transition || {}, key),
|
||||
};
|
||||
/**
|
||||
* 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 && transformProps.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 };
|
||||
66
node_modules/framer-motion/dist/es/animation/interfaces/visual-element-variant.mjs
generated
vendored
Normal file
66
node_modules/framer-motion/dist/es/animation/interfaces/visual-element-variant.mjs
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
import { resolveVariant } from '../../render/utils/resolve-dynamic-variants.mjs';
|
||||
import { animateTarget } from './visual-element-target.mjs';
|
||||
|
||||
function animateVariant(visualElement, variant, options = {}) {
|
||||
var _a;
|
||||
const resolved = resolveVariant(visualElement, variant, options.type === "exit"
|
||||
? (_a = visualElement.presenceContext) === null || _a === void 0 ? void 0 : _a.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, delayChildren + forwardDelay, 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, delayChildren = 0, staggerChildren = 0, staggerDirection = 1, options) {
|
||||
const animations = [];
|
||||
const maxStaggerDuration = (visualElement.variantChildren.size - 1) * staggerChildren;
|
||||
const generateStaggerDuration = staggerDirection === 1
|
||||
? (i = 0) => i * staggerChildren
|
||||
: (i = 0) => maxStaggerDuration - i * staggerChildren;
|
||||
Array.from(visualElement.variantChildren)
|
||||
.sort(sortByTreeOrder)
|
||||
.forEach((child, i) => {
|
||||
child.notify("AnimationStart", variant);
|
||||
animations.push(animateVariant(child, variant, {
|
||||
...options,
|
||||
delay: delayChildren + generateStaggerDuration(i),
|
||||
}).then(() => child.notify("AnimationComplete", variant)));
|
||||
});
|
||||
return Promise.all(animations);
|
||||
}
|
||||
function sortByTreeOrder(a, b) {
|
||||
return a.sortNodePosition(b);
|
||||
}
|
||||
|
||||
export { animateVariant, sortByTreeOrder };
|
||||
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 };
|
||||
40
node_modules/framer-motion/dist/es/animation/optimized-appear/handoff.mjs
generated
vendored
Normal file
40
node_modules/framer-motion/dist/es/animation/optimized-appear/handoff.mjs
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
import { appearAnimationStore } from './store.mjs';
|
||||
import { appearStoreId } from './store-id.mjs';
|
||||
|
||||
function handoffOptimizedAppearAnimation(elementId, valueName, frame) {
|
||||
var _a;
|
||||
const storeId = appearStoreId(elementId, valueName);
|
||||
const optimisedAnimation = appearAnimationStore.get(storeId);
|
||||
if (!optimisedAnimation) {
|
||||
return null;
|
||||
}
|
||||
const { animation, startTime } = optimisedAnimation;
|
||||
function cancelAnimation() {
|
||||
var _a;
|
||||
(_a = window.MotionCancelOptimisedAnimation) === null || _a === void 0 ? void 0 : _a.call(window, 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 || ((_a = window.MotionHandoffIsComplete) === null || _a === void 0 ? void 0 : _a.call(window, 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 };
|
||||
173
node_modules/framer-motion/dist/es/animation/optimized-appear/start.mjs
generated
vendored
Normal file
173
node_modules/framer-motion/dist/es/animation/optimized-appear/start.mjs
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
import { appearStoreId } from './store-id.mjs';
|
||||
import { startWaapiAnimation } from '../animators/waapi/index.mjs';
|
||||
import { optimizedAppearDataId } from './data-id.mjs';
|
||||
import { handoffOptimizedAppearAnimation } from './handoff.mjs';
|
||||
import { appearAnimationStore, appearComplete } from './store.mjs';
|
||||
import { noop } from 'motion-utils';
|
||||
import { getOptimisedAppearId } from './get-appear-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) => {
|
||||
var _a, _b;
|
||||
const appearId = getOptimisedAppearId(visualElement);
|
||||
if (!appearId)
|
||||
return;
|
||||
const valueIsOptimised = (_a = window.MotionHasOptimisedAnimation) === null || _a === void 0 ? void 0 : _a.call(window, appearId, valueName);
|
||||
const externalAnimationValue = (_b = visualElement.props.values) === null || _b === void 0 ? void 0 : _b[valueName];
|
||||
if (!valueIsOptimised || !externalAnimationValue)
|
||||
return;
|
||||
const removeSyncCheck = value.on("change", (latestValue) => {
|
||||
var _a;
|
||||
if (externalAnimationValue.get() !== latestValue) {
|
||||
(_a = window.MotionCancelOptimisedAnimation) === null || _a === void 0 ? void 0 : _a.call(window, 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 '../../render/html/utils/transform.mjs';
|
||||
|
||||
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 };
|
||||
230
node_modules/framer-motion/dist/es/animation/sequence/create.mjs
generated
vendored
Normal file
230
node_modules/framer-motion/dist/es/animation/sequence/create.mjs
generated
vendored
Normal file
@ -0,0 +1,230 @@
|
||||
import { createGeneratorEasing } from '../../easing/utils/create-generator-easing.mjs';
|
||||
import { defaultOffset } from '../../utils/offsets/default.mjs';
|
||||
import { fillOffset } from '../../utils/offsets/fill.mjs';
|
||||
import { progress } from '../../utils/progress.mjs';
|
||||
import { secondsToMilliseconds } from '../../utils/time-conversion.mjs';
|
||||
import { isMotionValue } from '../../value/utils/is-motion-value.mjs';
|
||||
import { resolveSubjects } from '../animate/resolve-subjects.mjs';
|
||||
import { isGenerator } from '../generators/utils/is-generator.mjs';
|
||||
import { calcNextTime } from './utils/calc-time.mjs';
|
||||
import { addKeyframes } from './utils/edit.mjs';
|
||||
import { compareByTime } from './utils/sort.mjs';
|
||||
|
||||
const defaultSegmentEasing = "easeInOut";
|
||||
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", ...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 === null || generators === void 0 ? void 0 : generators[type];
|
||||
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 !== null && duration !== void 0 ? duration : (duration = defaultDuration);
|
||||
const startTime = currentTime + calculatedDelay;
|
||||
const targetTime = startTime + duration;
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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 };
|
||||
21
node_modules/framer-motion/dist/es/animation/sequence/utils/calc-time.mjs
generated
vendored
Normal file
21
node_modules/framer-motion/dist/es/animation/sequence/utils/calc-time.mjs
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* 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) {
|
||||
var _a;
|
||||
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 {
|
||||
return (_a = labels.get(next)) !== null && _a !== void 0 ? _a : current;
|
||||
}
|
||||
}
|
||||
|
||||
export { calcNextTime };
|
||||
31
node_modules/framer-motion/dist/es/animation/sequence/utils/edit.mjs
generated
vendored
Normal file
31
node_modules/framer-motion/dist/es/animation/sequence/utils/edit.mjs
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
import { getEasingForSegment } from '../../../easing/utils/get-easing-for-segment.mjs';
|
||||
import { removeItem } from '../../../utils/array.mjs';
|
||||
import { mixNumber } from '../../../utils/mix/number.mjs';
|
||||
|
||||
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 };
|
||||
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 };
|
||||
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 } from '../../render/dom/utils/is-svg-element.mjs';
|
||||
import { SVGVisualElement } from '../../render/svg/SVGVisualElement.mjs';
|
||||
import { HTMLVisualElement } from '../../render/html/HTMLVisualElement.mjs';
|
||||
import { visualElementStore } from '../../render/store.mjs';
|
||||
import { ObjectVisualElement } from '../../render/object/ObjectVisualElement.mjs';
|
||||
|
||||
function createDOMVisualElement(element) {
|
||||
const options = {
|
||||
presenceContext: null,
|
||||
props: {},
|
||||
visualState: {
|
||||
renderState: {
|
||||
transform: {},
|
||||
transformOrigin: {},
|
||||
style: {},
|
||||
vars: {},
|
||||
attrs: {},
|
||||
},
|
||||
latestValues: {},
|
||||
},
|
||||
};
|
||||
const node = isSVGElement(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 '../../render/html/utils/transform.mjs';
|
||||
|
||||
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 };
|
||||
9
node_modules/framer-motion/dist/es/animation/utils/get-value-transition.mjs
generated
vendored
Normal file
9
node_modules/framer-motion/dist/es/animation/utils/get-value-transition.mjs
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
function getValueTransition(transition, key) {
|
||||
return transition
|
||||
? transition[key] ||
|
||||
transition["default"] ||
|
||||
transition
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export { getValueTransition };
|
||||
30
node_modules/framer-motion/dist/es/animation/utils/is-animatable.mjs
generated
vendored
Normal file
30
node_modules/framer-motion/dist/es/animation/utils/is-animatable.mjs
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
import { complex } from '../../value/types/complex/index.mjs';
|
||||
|
||||
/**
|
||||
* Check if a value is animatable. Examples:
|
||||
*
|
||||
* ✅: 100, "100px", "#fff"
|
||||
* ❌: "block", "url(2.jpg)"
|
||||
* @param value
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
const isAnimatable = (value, name) => {
|
||||
// If the list of keys tat might be non-animatable grows, replace with Set
|
||||
if (name === "zIndex")
|
||||
return false;
|
||||
// If it's a number or a keyframes array, we can animate it. We might at some point
|
||||
// need to do a deep isAnimatable check of keyframes, or let Popmotion handle this,
|
||||
// but for now lets leave it like this for performance reasons
|
||||
if (typeof value === "number" || Array.isArray(value))
|
||||
return true;
|
||||
if (typeof value === "string" && // It's animatable if we have a string
|
||||
(complex.test(value) || value === "0") && // And it contains numbers and/or colors
|
||||
!value.startsWith("url(") // Unless it starts with "url("
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export { isAnimatable };
|
||||
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 };
|
||||
15
node_modules/framer-motion/dist/es/animation/utils/is-none.mjs
generated
vendored
Normal file
15
node_modules/framer-motion/dist/es/animation/utils/is-none.mjs
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { isZeroValueString } from '../../utils/is-zero-value-string.mjs';
|
||||
|
||||
function isNone(value) {
|
||||
if (typeof value === "number") {
|
||||
return value === 0;
|
||||
}
|
||||
else if (value !== null) {
|
||||
return value === "none" || value === "0" || isZeroValueString(value);
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export { isNone };
|
||||
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 };
|
||||
26
node_modules/framer-motion/dist/es/animation/utils/stagger.mjs
generated
vendored
Normal file
26
node_modules/framer-motion/dist/es/animation/utils/stagger.mjs
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import { easingDefinitionToFunction } from '../../easing/utils/map.mjs';
|
||||
|
||||
function getOriginIndex(from, total) {
|
||||
if (from === "first") {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
const lastIndex = total - 1;
|
||||
return from === "last" ? lastIndex : lastIndex / 2;
|
||||
}
|
||||
}
|
||||
function stagger(duration = 0.1, { startDelay = 0, from = 0, ease } = {}) {
|
||||
return (i, total) => {
|
||||
const fromIndex = typeof from === "number" ? from : getOriginIndex(from, total);
|
||||
const distance = Math.abs(fromIndex - i);
|
||||
let delay = duration * distance;
|
||||
if (ease) {
|
||||
const maxDelay = total * duration;
|
||||
const easingFunction = easingDefinitionToFunction(ease);
|
||||
delay = easingFunction(delay / maxDelay) * maxDelay;
|
||||
}
|
||||
return startDelay + delay;
|
||||
};
|
||||
}
|
||||
|
||||
export { getOriginIndex, stagger };
|
||||
3
node_modules/framer-motion/dist/es/client.mjs
generated
vendored
Normal file
3
node_modules/framer-motion/dist/es/client.mjs
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
"use client";
|
||||
export { createMotionComponent as create } from './render/components/motion/create.mjs';
|
||||
export { MotionA as a, MotionAbbr as abbr, MotionAddress as address, MotionAnimate as animate, MotionArea as area, MotionArticle as article, MotionAside as aside, MotionAudio as audio, MotionB as b, MotionBase as base, MotionBdi as bdi, MotionBdo as bdo, MotionBig as big, MotionBlockquote as blockquote, MotionBody as body, MotionButton as button, MotionCanvas as canvas, MotionCaption as caption, MotionCircle as circle, MotionCite as cite, MotionClipPath as clipPath, MotionCode as code, MotionCol as col, MotionColgroup as colgroup, MotionData as data, MotionDatalist as datalist, MotionDd as dd, MotionDefs as defs, MotionDel as del, MotionDesc as desc, MotionDetails as details, MotionDfn as dfn, MotionDialog as dialog, MotionDiv as div, MotionDl as dl, MotionDt as dt, MotionEllipse as ellipse, MotionEm as em, MotionEmbed as embed, MotionFeBlend as feBlend, MotionFeColorMatrix as feColorMatrix, MotionFeComponentTransfer as feComponentTransfer, MotionFeComposite as feComposite, MotionFeConvolveMatrix as feConvolveMatrix, MotionFeDiffuseLighting as feDiffuseLighting, MotionFeDisplacementMap as feDisplacementMap, MotionFeDistantLight as feDistantLight, MotionFeDropShadow as feDropShadow, MotionFeFlood as feFlood, MotionFeFuncA as feFuncA, MotionFeFuncB as feFuncB, MotionFeFuncG as feFuncG, MotionFeFuncR as feFuncR, MotionFeGaussianBlur as feGaussianBlur, MotionFeImage as feImage, MotionFeMerge as feMerge, MotionFeMergeNode as feMergeNode, MotionFeMorphology as feMorphology, MotionFeOffset as feOffset, MotionFePointLight as fePointLight, MotionFeSpecularLighting as feSpecularLighting, MotionFeSpotLight as feSpotLight, MotionFeTile as feTile, MotionFeTurbulence as feTurbulence, MotionFieldset as fieldset, MotionFigcaption as figcaption, MotionFigure as figure, MotionFilter as filter, MotionFooter as footer, MotionForeignObject as foreignObject, MotionForm as form, MotionG as g, MotionH1 as h1, MotionH2 as h2, MotionH3 as h3, MotionH4 as h4, MotionH5 as h5, MotionH6 as h6, MotionHead as head, MotionHeader as header, MotionHgroup as hgroup, MotionHr as hr, MotionHtml as html, MotionI as i, MotionIframe as iframe, MotionImage as image, MotionImg as img, MotionInput as input, MotionIns as ins, MotionKbd as kbd, MotionKeygen as keygen, MotionLabel as label, MotionLegend as legend, MotionLi as li, MotionLine as line, MotionLinearGradient as linearGradient, MotionLink as link, MotionMain as main, MotionMap as map, MotionMark as mark, MotionMarker as marker, MotionMask as mask, MotionMenu as menu, MotionMenuitem as menuitem, MotionMetadata as metadata, MotionMeter as meter, MotionNav as nav, MotionObject as object, MotionOl as ol, MotionOptgroup as optgroup, MotionOption as option, MotionOutput as output, MotionP as p, MotionParam as param, MotionPath as path, MotionPattern as pattern, MotionPicture as picture, MotionPolygon as polygon, MotionPolyline as polyline, MotionPre as pre, MotionProgress as progress, MotionQ as q, MotionRadialGradient as radialGradient, MotionRect as rect, MotionRp as rp, MotionRt as rt, MotionRuby as ruby, MotionS as s, MotionSamp as samp, MotionScript as script, MotionSection as section, MotionSelect as select, MotionSmall as small, MotionSource as source, MotionSpan as span, MotionStop as stop, MotionStrong as strong, MotionStyle as style, MotionSub as sub, MotionSummary as summary, MotionSup as sup, MotionSvg as svg, MotionSymbol as symbol, MotionTable as table, MotionTbody as tbody, MotionTd as td, MotionText as text, MotionTextPath as textPath, MotionTextarea as textarea, MotionTfoot as tfoot, MotionTh as th, MotionThead as thead, MotionTime as time, MotionTitle as title, MotionTr as tr, MotionTrack as track, MotionTspan as tspan, MotionU as u, MotionUl as ul, MotionUse as use, MotionVideo as video, MotionView as view, MotionWbr as wbr, MotionWebview as webview } from './render/components/motion/elements.mjs';
|
||||
77
node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
generated
vendored
Normal file
77
node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import * as React from 'react';
|
||||
import { useId, useRef, useContext, useInsertionEffect } from 'react';
|
||||
import { MotionConfigContext } from '../../context/MotionConfigContext.mjs';
|
||||
|
||||
/**
|
||||
* Measurement functionality has to be within a separate component
|
||||
* to leverage snapshot lifecycle.
|
||||
*/
|
||||
class PopChildMeasure extends React.Component {
|
||||
getSnapshotBeforeUpdate(prevProps) {
|
||||
const element = this.props.childRef.current;
|
||||
if (element && prevProps.isPresent && !this.props.isPresent) {
|
||||
const size = this.props.sizeRef.current;
|
||||
size.height = element.offsetHeight || 0;
|
||||
size.width = element.offsetWidth || 0;
|
||||
size.top = element.offsetTop;
|
||||
size.left = element.offsetLeft;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Required with getSnapshotBeforeUpdate to stop React complaining.
|
||||
*/
|
||||
componentDidUpdate() { }
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
function PopChild({ children, isPresent }) {
|
||||
const id = useId();
|
||||
const ref = useRef(null);
|
||||
const size = useRef({
|
||||
width: 0,
|
||||
height: 0,
|
||||
top: 0,
|
||||
left: 0,
|
||||
});
|
||||
const { nonce } = useContext(MotionConfigContext);
|
||||
/**
|
||||
* We create and inject a style block so we can apply this explicit
|
||||
* sizing in a non-destructive manner by just deleting the style block.
|
||||
*
|
||||
* We can't apply size via render as the measurement happens
|
||||
* in getSnapshotBeforeUpdate (post-render), likewise if we apply the
|
||||
* styles directly on the DOM node, we might be overwriting
|
||||
* styles set via the style prop.
|
||||
*/
|
||||
useInsertionEffect(() => {
|
||||
const { width, height, top, left } = size.current;
|
||||
if (isPresent || !ref.current || !width || !height)
|
||||
return;
|
||||
ref.current.dataset.motionPopId = id;
|
||||
const style = document.createElement("style");
|
||||
if (nonce)
|
||||
style.nonce = nonce;
|
||||
document.head.appendChild(style);
|
||||
if (style.sheet) {
|
||||
style.sheet.insertRule(`
|
||||
[data-motion-pop-id="${id}"] {
|
||||
position: absolute !important;
|
||||
width: ${width}px !important;
|
||||
height: ${height}px !important;
|
||||
top: ${top}px !important;
|
||||
left: ${left}px !important;
|
||||
}
|
||||
`);
|
||||
}
|
||||
return () => {
|
||||
document.head.removeChild(style);
|
||||
};
|
||||
}, [isPresent]);
|
||||
return (jsx(PopChildMeasure, { isPresent: isPresent, childRef: ref, sizeRef: size, children: React.cloneElement(children, { ref }) }));
|
||||
}
|
||||
|
||||
export { PopChild };
|
||||
61
node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
generated
vendored
Normal file
61
node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import * as React from 'react';
|
||||
import { useId, useCallback, useMemo } from 'react';
|
||||
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { PopChild } from './PopChild.mjs';
|
||||
|
||||
const PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, presenceAffectsLayout, mode, }) => {
|
||||
const presenceChildren = useConstant(newChildrenMap);
|
||||
const id = useId();
|
||||
const memoizedOnExitComplete = useCallback((childId) => {
|
||||
presenceChildren.set(childId, true);
|
||||
for (const isComplete of presenceChildren.values()) {
|
||||
if (!isComplete)
|
||||
return; // can stop searching when any is incomplete
|
||||
}
|
||||
onExitComplete && onExitComplete();
|
||||
}, [presenceChildren, onExitComplete]);
|
||||
const context = useMemo(() => ({
|
||||
id,
|
||||
initial,
|
||||
isPresent,
|
||||
custom,
|
||||
onExitComplete: memoizedOnExitComplete,
|
||||
register: (childId) => {
|
||||
presenceChildren.set(childId, false);
|
||||
return () => presenceChildren.delete(childId);
|
||||
},
|
||||
}),
|
||||
/**
|
||||
* If the presence of a child affects the layout of the components around it,
|
||||
* we want to make a new context value to ensure they get re-rendered
|
||||
* so they can detect that layout change.
|
||||
*/
|
||||
presenceAffectsLayout
|
||||
? [Math.random(), memoizedOnExitComplete]
|
||||
: [isPresent, memoizedOnExitComplete]);
|
||||
useMemo(() => {
|
||||
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
||||
}, [isPresent]);
|
||||
/**
|
||||
* If there's no `motion` components to fire exit animations, we want to remove this
|
||||
* component immediately.
|
||||
*/
|
||||
React.useEffect(() => {
|
||||
!isPresent &&
|
||||
!presenceChildren.size &&
|
||||
onExitComplete &&
|
||||
onExitComplete();
|
||||
}, [isPresent]);
|
||||
if (mode === "popLayout") {
|
||||
children = jsx(PopChild, { isPresent: isPresent, children: children });
|
||||
}
|
||||
return (jsx(PresenceContext.Provider, { value: context, children: children }));
|
||||
};
|
||||
function newChildrenMap() {
|
||||
return new Map();
|
||||
}
|
||||
|
||||
export { PresenceChild };
|
||||
163
node_modules/framer-motion/dist/es/components/AnimatePresence/index.mjs
generated
vendored
Normal file
163
node_modules/framer-motion/dist/es/components/AnimatePresence/index.mjs
generated
vendored
Normal file
@ -0,0 +1,163 @@
|
||||
"use client";
|
||||
import { jsx, Fragment } from 'react/jsx-runtime';
|
||||
import { useMemo, useRef, useState, useContext } from 'react';
|
||||
import { PresenceChild } from './PresenceChild.mjs';
|
||||
import { LayoutGroupContext } from '../../context/LayoutGroupContext.mjs';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { onlyElements, getChildKey } from './utils.mjs';
|
||||
import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
|
||||
|
||||
/**
|
||||
* `AnimatePresence` enables the animation of components that have been removed from the tree.
|
||||
*
|
||||
* When adding/removing more than a single child, every child **must** be given a unique `key` prop.
|
||||
*
|
||||
* Any `motion` components that have an `exit` property defined will animate out when removed from
|
||||
* the tree.
|
||||
*
|
||||
* ```jsx
|
||||
* import { motion, AnimatePresence } from 'framer-motion'
|
||||
*
|
||||
* export const Items = ({ items }) => (
|
||||
* <AnimatePresence>
|
||||
* {items.map(item => (
|
||||
* <motion.div
|
||||
* key={item.id}
|
||||
* initial={{ opacity: 0 }}
|
||||
* animate={{ opacity: 1 }}
|
||||
* exit={{ opacity: 0 }}
|
||||
* />
|
||||
* ))}
|
||||
* </AnimatePresence>
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* You can sequence exit animations throughout a tree using variants.
|
||||
*
|
||||
* If a child contains multiple `motion` components with `exit` props, it will only unmount the child
|
||||
* once all `motion` components have finished animating out. Likewise, any components using
|
||||
* `usePresence` all need to call `safeToRemove`.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
const AnimatePresence = ({ children, exitBeforeEnter, custom, initial = true, onExitComplete, presenceAffectsLayout = true, mode = "sync", }) => {
|
||||
invariant(!exitBeforeEnter, "Replace exitBeforeEnter with mode='wait'");
|
||||
/**
|
||||
* Filter any children that aren't ReactElements. We can only track components
|
||||
* between renders with a props.key.
|
||||
*/
|
||||
const presentChildren = useMemo(() => onlyElements(children), [children]);
|
||||
/**
|
||||
* Track the keys of the currently rendered children. This is used to
|
||||
* determine which children are exiting.
|
||||
*/
|
||||
const presentKeys = presentChildren.map(getChildKey);
|
||||
/**
|
||||
* If `initial={false}` we only want to pass this to components in the first render.
|
||||
*/
|
||||
const isInitialRender = useRef(true);
|
||||
/**
|
||||
* A ref containing the currently present children. When all exit animations
|
||||
* are complete, we use this to re-render the component with the latest children
|
||||
* *committed* rather than the latest children *rendered*.
|
||||
*/
|
||||
const pendingPresentChildren = useRef(presentChildren);
|
||||
/**
|
||||
* Track which exiting children have finished animating out.
|
||||
*/
|
||||
const exitComplete = useConstant(() => new Map());
|
||||
/**
|
||||
* Save children to render as React state. To ensure this component is concurrent-safe,
|
||||
* we check for exiting children via an effect.
|
||||
*/
|
||||
const [diffedChildren, setDiffedChildren] = useState(presentChildren);
|
||||
const [renderedChildren, setRenderedChildren] = useState(presentChildren);
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
isInitialRender.current = false;
|
||||
pendingPresentChildren.current = presentChildren;
|
||||
/**
|
||||
* Update complete status of exiting children.
|
||||
*/
|
||||
for (let i = 0; i < renderedChildren.length; i++) {
|
||||
const key = getChildKey(renderedChildren[i]);
|
||||
if (!presentKeys.includes(key)) {
|
||||
if (exitComplete.get(key) !== true) {
|
||||
exitComplete.set(key, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
exitComplete.delete(key);
|
||||
}
|
||||
}
|
||||
}, [renderedChildren, presentKeys.length, presentKeys.join("-")]);
|
||||
const exitingChildren = [];
|
||||
if (presentChildren !== diffedChildren) {
|
||||
let nextChildren = [...presentChildren];
|
||||
/**
|
||||
* Loop through all the currently rendered components and decide which
|
||||
* are exiting.
|
||||
*/
|
||||
for (let i = 0; i < renderedChildren.length; i++) {
|
||||
const child = renderedChildren[i];
|
||||
const key = getChildKey(child);
|
||||
if (!presentKeys.includes(key)) {
|
||||
nextChildren.splice(i, 0, child);
|
||||
exitingChildren.push(child);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* If we're in "wait" mode, and we have exiting children, we want to
|
||||
* only render these until they've all exited.
|
||||
*/
|
||||
if (mode === "wait" && exitingChildren.length) {
|
||||
nextChildren = exitingChildren;
|
||||
}
|
||||
setRenderedChildren(onlyElements(nextChildren));
|
||||
setDiffedChildren(presentChildren);
|
||||
/**
|
||||
* Early return to ensure once we've set state with the latest diffed
|
||||
* children, we can immediately re-render.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if (process.env.NODE_ENV !== "production" &&
|
||||
mode === "wait" &&
|
||||
renderedChildren.length > 1) {
|
||||
console.warn(`You're attempting to animate multiple children within AnimatePresence, but its mode is set to "wait". This will lead to odd visual behaviour.`);
|
||||
}
|
||||
/**
|
||||
* If we've been provided a forceRender function by the LayoutGroupContext,
|
||||
* we can use it to force a re-render amongst all surrounding components once
|
||||
* all components have finished animating out.
|
||||
*/
|
||||
const { forceRender } = useContext(LayoutGroupContext);
|
||||
return (jsx(Fragment, { children: renderedChildren.map((child) => {
|
||||
const key = getChildKey(child);
|
||||
const isPresent = presentChildren === renderedChildren ||
|
||||
presentKeys.includes(key);
|
||||
const onExit = () => {
|
||||
if (exitComplete.has(key)) {
|
||||
exitComplete.set(key, true);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
let isEveryExitComplete = true;
|
||||
exitComplete.forEach((isExitComplete) => {
|
||||
if (!isExitComplete)
|
||||
isEveryExitComplete = false;
|
||||
});
|
||||
if (isEveryExitComplete) {
|
||||
forceRender === null || forceRender === void 0 ? void 0 : forceRender();
|
||||
setRenderedChildren(pendingPresentChildren.current);
|
||||
onExitComplete && onExitComplete();
|
||||
}
|
||||
};
|
||||
return (jsx(PresenceChild, { isPresent: isPresent, initial: !isInitialRender.current || initial
|
||||
? undefined
|
||||
: false, custom: isPresent ? undefined : custom, presenceAffectsLayout: presenceAffectsLayout, mode: mode, onExitComplete: isPresent ? undefined : onExit, children: child }, key));
|
||||
}) }));
|
||||
};
|
||||
|
||||
export { AnimatePresence };
|
||||
66
node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.mjs
generated
vendored
Normal file
66
node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.mjs
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
import { useContext, useId, useEffect, useCallback } from 'react';
|
||||
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
||||
|
||||
/**
|
||||
* When a component is the child of `AnimatePresence`, it can use `usePresence`
|
||||
* to access information about whether it's still present in the React tree.
|
||||
*
|
||||
* ```jsx
|
||||
* import { usePresence } from "framer-motion"
|
||||
*
|
||||
* export const Component = () => {
|
||||
* const [isPresent, safeToRemove] = usePresence()
|
||||
*
|
||||
* useEffect(() => {
|
||||
* !isPresent && setTimeout(safeToRemove, 1000)
|
||||
* }, [isPresent])
|
||||
*
|
||||
* return <div />
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* If `isPresent` is `false`, it means that a component has been removed the tree, but
|
||||
* `AnimatePresence` won't really remove it until `safeToRemove` has been called.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function usePresence() {
|
||||
const context = useContext(PresenceContext);
|
||||
if (context === null)
|
||||
return [true, null];
|
||||
const { isPresent, onExitComplete, register } = context;
|
||||
// It's safe to call the following hooks conditionally (after an early return) because the context will always
|
||||
// either be null or non-null for the lifespan of the component.
|
||||
const id = useId();
|
||||
useEffect(() => register(id), []);
|
||||
const safeToRemove = useCallback(() => onExitComplete && onExitComplete(id), [id, onExitComplete]);
|
||||
return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
|
||||
}
|
||||
/**
|
||||
* Similar to `usePresence`, except `useIsPresent` simply returns whether or not the component is present.
|
||||
* There is no `safeToRemove` function.
|
||||
*
|
||||
* ```jsx
|
||||
* import { useIsPresent } from "framer-motion"
|
||||
*
|
||||
* export const Component = () => {
|
||||
* const isPresent = useIsPresent()
|
||||
*
|
||||
* useEffect(() => {
|
||||
* !isPresent && console.log("I've been removed!")
|
||||
* }, [isPresent])
|
||||
*
|
||||
* return <div />
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function useIsPresent() {
|
||||
return isPresent(useContext(PresenceContext));
|
||||
}
|
||||
function isPresent(context) {
|
||||
return context === null ? true : context.isPresent;
|
||||
}
|
||||
|
||||
export { isPresent, useIsPresent, usePresence };
|
||||
14
node_modules/framer-motion/dist/es/components/AnimatePresence/utils.mjs
generated
vendored
Normal file
14
node_modules/framer-motion/dist/es/components/AnimatePresence/utils.mjs
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import { Children, isValidElement } from 'react';
|
||||
|
||||
const getChildKey = (child) => child.key || "";
|
||||
function onlyElements(children) {
|
||||
const filtered = [];
|
||||
// We use forEach here instead of map as map mutates the component key by preprending `.$`
|
||||
Children.forEach(children, (child) => {
|
||||
if (isValidElement(child))
|
||||
filtered.push(child);
|
||||
});
|
||||
return filtered;
|
||||
}
|
||||
|
||||
export { getChildKey, onlyElements };
|
||||
15
node_modules/framer-motion/dist/es/components/AnimateSharedLayout.mjs
generated
vendored
Normal file
15
node_modules/framer-motion/dist/es/components/AnimateSharedLayout.mjs
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { invariant } from 'motion-utils';
|
||||
import * as React from 'react';
|
||||
import { useConstant } from '../utils/use-constant.mjs';
|
||||
import { LayoutGroup } from './LayoutGroup/index.mjs';
|
||||
|
||||
let id = 0;
|
||||
const AnimateSharedLayout = ({ children }) => {
|
||||
React.useEffect(() => {
|
||||
invariant(false, "AnimateSharedLayout is deprecated: https://www.framer.com/docs/guide-upgrade/##shared-layout-animations");
|
||||
}, []);
|
||||
return (jsx(LayoutGroup, { id: useConstant(() => `asl-${id++}`), children: children }));
|
||||
};
|
||||
|
||||
export { AnimateSharedLayout };
|
||||
32
node_modules/framer-motion/dist/es/components/LayoutGroup/index.mjs
generated
vendored
Normal file
32
node_modules/framer-motion/dist/es/components/LayoutGroup/index.mjs
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { useContext, useRef, useMemo } from 'react';
|
||||
import { LayoutGroupContext } from '../../context/LayoutGroupContext.mjs';
|
||||
import { DeprecatedLayoutGroupContext } from '../../context/DeprecatedLayoutGroupContext.mjs';
|
||||
import { useForceUpdate } from '../../utils/use-force-update.mjs';
|
||||
import { nodeGroup } from '../../projection/node/group.mjs';
|
||||
|
||||
const shouldInheritGroup = (inherit) => inherit === true;
|
||||
const shouldInheritId = (inherit) => shouldInheritGroup(inherit === true) || inherit === "id";
|
||||
const LayoutGroup = ({ children, id, inherit = true }) => {
|
||||
const layoutGroupContext = useContext(LayoutGroupContext);
|
||||
const deprecatedLayoutGroupContext = useContext(DeprecatedLayoutGroupContext);
|
||||
const [forceRender, key] = useForceUpdate();
|
||||
const context = useRef(null);
|
||||
const upstreamId = layoutGroupContext.id || deprecatedLayoutGroupContext;
|
||||
if (context.current === null) {
|
||||
if (shouldInheritId(inherit) && upstreamId) {
|
||||
id = id ? upstreamId + "-" + id : upstreamId;
|
||||
}
|
||||
context.current = {
|
||||
id,
|
||||
group: shouldInheritGroup(inherit)
|
||||
? layoutGroupContext.group || nodeGroup()
|
||||
: nodeGroup(),
|
||||
};
|
||||
}
|
||||
const memoizedContext = useMemo(() => ({ ...context.current, forceRender }), [key]);
|
||||
return (jsx(LayoutGroupContext.Provider, { value: memoizedContext, children: children }));
|
||||
};
|
||||
|
||||
export { LayoutGroup };
|
||||
68
node_modules/framer-motion/dist/es/components/LazyMotion/index.mjs
generated
vendored
Normal file
68
node_modules/framer-motion/dist/es/components/LazyMotion/index.mjs
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import { LazyContext } from '../../context/LazyContext.mjs';
|
||||
import { loadFeatures } from '../../motion/features/load-features.mjs';
|
||||
|
||||
/**
|
||||
* Used in conjunction with the `m` component to reduce bundle size.
|
||||
*
|
||||
* `m` is a version of the `motion` component that only loads functionality
|
||||
* critical for the initial render.
|
||||
*
|
||||
* `LazyMotion` can then be used to either synchronously or asynchronously
|
||||
* load animation and gesture support.
|
||||
*
|
||||
* ```jsx
|
||||
* // Synchronous loading
|
||||
* import { LazyMotion, m, domAnimation } from "framer-motion"
|
||||
*
|
||||
* function App() {
|
||||
* return (
|
||||
* <LazyMotion features={domAnimation}>
|
||||
* <m.div animate={{ scale: 2 }} />
|
||||
* </LazyMotion>
|
||||
* )
|
||||
* }
|
||||
*
|
||||
* // Asynchronous loading
|
||||
* import { LazyMotion, m } from "framer-motion"
|
||||
*
|
||||
* function App() {
|
||||
* return (
|
||||
* <LazyMotion features={() => import('./path/to/domAnimation')}>
|
||||
* <m.div animate={{ scale: 2 }} />
|
||||
* </LazyMotion>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function LazyMotion({ children, features, strict = false }) {
|
||||
const [, setIsLoaded] = useState(!isLazyBundle(features));
|
||||
const loadedRenderer = useRef(undefined);
|
||||
/**
|
||||
* If this is a synchronous load, load features immediately
|
||||
*/
|
||||
if (!isLazyBundle(features)) {
|
||||
const { renderer, ...loadedFeatures } = features;
|
||||
loadedRenderer.current = renderer;
|
||||
loadFeatures(loadedFeatures);
|
||||
}
|
||||
useEffect(() => {
|
||||
if (isLazyBundle(features)) {
|
||||
features().then(({ renderer, ...loadedFeatures }) => {
|
||||
loadFeatures(loadedFeatures);
|
||||
loadedRenderer.current = renderer;
|
||||
setIsLoaded(true);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
return (jsx(LazyContext.Provider, { value: { renderer: loadedRenderer.current, strict }, children: children }));
|
||||
}
|
||||
function isLazyBundle(features) {
|
||||
return typeof features === "function";
|
||||
}
|
||||
|
||||
export { LazyMotion };
|
||||
48
node_modules/framer-motion/dist/es/components/MotionConfig/index.mjs
generated
vendored
Normal file
48
node_modules/framer-motion/dist/es/components/MotionConfig/index.mjs
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { MotionConfigContext } from '../../context/MotionConfigContext.mjs';
|
||||
import { loadExternalIsValidProp } from '../../render/dom/utils/filter-props.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
|
||||
/**
|
||||
* `MotionConfig` is used to set configuration options for all children `motion` components.
|
||||
*
|
||||
* ```jsx
|
||||
* import { motion, MotionConfig } from "framer-motion"
|
||||
*
|
||||
* export function App() {
|
||||
* return (
|
||||
* <MotionConfig transition={{ type: "spring" }}>
|
||||
* <motion.div animate={{ x: 100 }} />
|
||||
* </MotionConfig>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function MotionConfig({ children, isValidProp, ...config }) {
|
||||
isValidProp && loadExternalIsValidProp(isValidProp);
|
||||
/**
|
||||
* Inherit props from any parent MotionConfig components
|
||||
*/
|
||||
config = { ...useContext(MotionConfigContext), ...config };
|
||||
/**
|
||||
* Don't allow isStatic to change between renders as it affects how many hooks
|
||||
* motion components fire.
|
||||
*/
|
||||
config.isStatic = useConstant(() => config.isStatic);
|
||||
/**
|
||||
* Creating a new config context object will re-render every `motion` component
|
||||
* every time it renders. So we only want to create a new one sparingly.
|
||||
*/
|
||||
const context = useMemo(() => config, [
|
||||
JSON.stringify(config.transition),
|
||||
config.transformPagePoint,
|
||||
config.reducedMotion,
|
||||
]);
|
||||
return (jsx(MotionConfigContext.Provider, { value: context, children: children }));
|
||||
}
|
||||
|
||||
export { MotionConfig };
|
||||
53
node_modules/framer-motion/dist/es/components/Reorder/Group.mjs
generated
vendored
Normal file
53
node_modules/framer-motion/dist/es/components/Reorder/Group.mjs
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { forwardRef, useRef, useEffect } from 'react';
|
||||
import { ReorderContext } from '../../context/ReorderContext.mjs';
|
||||
import { motion } from '../../render/components/motion/proxy.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { checkReorder } from './utils/check-reorder.mjs';
|
||||
|
||||
function ReorderGroupComponent({ children, as = "ul", axis = "y", onReorder, values, ...props }, externalRef) {
|
||||
const Component = useConstant(() => motion[as]);
|
||||
const order = [];
|
||||
const isReordering = useRef(false);
|
||||
invariant(Boolean(values), "Reorder.Group must be provided a values prop");
|
||||
const context = {
|
||||
axis,
|
||||
registerItem: (value, layout) => {
|
||||
// If the entry was already added, update it rather than adding it again
|
||||
const idx = order.findIndex((entry) => value === entry.value);
|
||||
if (idx !== -1) {
|
||||
order[idx].layout = layout[axis];
|
||||
}
|
||||
else {
|
||||
order.push({ value: value, layout: layout[axis] });
|
||||
}
|
||||
order.sort(compareMin);
|
||||
},
|
||||
updateOrder: (item, offset, velocity) => {
|
||||
if (isReordering.current)
|
||||
return;
|
||||
const newOrder = checkReorder(order, item, offset, velocity);
|
||||
if (order !== newOrder) {
|
||||
isReordering.current = true;
|
||||
onReorder(newOrder
|
||||
.map(getValue)
|
||||
.filter((value) => values.indexOf(value) !== -1));
|
||||
}
|
||||
},
|
||||
};
|
||||
useEffect(() => {
|
||||
isReordering.current = false;
|
||||
});
|
||||
return (jsx(Component, { ...props, ref: externalRef, ignoreStrict: true, children: jsx(ReorderContext.Provider, { value: context, children: children }) }));
|
||||
}
|
||||
const ReorderGroup = /*@__PURE__*/ forwardRef(ReorderGroupComponent);
|
||||
function getValue(item) {
|
||||
return item.value;
|
||||
}
|
||||
function compareMin(a, b) {
|
||||
return a.layout.min - b.layout.min;
|
||||
}
|
||||
|
||||
export { ReorderGroup, ReorderGroupComponent };
|
||||
34
node_modules/framer-motion/dist/es/components/Reorder/Item.mjs
generated
vendored
Normal file
34
node_modules/framer-motion/dist/es/components/Reorder/Item.mjs
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { forwardRef, useContext } from 'react';
|
||||
import { ReorderContext } from '../../context/ReorderContext.mjs';
|
||||
import { motion } from '../../render/components/motion/proxy.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useMotionValue } from '../../value/use-motion-value.mjs';
|
||||
import { useTransform } from '../../value/use-transform.mjs';
|
||||
import { isMotionValue } from '../../value/utils/is-motion-value.mjs';
|
||||
|
||||
function useDefaultMotionValue(value, defaultValue = 0) {
|
||||
return isMotionValue(value) ? value : useMotionValue(defaultValue);
|
||||
}
|
||||
function ReorderItemComponent({ children, style = {}, value, as = "li", onDrag, layout = true, ...props }, externalRef) {
|
||||
const Component = useConstant(() => motion[as]);
|
||||
const context = useContext(ReorderContext);
|
||||
const point = {
|
||||
x: useDefaultMotionValue(style.x),
|
||||
y: useDefaultMotionValue(style.y),
|
||||
};
|
||||
const zIndex = useTransform([point.x, point.y], ([latestX, latestY]) => latestX || latestY ? 1 : "unset");
|
||||
invariant(Boolean(context), "Reorder.Item must be a child of Reorder.Group");
|
||||
const { axis, registerItem, updateOrder } = context;
|
||||
return (jsx(Component, { drag: axis, ...props, dragSnapToOrigin: true, style: { ...style, x: point.x, y: point.y, zIndex }, layout: layout, onDrag: (event, gesturePoint) => {
|
||||
const { velocity } = gesturePoint;
|
||||
velocity[axis] &&
|
||||
updateOrder(value, point[axis].get(), velocity[axis]);
|
||||
onDrag && onDrag(event, gesturePoint);
|
||||
}, onLayoutMeasure: (measured) => registerItem(value, measured), ref: externalRef, ignoreStrict: true, children: children }));
|
||||
}
|
||||
const ReorderItem = /*@__PURE__*/ forwardRef(ReorderItemComponent);
|
||||
|
||||
export { ReorderItem, ReorderItemComponent };
|
||||
2
node_modules/framer-motion/dist/es/components/Reorder/namespace.mjs
generated
vendored
Normal file
2
node_modules/framer-motion/dist/es/components/Reorder/namespace.mjs
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export { ReorderGroup as Group } from './Group.mjs';
|
||||
export { ReorderItem as Item } from './Item.mjs';
|
||||
24
node_modules/framer-motion/dist/es/components/Reorder/utils/check-reorder.mjs
generated
vendored
Normal file
24
node_modules/framer-motion/dist/es/components/Reorder/utils/check-reorder.mjs
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
import { moveItem } from '../../../utils/array.mjs';
|
||||
import { mixNumber } from '../../../utils/mix/number.mjs';
|
||||
|
||||
function checkReorder(order, value, offset, velocity) {
|
||||
if (!velocity)
|
||||
return order;
|
||||
const index = order.findIndex((item) => item.value === value);
|
||||
if (index === -1)
|
||||
return order;
|
||||
const nextOffset = velocity > 0 ? 1 : -1;
|
||||
const nextItem = order[index + nextOffset];
|
||||
if (!nextItem)
|
||||
return order;
|
||||
const item = order[index];
|
||||
const nextLayout = nextItem.layout;
|
||||
const nextItemCenter = mixNumber(nextLayout.min, nextLayout.max, 0.5);
|
||||
if ((nextOffset === 1 && item.layout.max + offset > nextItemCenter) ||
|
||||
(nextOffset === -1 && item.layout.min + offset < nextItemCenter)) {
|
||||
return moveItem(order, index, index + nextOffset);
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
export { checkReorder };
|
||||
10
node_modules/framer-motion/dist/es/context/DeprecatedLayoutGroupContext.mjs
generated
vendored
Normal file
10
node_modules/framer-motion/dist/es/context/DeprecatedLayoutGroupContext.mjs
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
/**
|
||||
* Note: Still used by components generated by old versions of Framer
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
const DeprecatedLayoutGroupContext = createContext(null);
|
||||
|
||||
export { DeprecatedLayoutGroupContext };
|
||||
6
node_modules/framer-motion/dist/es/context/LayoutGroupContext.mjs
generated
vendored
Normal file
6
node_modules/framer-motion/dist/es/context/LayoutGroupContext.mjs
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
const LayoutGroupContext = createContext({});
|
||||
|
||||
export { LayoutGroupContext };
|
||||
6
node_modules/framer-motion/dist/es/context/LazyContext.mjs
generated
vendored
Normal file
6
node_modules/framer-motion/dist/es/context/LazyContext.mjs
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
const LazyContext = createContext({ strict: false });
|
||||
|
||||
export { LazyContext };
|
||||
13
node_modules/framer-motion/dist/es/context/MotionConfigContext.mjs
generated
vendored
Normal file
13
node_modules/framer-motion/dist/es/context/MotionConfigContext.mjs
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
const MotionConfigContext = createContext({
|
||||
transformPagePoint: (p) => p,
|
||||
isStatic: false,
|
||||
reducedMotion: "never",
|
||||
});
|
||||
|
||||
export { MotionConfigContext };
|
||||
13
node_modules/framer-motion/dist/es/context/MotionContext/create.mjs
generated
vendored
Normal file
13
node_modules/framer-motion/dist/es/context/MotionContext/create.mjs
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { MotionContext } from './index.mjs';
|
||||
import { getCurrentTreeVariants } from './utils.mjs';
|
||||
|
||||
function useCreateMotionContext(props) {
|
||||
const { initial, animate } = getCurrentTreeVariants(props, useContext(MotionContext));
|
||||
return useMemo(() => ({ initial, animate }), [variantLabelsAsDependency(initial), variantLabelsAsDependency(animate)]);
|
||||
}
|
||||
function variantLabelsAsDependency(prop) {
|
||||
return Array.isArray(prop) ? prop.join(" ") : prop;
|
||||
}
|
||||
|
||||
export { useCreateMotionContext };
|
||||
6
node_modules/framer-motion/dist/es/context/MotionContext/index.mjs
generated
vendored
Normal file
6
node_modules/framer-motion/dist/es/context/MotionContext/index.mjs
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
const MotionContext = createContext({});
|
||||
|
||||
export { MotionContext };
|
||||
17
node_modules/framer-motion/dist/es/context/MotionContext/utils.mjs
generated
vendored
Normal file
17
node_modules/framer-motion/dist/es/context/MotionContext/utils.mjs
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
import { isVariantLabel } from '../../render/utils/is-variant-label.mjs';
|
||||
import { isControllingVariants } from '../../render/utils/is-controlling-variants.mjs';
|
||||
|
||||
function getCurrentTreeVariants(props, context) {
|
||||
if (isControllingVariants(props)) {
|
||||
const { initial, animate } = props;
|
||||
return {
|
||||
initial: initial === false || isVariantLabel(initial)
|
||||
? initial
|
||||
: undefined,
|
||||
animate: isVariantLabel(animate) ? animate : undefined,
|
||||
};
|
||||
}
|
||||
return props.inherit !== false ? context : {};
|
||||
}
|
||||
|
||||
export { getCurrentTreeVariants };
|
||||
9
node_modules/framer-motion/dist/es/context/PresenceContext.mjs
generated
vendored
Normal file
9
node_modules/framer-motion/dist/es/context/PresenceContext.mjs
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
const PresenceContext = createContext(null);
|
||||
|
||||
export { PresenceContext };
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user