UNPKG

framer-motion

Version:

A simple and powerful JavaScript animation library

95 lines (92 loc) 3.44 kB
import { mixNumber as mixNumber$1 } from './number.mjs'; import { mixColor } from './color.mjs'; import { pipe } from '../pipe.mjs'; import { warning } from 'motion-utils'; import { color } from '../../value/types/color/index.mjs'; import { complex, analyseComplexValue } from '../../value/types/complex/index.mjs'; import { isCSSVariableToken } from '../../render/dom/utils/is-css-variable.mjs'; import { invisibleValues, mixVisibility } from './visibility.mjs'; import { mixImmediate } from './immediate.mjs'; function mixNumber(a, b) { return (p) => mixNumber$1(a, b, p); } function getMixer(a) { if (typeof a === "number") { return mixNumber; } else if (typeof a === "string") { return isCSSVariableToken(a) ? mixImmediate : color.test(a) ? mixColor : mixComplex; } else if (Array.isArray(a)) { return mixArray; } else if (typeof a === "object") { return color.test(a) ? mixColor : mixObject; } return mixImmediate; } function mixArray(a, b) { const output = [...a]; const numValues = output.length; const blendValue = a.map((v, i) => getMixer(v)(v, b[i])); return (p) => { for (let i = 0; i < numValues; i++) { output[i] = blendValue[i](p); } return output; }; } function mixObject(a, b) { const output = { ...a, ...b }; const blendValue = {}; for (const key in output) { if (a[key] !== undefined && b[key] !== undefined) { blendValue[key] = getMixer(a[key])(a[key], b[key]); } } return (v) => { for (const key in blendValue) { output[key] = blendValue[key](v); } return output; }; } function matchOrder(origin, target) { var _a; const orderedOrigin = []; const pointers = { color: 0, var: 0, number: 0 }; for (let i = 0; i < target.values.length; i++) { const type = target.types[i]; const originIndex = origin.indexes[type][pointers[type]]; const originValue = (_a = origin.values[originIndex]) !== null && _a !== void 0 ? _a : 0; orderedOrigin[i] = originValue; pointers[type]++; } return orderedOrigin; } const mixComplex = (origin, target) => { const template = complex.createTransformer(target); const originStats = analyseComplexValue(origin); const targetStats = analyseComplexValue(target); const canInterpolate = originStats.indexes.var.length === targetStats.indexes.var.length && originStats.indexes.color.length === targetStats.indexes.color.length && originStats.indexes.number.length >= targetStats.indexes.number.length; if (canInterpolate) { if ((invisibleValues.has(origin) && !targetStats.values.length) || (invisibleValues.has(target) && !originStats.values.length)) { return mixVisibility(origin, target); } return pipe(mixArray(matchOrder(originStats, targetStats), targetStats.values), template); } else { warning(true, `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`); return mixImmediate(origin, target); } }; export { getMixer, mixArray, mixComplex, mixObject };