This commit is contained in:
Iliyan Angelov
2025-09-14 23:24:25 +03:00
commit c67067a2a4
71311 changed files with 6800714 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
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';
function createVisualElement(element) {
const options = {
presenceContext: null,
props: {},
visualState: {
renderState: {
transform: {},
transformOrigin: {},
style: {},
vars: {},
attrs: {},
},
latestValues: {},
},
};
const node = isSVGElement(element)
? new SVGVisualElement(options, {
enableHardwareAcceleration: false,
})
: new HTMLVisualElement(options, {
enableHardwareAcceleration: true,
});
node.mount(element);
visualElementStore.set(element, node);
}
export { createVisualElement };

View 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 };

View 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 = (key, value) => {
// If the list of keys tat might be non-animatable grows, replace with Set
if (key === "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 };

View File

@@ -0,0 +1,7 @@
function isAnimationControls(v) {
return (v !== null &&
typeof v === "object" &&
typeof v.start === "function");
}
export { isAnimationControls };

View File

@@ -0,0 +1,5 @@
function isDOMKeyframes(keyframes) {
return typeof keyframes === "object" && !Array.isArray(keyframes);
}
export { isDOMKeyframes };

View File

@@ -0,0 +1,5 @@
const isKeyframesTarget = (v) => {
return Array.isArray(v);
};
export { isKeyframesTarget };

View File

@@ -0,0 +1,12 @@
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);
}
}
export { isNone };

View File

@@ -0,0 +1,45 @@
import { getAnimatableNone } from '../../render/dom/value-types/animatable-none.mjs';
import { isAnimatable } from './is-animatable.mjs';
import { isNone } from './is-none.mjs';
function getKeyframes(value, valueName, target, transition) {
const isTargetAnimatable = isAnimatable(valueName, target);
let keyframes;
if (Array.isArray(target)) {
keyframes = [...target];
}
else {
keyframes = [null, target];
}
const defaultOrigin = transition.from !== undefined ? transition.from : value.get();
let animatableTemplateValue = undefined;
const noneKeyframeIndexes = [];
for (let i = 0; i < keyframes.length; i++) {
/**
* Fill null/wildcard keyframes
*/
if (keyframes[i] === null) {
keyframes[i] = i === 0 ? defaultOrigin : keyframes[i - 1];
}
if (isNone(keyframes[i])) {
noneKeyframeIndexes.push(i);
}
// TODO: Clean this conditional, it works for now
if (typeof keyframes[i] === "string" &&
keyframes[i] !== "none" &&
keyframes[i] !== "0") {
animatableTemplateValue = keyframes[i];
}
}
if (isTargetAnimatable &&
noneKeyframeIndexes.length &&
animatableTemplateValue) {
for (let i = 0; i < noneKeyframeIndexes.length; i++) {
const index = noneKeyframeIndexes[i];
keyframes[index] = getAnimatableNone(valueName, animatableTemplateValue);
}
}
return keyframes;
}
export { getKeyframes };

View 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 };

View File

@@ -0,0 +1,13 @@
/**
* 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;
}
function getValueTransition(transition, key) {
return transition[key] || transition["default"] || transition;
}
export { getValueTransition, isTransitionDefined };