Skip to content

Instantly share code, notes, and snippets.

@aleclarson
Last active September 12, 2021 01:55
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save aleclarson/32c0698249d039cdeea22b27b4d69390 to your computer and use it in GitHub Desktop.
// Convert "translate(10px) rotate(0)" into ["translate", "rotate"]
// This helps interpolate strings of different arity.
const keyRegex = /(?:^| )([\w-]+)\(([^ ,]+(?:(?:,[ ]*|[ ]+)[^ ,)]+)*)\)/g
/**
* Create a specialized interpolator for strings like:
*
* "translate(...) rotate(...)"
*/
export const createKeyedInterpolator = (config: InterpolatorConfig<string>) => {
type KeyFrame = { [key: string]: string }
// Collect the keyframes and from values.
const fromValues: KeyFrame = {}
const keyframes = config.output.map((output, i) => {
// Replace colors with rgba(...)
output = output
.replace(colorRegex, colorToRgba)
.replace(colorNamesRegex, colorToRgba)
const keyframe: KeyFrame = {}
keyRegex.lastIndex = 0
for (let match; (match = keyRegex.exec(output)); ) {
const key = match[1]
const value = match[2]
if (fromValues[key] == null) {
// Infer 0 as the from value when none exists.
fromValues[key] = i == 0 ? value : value.replace(numberRegex, '0')
}
// Keep the parsed argument list as a string.
keyframe[key] = value
}
return keyframe
})
console.log('interpolate:', { config, fromValues, keyframes })
// Each key has its own interpolator.
const keys = Object.keys(fromValues)
const interpolators = keys.map(key => {
let prev = fromValues[key]
return createInterpolator({
...config,
output: keyframes.map(keyframe => {
const value = keyframe[key]
return value !== void 0 ? (prev = value) : prev
}),
})
})
return (input: number) =>
keys.map((key, i) => `${key}(${interpolators[i](input)})`).join(' ')
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment