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,74 @@
import { buildTransform } from './build-transform.mjs';
import { isCSSVariableName } from '../../dom/utils/is-css-variable.mjs';
import { transformProps } from './transform.mjs';
import { getValueAsType } from '../../dom/value-types/get-as-type.mjs';
import { numberValueTypes } from '../../dom/value-types/number.mjs';
function buildHTMLStyles(state, latestValues, options, transformTemplate) {
const { style, vars, transform, transformOrigin } = state;
// Track whether we encounter any transform or transformOrigin values.
let hasTransform = false;
let hasTransformOrigin = false;
// Does the calculated transform essentially equal "none"?
let transformIsNone = true;
/**
* Loop over all our latest animated values and decide whether to handle them
* as a style or CSS variable.
*
* Transforms and transform origins are kept seperately for further processing.
*/
for (const key in latestValues) {
const value = latestValues[key];
/**
* If this is a CSS variable we don't do any further processing.
*/
if (isCSSVariableName(key)) {
vars[key] = value;
continue;
}
// Convert the value to its default value type, ie 0 -> "0px"
const valueType = numberValueTypes[key];
const valueAsType = getValueAsType(value, valueType);
if (transformProps.has(key)) {
// If this is a transform, flag to enable further transform processing
hasTransform = true;
transform[key] = valueAsType;
// If we already know we have a non-default transform, early return
if (!transformIsNone)
continue;
// Otherwise check to see if this is a default transform
if (value !== (valueType.default || 0))
transformIsNone = false;
}
else if (key.startsWith("origin")) {
// If this is a transform origin, flag and enable further transform-origin processing
hasTransformOrigin = true;
transformOrigin[key] = valueAsType;
}
else {
style[key] = valueAsType;
}
}
if (!latestValues.transform) {
if (hasTransform || transformTemplate) {
style.transform = buildTransform(state.transform, options, transformIsNone, transformTemplate);
}
else if (style.transform) {
/**
* If we have previously created a transform but currently don't have any,
* reset transform style to none.
*/
style.transform = "none";
}
}
/**
* Build a transformOrigin style. Uses the same defaults as the browser for
* undefined origins.
*/
if (hasTransformOrigin) {
const { originX = "50%", originY = "50%", originZ = 0, } = transformOrigin;
style.transformOrigin = `${originX} ${originY} ${originZ}`;
}
}
export { buildHTMLStyles };

View File

@@ -0,0 +1,45 @@
import { transformPropOrder } from './transform.mjs';
const translateAlias = {
x: "translateX",
y: "translateY",
z: "translateZ",
transformPerspective: "perspective",
};
const numTransforms = transformPropOrder.length;
/**
* Build a CSS transform style from individual x/y/scale etc properties.
*
* This outputs with a default order of transforms/scales/rotations, this can be customised by
* providing a transformTemplate function.
*/
function buildTransform(transform, { enableHardwareAcceleration = true, allowTransformNone = true, }, transformIsDefault, transformTemplate) {
// The transform string we're going to build into.
let transformString = "";
/**
* Loop over all possible transforms in order, adding the ones that
* are present to the transform string.
*/
for (let i = 0; i < numTransforms; i++) {
const key = transformPropOrder[i];
if (transform[key] !== undefined) {
const transformName = translateAlias[key] || key;
transformString += `${transformName}(${transform[key]}) `;
}
}
if (enableHardwareAcceleration && !transform.z) {
transformString += "translateZ(0)";
}
transformString = transformString.trim();
// If we have a custom `transform` template, pass our transform values and
// generated transformString to that before returning
if (transformTemplate) {
transformString = transformTemplate(transform, transformIsDefault ? "" : transformString);
}
else if (allowTransformNone && transformIsDefault) {
transformString = "none";
}
return transformString;
}
export { buildTransform };

View File

@@ -0,0 +1,8 @@
const createHtmlRenderState = () => ({
style: {},
transform: {},
transformOrigin: {},
vars: {},
});
export { createHtmlRenderState };

View File

@@ -0,0 +1,9 @@
function renderHTML(element, { style, vars }, styleProp, projection) {
Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
// Loop over any CSS variables and assign those.
for (const key in vars) {
element.style.setProperty(key, vars[key]);
}
}
export { renderHTML };

View File

@@ -0,0 +1,17 @@
import { isForcedMotionValue } from '../../../motion/utils/is-forced-motion-value.mjs';
import { isMotionValue } from '../../../value/utils/is-motion-value.mjs';
function scrapeMotionValuesFromProps(props, prevProps) {
const { style } = props;
const newValues = {};
for (const key in style) {
if (isMotionValue(style[key]) ||
(prevProps.style && isMotionValue(prevProps.style[key])) ||
isForcedMotionValue(key, props)) {
newValues[key] = style[key];
}
}
return newValues;
}
export { scrapeMotionValuesFromProps };

View File

@@ -0,0 +1,28 @@
/**
* Generate a list of every possible transform key.
*/
const transformPropOrder = [
"transformPerspective",
"x",
"y",
"z",
"translateX",
"translateY",
"translateZ",
"scale",
"scaleX",
"scaleY",
"rotate",
"rotateX",
"rotateY",
"rotateZ",
"skew",
"skewX",
"skewY",
];
/**
* A quick lookup for transform props.
*/
const transformProps = new Set(transformPropOrder);
export { transformPropOrder, transformProps };