MCPcopy
hub / github.com/pmndrs/react-spring / createStringInterpolator

Function createStringInterpolator

packages/shared/src/stringInterpolation.ts:40–119  ·  view source on GitHub ↗
(
  config: InterpolatorConfig<string>
)

Source from the content-addressed store, hash-verified

38 * "rotate(0deg) translate(2px, 3px)" // CSS transforms
39 */
40export const createStringInterpolator = (
41 config: InterpolatorConfig<string>
42) => {
43 if (!namedColorRegex)
44 namedColorRegex = G.colors
45 ? // match color names, ignore partial matches
46 new RegExp(`(${Object.keys(G.colors).join('|')})(?!\\w)`, 'g')
47 : // never match
48 /^\b$/
49
50 // Convert colors to rgba(...)
51 const output = config.output.map(value => {
52 return getFluidValue(value)
53 .replace(cssVariableRegex, variableToRgba)
54 .replace(colorRegex, colorToRgba)
55 .replace(namedColorRegex, colorToRgba)
56 })
57
58 // Convert ["1px 2px", "0px 0px"] into [[1, 2], [0, 0]]
59 const keyframes = output.map(value => getNumbers(value).map(Number))
60
61 // Convert ["1px 2px", "0px 0px"] into [[1, 0], [2, 0]]
62 const outputRanges = keyframes[0].map((_, i) =>
63 keyframes.map(values => {
64 if (!(i in values)) {
65 throw Error('The arity of each "output" value must be equal')
66 }
67 return values[i]
68 })
69 )
70
71 // Create an interpolator for each animated number
72 const interpolators = outputRanges.map(output =>
73 createInterpolator({ ...config, output })
74 )
75
76 const inputRange = config.range || [0, 1]
77
78 // Per number-position, the shared fractional-digit count across all
79 // keyframes — or `null` when keyframes disagree or every keyframe is
80 // a whole number. Whole-number keyframes are left untouched so that
81 // values like the alpha channel in `rgba(…, 0)` → `rgba(…, 1)` keep
82 // their natural sub-frame precision.
83 const allTokens = output.map(value => getNumbers(value))
84 const decimalCounts = allTokens[0].map((_, pos) => {
85 const counts = allTokens.map(tokens => {
86 const token = tokens[pos]
87 const dot = token.indexOf('.')
88 return dot === -1 ? 0 : token.length - dot - 1
89 })
90 return counts.every(c => c === counts[0]) && counts[0] > 0
91 ? counts[0]
92 : null
93 })
94
95 // Use the first `output` as a template for each call
96 return (input: number) => {
97 // When `input` lands exactly on a keyframe, return that keyframe's

Callers 1

Calls 3

getFluidValueFunction · 0.90
createInterpolatorFunction · 0.90
getNumbersFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…