Mission Control Dashboard - Initial implementation
This commit is contained in:
39
node_modules/framer-motion/dist/es/animation/optimized-appear/handoff.mjs
generated
vendored
Normal file
39
node_modules/framer-motion/dist/es/animation/optimized-appear/handoff.mjs
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { appearAnimationStore } from './store.mjs';
|
||||
import { appearStoreId } from './store-id.mjs';
|
||||
|
||||
function handoffOptimizedAppearAnimation(elementId, valueName, frame) {
|
||||
const storeId = appearStoreId(elementId, valueName);
|
||||
const optimisedAnimation = appearAnimationStore.get(storeId);
|
||||
if (!optimisedAnimation) {
|
||||
return null;
|
||||
}
|
||||
const { animation, startTime } = optimisedAnimation;
|
||||
function cancelAnimation() {
|
||||
window.MotionCancelOptimisedAnimation?.(elementId, valueName, frame);
|
||||
}
|
||||
/**
|
||||
* We can cancel the animation once it's finished now that we've synced
|
||||
* with Motion.
|
||||
*
|
||||
* Prefer onfinish over finished as onfinish is backwards compatible with
|
||||
* older browsers.
|
||||
*/
|
||||
animation.onfinish = cancelAnimation;
|
||||
if (startTime === null || window.MotionHandoffIsComplete?.(elementId)) {
|
||||
/**
|
||||
* If the startTime is null, this animation is the Paint Ready detection animation
|
||||
* and we can cancel it immediately without handoff.
|
||||
*
|
||||
* Or if we've already handed off the animation then we're now interrupting it.
|
||||
* In which case we need to cancel it.
|
||||
*/
|
||||
cancelAnimation();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return startTime;
|
||||
}
|
||||
}
|
||||
|
||||
export { handoffOptimizedAppearAnimation };
|
||||
//# sourceMappingURL=handoff.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/animation/optimized-appear/handoff.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/animation/optimized-appear/handoff.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"handoff.mjs","sources":["../../../../src/animation/optimized-appear/handoff.ts"],"sourcesContent":["import type { Batcher } from \"motion-dom\"\nimport { appearAnimationStore } from \"./store\"\nimport { appearStoreId } from \"./store-id\"\n\nexport function handoffOptimizedAppearAnimation(\n elementId: string,\n valueName: string,\n frame: Batcher\n): number | null {\n const storeId = appearStoreId(elementId, valueName)\n const optimisedAnimation = appearAnimationStore.get(storeId)\n\n if (!optimisedAnimation) {\n return null\n }\n\n const { animation, startTime } = optimisedAnimation\n\n function cancelAnimation() {\n window.MotionCancelOptimisedAnimation?.(elementId, valueName, frame)\n }\n\n /**\n * We can cancel the animation once it's finished now that we've synced\n * with Motion.\n *\n * Prefer onfinish over finished as onfinish is backwards compatible with\n * older browsers.\n */\n animation.onfinish = cancelAnimation\n\n if (startTime === null || window.MotionHandoffIsComplete?.(elementId)) {\n /**\n * If the startTime is null, this animation is the Paint Ready detection animation\n * and we can cancel it immediately without handoff.\n *\n * Or if we've already handed off the animation then we're now interrupting it.\n * In which case we need to cancel it.\n */\n cancelAnimation()\n return null\n } else {\n return startTime\n }\n}\n"],"names":[],"mappings":";;;SAIgB,+BAA+B,CAC3C,SAAiB,EACjB,SAAiB,EACjB,KAAc,EAAA;IAEd,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC;IACnD,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC;IAE5D,IAAI,CAAC,kBAAkB,EAAE;AACrB,QAAA,OAAO,IAAI;IACf;AAEA,IAAA,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,kBAAkB;AAEnD,IAAA,SAAS,eAAe,GAAA;QACpB,MAAM,CAAC,8BAA8B,GAAG,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC;IACxE;AAEA;;;;;;AAMG;AACH,IAAA,SAAS,CAAC,QAAQ,GAAG,eAAe;AAEpC,IAAA,IAAI,SAAS,KAAK,IAAI,IAAI,MAAM,CAAC,uBAAuB,GAAG,SAAS,CAAC,EAAE;AACnE;;;;;;AAMG;AACH,QAAA,eAAe,EAAE;AACjB,QAAA,OAAO,IAAI;IACf;SAAO;AACH,QAAA,OAAO,SAAS;IACpB;AACJ;;;;"}
|
||||
170
node_modules/framer-motion/dist/es/animation/optimized-appear/start.mjs
generated
vendored
Normal file
170
node_modules/framer-motion/dist/es/animation/optimized-appear/start.mjs
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
import { optimizedAppearDataId, startWaapiAnimation, getOptimisedAppearId } from 'motion-dom';
|
||||
import { noop } from 'motion-utils';
|
||||
import { handoffOptimizedAppearAnimation } from './handoff.mjs';
|
||||
import { appearAnimationStore, appearComplete } from './store.mjs';
|
||||
import { appearStoreId } from './store-id.mjs';
|
||||
|
||||
/**
|
||||
* A single time to use across all animations to manually set startTime
|
||||
* and ensure they're all in sync.
|
||||
*/
|
||||
let startFrameTime;
|
||||
/**
|
||||
* A dummy animation to detect when Chrome is ready to start
|
||||
* painting the page and hold off from triggering the real animation
|
||||
* until then. We only need one animation to detect paint ready.
|
||||
*
|
||||
* https://bugs.chromium.org/p/chromium/issues/detail?id=1406850
|
||||
*/
|
||||
let readyAnimation;
|
||||
/**
|
||||
* Keep track of animations that were suspended vs cancelled so we
|
||||
* can easily resume them when we're done measuring layout.
|
||||
*/
|
||||
const suspendedAnimations = new Set();
|
||||
function resumeSuspendedAnimations() {
|
||||
suspendedAnimations.forEach((data) => {
|
||||
data.animation.play();
|
||||
data.animation.startTime = data.startTime;
|
||||
});
|
||||
suspendedAnimations.clear();
|
||||
}
|
||||
function startOptimizedAppearAnimation(element, name, keyframes, options, onReady) {
|
||||
// Prevent optimised appear animations if Motion has already started animating.
|
||||
if (window.MotionIsMounted) {
|
||||
return;
|
||||
}
|
||||
const id = element.dataset[optimizedAppearDataId];
|
||||
if (!id)
|
||||
return;
|
||||
window.MotionHandoffAnimation = handoffOptimizedAppearAnimation;
|
||||
const storeId = appearStoreId(id, name);
|
||||
if (!readyAnimation) {
|
||||
readyAnimation = startWaapiAnimation(element, name, [keyframes[0], keyframes[0]],
|
||||
/**
|
||||
* 10 secs is basically just a super-safe duration to give Chrome
|
||||
* long enough to get the animation ready.
|
||||
*/
|
||||
{ duration: 10000, ease: "linear" });
|
||||
appearAnimationStore.set(storeId, {
|
||||
animation: readyAnimation,
|
||||
startTime: null,
|
||||
});
|
||||
/**
|
||||
* If there's no readyAnimation then there's been no instantiation
|
||||
* of handoff animations.
|
||||
*/
|
||||
window.MotionHandoffAnimation = handoffOptimizedAppearAnimation;
|
||||
window.MotionHasOptimisedAnimation = (elementId, valueName) => {
|
||||
if (!elementId)
|
||||
return false;
|
||||
/**
|
||||
* Keep a map of elementIds that have started animating. We check
|
||||
* via ID instead of Element because of hydration errors and
|
||||
* pre-hydration checks. We also actively record IDs as they start
|
||||
* animating rather than simply checking for data-appear-id as
|
||||
* this attrbute might be present but not lead to an animation, for
|
||||
* instance if the element's appear animation is on a different
|
||||
* breakpoint.
|
||||
*/
|
||||
if (!valueName) {
|
||||
return appearComplete.has(elementId);
|
||||
}
|
||||
const animationId = appearStoreId(elementId, valueName);
|
||||
return Boolean(appearAnimationStore.get(animationId));
|
||||
};
|
||||
window.MotionHandoffMarkAsComplete = (elementId) => {
|
||||
if (appearComplete.has(elementId)) {
|
||||
appearComplete.set(elementId, true);
|
||||
}
|
||||
};
|
||||
window.MotionHandoffIsComplete = (elementId) => {
|
||||
return appearComplete.get(elementId) === true;
|
||||
};
|
||||
/**
|
||||
* We only need to cancel transform animations as
|
||||
* they're the ones that will interfere with the
|
||||
* layout animation measurements.
|
||||
*/
|
||||
window.MotionCancelOptimisedAnimation = (elementId, valueName, frame, canResume) => {
|
||||
const animationId = appearStoreId(elementId, valueName);
|
||||
const data = appearAnimationStore.get(animationId);
|
||||
if (!data)
|
||||
return;
|
||||
if (frame && canResume === undefined) {
|
||||
/**
|
||||
* Wait until the end of the subsequent frame to cancel the animation
|
||||
* to ensure we don't remove the animation before the main thread has
|
||||
* had a chance to resolve keyframes and render.
|
||||
*/
|
||||
frame.postRender(() => {
|
||||
frame.postRender(() => {
|
||||
data.animation.cancel();
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
data.animation.cancel();
|
||||
}
|
||||
if (frame && canResume) {
|
||||
suspendedAnimations.add(data);
|
||||
frame.render(resumeSuspendedAnimations);
|
||||
}
|
||||
else {
|
||||
appearAnimationStore.delete(animationId);
|
||||
/**
|
||||
* If there are no more animations left, we can remove the cancel function.
|
||||
* This will let us know when we can stop checking for conflicting layout animations.
|
||||
*/
|
||||
if (!appearAnimationStore.size) {
|
||||
window.MotionCancelOptimisedAnimation = undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
window.MotionCheckAppearSync = (visualElement, valueName, value) => {
|
||||
const appearId = getOptimisedAppearId(visualElement);
|
||||
if (!appearId)
|
||||
return;
|
||||
const valueIsOptimised = window.MotionHasOptimisedAnimation?.(appearId, valueName);
|
||||
const externalAnimationValue = visualElement.props.values?.[valueName];
|
||||
if (!valueIsOptimised || !externalAnimationValue)
|
||||
return;
|
||||
const removeSyncCheck = value.on("change", (latestValue) => {
|
||||
if (externalAnimationValue.get() !== latestValue) {
|
||||
window.MotionCancelOptimisedAnimation?.(appearId, valueName);
|
||||
removeSyncCheck();
|
||||
}
|
||||
});
|
||||
return removeSyncCheck;
|
||||
};
|
||||
}
|
||||
const startAnimation = () => {
|
||||
readyAnimation.cancel();
|
||||
const appearAnimation = startWaapiAnimation(element, name, keyframes, options);
|
||||
/**
|
||||
* Record the time of the first started animation. We call performance.now() once
|
||||
* here and once in handoff to ensure we're getting
|
||||
* close to a frame-locked time. This keeps all animations in sync.
|
||||
*/
|
||||
if (startFrameTime === undefined) {
|
||||
startFrameTime = performance.now();
|
||||
}
|
||||
appearAnimation.startTime = startFrameTime;
|
||||
appearAnimationStore.set(storeId, {
|
||||
animation: appearAnimation,
|
||||
startTime: startFrameTime,
|
||||
});
|
||||
if (onReady)
|
||||
onReady(appearAnimation);
|
||||
};
|
||||
appearComplete.set(id, false);
|
||||
if (readyAnimation.ready) {
|
||||
readyAnimation.ready.then(startAnimation).catch(noop);
|
||||
}
|
||||
else {
|
||||
startAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
export { startOptimizedAppearAnimation };
|
||||
//# sourceMappingURL=start.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/animation/optimized-appear/start.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/animation/optimized-appear/start.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
9
node_modules/framer-motion/dist/es/animation/optimized-appear/store-id.mjs
generated
vendored
Normal file
9
node_modules/framer-motion/dist/es/animation/optimized-appear/store-id.mjs
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import { transformProps } from 'motion-dom';
|
||||
|
||||
const appearStoreId = (elementId, valueName) => {
|
||||
const key = transformProps.has(valueName) ? "transform" : valueName;
|
||||
return `${elementId}: ${key}`;
|
||||
};
|
||||
|
||||
export { appearStoreId };
|
||||
//# sourceMappingURL=store-id.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/animation/optimized-appear/store-id.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/animation/optimized-appear/store-id.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"store-id.mjs","sources":["../../../../src/animation/optimized-appear/store-id.ts"],"sourcesContent":["import { transformProps } from \"motion-dom\"\n\nexport const appearStoreId = (elementId: string, valueName: string) => {\n const key = transformProps.has(valueName) ? \"transform\" : valueName\n\n return `${elementId}: ${key}`\n}\n"],"names":[],"mappings":";;MAEa,aAAa,GAAG,CAAC,SAAiB,EAAE,SAAiB,KAAI;AAClE,IAAA,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,WAAW,GAAG,SAAS;AAEnE,IAAA,OAAO,CAAA,EAAG,SAAS,CAAA,EAAA,EAAK,GAAG,EAAE;AACjC;;;;"}
|
||||
5
node_modules/framer-motion/dist/es/animation/optimized-appear/store.mjs
generated
vendored
Normal file
5
node_modules/framer-motion/dist/es/animation/optimized-appear/store.mjs
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const appearAnimationStore = new Map();
|
||||
const appearComplete = new Map();
|
||||
|
||||
export { appearAnimationStore, appearComplete };
|
||||
//# sourceMappingURL=store.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/animation/optimized-appear/store.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/animation/optimized-appear/store.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"store.mjs","sources":["../../../../src/animation/optimized-appear/store.ts"],"sourcesContent":["export interface AppearStoreEntry {\n animation: Animation\n startTime: number | null\n}\n\nexport type AppearElementId = string\n\nexport type IsComplete = boolean\n\nexport const appearAnimationStore = new Map<AppearElementId, AppearStoreEntry>()\n\nexport const appearComplete = new Map<AppearElementId, IsComplete>()\n"],"names":[],"mappings":"AASO,MAAM,oBAAoB,GAAG,IAAI,GAAG;AAEpC,MAAM,cAAc,GAAG,IAAI,GAAG;;;;"}
|
||||
Reference in New Issue
Block a user