svelte-motion
Version:
Svelte animation library based on the React library framer-motion.
110 lines (107 loc) • 4.72 kB
JavaScript
/**
based on framer-motion@4.0.3,
Copyright (c) 2018 Framer B.V.
*/
import { valueScaleCorrection } from '../../dom/projection/scale-correction.js';
import { buildTransform, buildTransformOrigin } from './build-transform.js';
import { isCSSVariable } from '../../dom/utils/is-css-variable.js';
import { isTransformProp, isTransformOriginProp } from './transform.js';
import { getValueAsType } from '../../dom/value-types/get-as-type.js';
import { numberValueTypes } from '../../dom/value-types/number.js';
function buildHTMLStyles(state, latestValues, projection, layoutState, options, transformTemplate, buildProjectionTransform, buildProjectionTransformOrigin) {
var _a;
var style = state.style, vars = state.vars, transform = state.transform, transformKeys = state.transformKeys, transformOrigin = state.transformOrigin;
// Empty the transformKeys array. As we're throwing out refs to its items
// this might not be as cheap as suspected. Maybe using the array as a buffer
// with a manual incrementation would be better.
transformKeys.length = 0;
// Track whether we encounter any transform or transformOrigin values.
var hasTransform = false;
var hasTransformOrigin = false;
// Does the calculated transform essentially equal "none"?
var 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 (var key in latestValues) {
var value = latestValues[key];
/**
* If this is a CSS variable we don't do any further processing.
*/
if (isCSSVariable(key)) {
vars[key] = value;
continue;
}
// Convert the value to its default value type, ie 0 -> "0px"
var valueType = numberValueTypes[key];
var valueAsType = getValueAsType(value, valueType);
if (isTransformProp(key)) {
// If this is a transform, flag to enable further transform processing
hasTransform = true;
transform[key] = valueAsType;
transformKeys.push(key);
// 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 !== ((_a = valueType.default) !== null && _a !== void 0 ? _a : 0))
transformIsNone = false;
}
else if (isTransformOriginProp(key)) {
transformOrigin[key] = valueAsType;
// If this is a transform origin, flag and enable further transform-origin processing
hasTransformOrigin = true;
}
else {
/**
* If layout projection is on, and we need to perform scale correction for this
* value type, perform it.
*/
if (layoutState &&
projection &&
layoutState.isHydrated &&
valueScaleCorrection[key]) {
var correctedValue = valueScaleCorrection[key].process(value, layoutState, projection);
/**
* Scale-correctable values can define a number of other values to break
* down into. For instance borderRadius needs applying to borderBottomLeftRadius etc
*/
var applyTo = valueScaleCorrection[key].applyTo;
if (applyTo) {
var num = applyTo.length;
for (var i = 0; i < num; i++) {
style[applyTo[i]] = correctedValue;
}
}
else {
style[key] = correctedValue;
}
}
else {
style[key] = valueAsType;
}
}
}
if (layoutState &&
projection &&
buildProjectionTransform &&
buildProjectionTransformOrigin) {
style.transform = buildProjectionTransform(layoutState.deltaFinal, layoutState.treeScale, hasTransform ? transform : undefined);
if (transformTemplate) {
style.transform = transformTemplate(transform, style.transform);
}
style.transformOrigin = buildProjectionTransformOrigin(layoutState);
}
else {
if (hasTransform) {
style.transform = buildTransform(state, options, transformIsNone, transformTemplate);
}
if (hasTransformOrigin) {
style.transformOrigin = buildTransformOrigin(transformOrigin);
}
}
}
export { buildHTMLStyles };