Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for interpolating boxShadows #47

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .watchmanconfig
@@ -0,0 +1,6 @@
{
"ignore_dirs": [
".git",
"node_modules"
]
}
39 changes: 25 additions & 14 deletions src/Interpolation.js
Expand Up @@ -175,20 +175,30 @@ function colorToRgba(input: string): string {

var stringShapeRegex = /[0-9\.-]+/g;

// Covers rgb, rgba, hsl, hsla
// Taken from https://gist.github.com/olmokramer/82ccce673f86db7cda5e
var colorRegex = /(#[\d\w]+|\w+\((?:\d+%?(?:,\s)*){3}(?:\d*\.?\d+)?\))/
// Covers color names (transparent, blue, etc.)
var colorNamesRegex = new RegExp(`(${Object.keys(normalizeColor.colorNames).join('|')})`, 'g')

/**
* Supports string shapes by extracting numbers so new values can be computed,
* and recombines those values into new strings of the same shape. Supports
* things like:
*
* rgba(123, 42, 99, 0.36) // colors
* -45deg // values with units
* rgba(123, 42, 99, 0.36) // colors
* 0 2px 2px 0px rgba(0, 0, 0, 0.12) // box shadows
* -45deg // values with units
*/
function createInterpolationFromStringOutputRange(
config: InterpolationConfigType,
): (input: number) => string {
var outputRange: Array<string> = (config.outputRange: any);
invariant(outputRange.length >= 2, 'Bad output range');
outputRange = outputRange.map(colorToRgba);
// Replace colors with rgba
outputRange = outputRange
.map(rangeValue => rangeValue.replace(colorRegex, colorToRgba))
.map(rangeValue => rangeValue.replace(colorNamesRegex, colorToRgba));
checkPattern(outputRange);

// ['rgba(0, 100, 200, 0)', 'rgba(50, 150, 250, 0.5)']
Expand Down Expand Up @@ -222,19 +232,20 @@ function createInterpolationFromStringOutputRange(
});
});

// rgba requires that the r,g,b are integers.... so we want to round them, but we *dont* want to
// round the opacity (4th column).
const shouldRound = (/^rgb/).test(outputRange[0]);

return (input) => {
var i = 0;
// 'rgba(0, 100, 200, 0)'
// ->
// 'rgba(${interpolations[0](input)}, ${interpolations[1](input)}, ...'
return outputRange[0].replace(stringShapeRegex, () => {
const val = interpolations[i++](input);
return String(shouldRound && i < 4 ? Math.round(val) : val);
});
return outputRange[0]
// 'rgba(0, 100, 200, 0)'
// ->
// 'rgba(${interpolations[0](input)}, ${interpolations[1](input)}, ...'
.replace(stringShapeRegex, () => interpolations[i++](input))
// rgba requires that the r,g,b are integers.... so we want to round them, but we *dont* want to
// round the opacity (4th column).
.replace(
/rgba\(([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+)\)/gi,
(_, p1, p2, p3, p4) =>
`rgba(${Math.round(p1)}, ${Math.round(p2)}, ${Math.round(p3)}, ${p4})`
)
};
}

Expand Down
7 changes: 4 additions & 3 deletions src/normalizeColor.js
Expand Up @@ -26,8 +26,8 @@ if ((match = matchers.hex6.exec(color))) {
return parseInt(match[1] + 'ff', 16) >>> 0;
}

if (names.hasOwnProperty(color)) {
return names[color];
if (colorNames.hasOwnProperty(color)) {
return colorNames[color];
}

if ((match = matchers.rgb.exec(color))) {
Expand Down Expand Up @@ -189,7 +189,7 @@ function parsePercentage(str: string): number {
return int / 100;
}

var names = {
var colorNames = {
transparent: 0x00000000,

// http://www.w3.org/TR/css3-color/#svg-color
Expand Down Expand Up @@ -345,3 +345,4 @@ var names = {
};

module.exports = normalizeColor;
module.exports.colorNames = colorNames;