A gulp package for replacing colors within SVGs.
This library is a fork of the gulp-recolor-svg plugin, which appeared to be unmaintained, but highly useful for me.
This project uses yarn
Thanks should go to Richard Clark for creating this project in the first place.
The main differences between the two projects are
- updated dependencies
- internalising usage of Color module
- adding yarn.lock
Let's say I have the following SVG (named plus.svg), a blue "+" symbol:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 15 15" enable-background="new 0 0 15 15" xml:space="preserve">
<path fill="#0000FF" d="M6.3,1.1v5.2H1.1c-0.7,0-0.7,0.5-0.7,1.2c0,0.7,0.1,1.2,0.7,1.2h5.2v5.2c0,0.7,0.5,0.7,1.2,0.7
c0.7,0,1.2-0.1,1.2-0.7V8.7h5.2c0.7,0,0.7-0.5,0.7-1.2c0-0.7-0.1-1.2-0.7-1.2H8.7V1.1c0-0.7-0.5-0.7-1.2-0.7
C6.8,0.4,6.3,0.5,6.3,1.1"/>
</svg>The simplest use case for this package is replacing one or more colors in an SVG with different colors.
This gulpfile will generate a new SVG, plus--red.svg, containing a red plus symbol in place of the blue symbol:
const gulp = require('gulp');
const RecolorSvg = require('gulp-svg-recolor');
const rename = require('gulp-rename');
gulp.task('default', function(){
gulp.src('plus.svg')
.pipe(RecolorSvg.Replace(
[RecolorSvg.ColorMatcher('blue')],
['red']
))
.pipe(rename({
suffix: '--red'
}))
.pipe(gulp.dest('./'));
});This package can also be used to easily generate multiple variants of an input image. For example, if I'm using an SVG as the background of a <button>, I can easily different color variants for the button's hover, active, focus, and disabled states.
Given plus.svg, this gulpfile will generate four SVGs: plus--hover.svg, plus--active.svg, plus--focus.svg, and plus--disabled.svg, each with a different colored plus symbol:
const gulp = require('gulp');
const RecolorSvg = require('gulp-svg-recolor');
gulp.task('default', function(){
gulp.src('plus.svg')
.pipe(RecolorSvg.GenerateVariants(
[RecolorSvg.ColorMatcher('blue')],
[{ suffix: '--hover', colors: ['red'] },
{ suffix: '--active', colors: ['yellow'] },
{ suffix: '--focus', colors: ['cyan'] },
{ suffix: '--disabled', colors: ['#ccc'] }]
))
.pipe(gulp.dest('./'));
});This is just a wrapper around the color package for Node, which provides utilities for parsing and serializing CSS colors.
RecolorSvg exposes Color module, however after API and documentation issues caused confusion and the library to 'not work', the need to pass in color objects i.e. Color("red"), was removed and now you simply pass in a valid CSS color value.
This returns a function that, when invoked with a color, will return a boolean value indicating whether the similarity of this color to the color used when instantiating the matcher is within the specified threshold.
Colors are compared using the CIE76 color difference algorithm. Since the vision of humans is more sensitive to differences in certain colors than in others, using the algorithm allows colors to be replaced uniformly across the visible spectrum. (However, this algorithm does have certain limitations—see the linked algorithm.)
Usage:
const RecolorSvg = require('gulp-svg-recolor');
const Color = require('color');
// You can use your own version of Color outside the library, just be sure
// to convert it back to a valid CSS color value, like hex.
const lighterRed = Color('red').lighten(0.02).hex();
matcher = RecolorSvg.ColorMatcher('red', 2);
matcher(lighterRed); # returns true
matcher('blue'); # returns falseReturns a function that when passed a stream containing a file, emits multiple files—one for each variant—with the colors replaced.
Arguments:
-
matcherFunctionsis an array of functions that accept a single argument (a color) and return a boolean value indicating whether that color should be replaced. A matcher function can be an instance ofColorMatcher, or a custom function. -
variants: an array of objects withsuffixandcolorsproperties. The value ofsuffixis appended to the file name of the file generated for the variant; the value ofcolorsis an array of colors, with a length equal to the length ofmatcherFunctions. If a function frommatcherFunctionsevaluates totruefor a certain color in the SVG, that color will be replaced with the color at the corresponding index fromcolors.
Returns a function that when passed a stream containing a file, emits a file with the colors replaced.
Arguments:
-
matcherFunctionsis an array of functions that accept a single argument (a color) and return a boolean value indicating whether that color should be replaced. A matcher function can be an instance ofColorMatcher, or a custom function. -
replacementColorsis an array of replacement colors. The length of this array should match the length ofmatcherFunctions. For each function ofmatcherFunction, if the function returns atruevalue, that color will be replaced by the color at the corresponding index fromreplacementColors.
See the Simple Recolor example.
Prior to running tests, you must install the devDependencies using:
npm installTests can be run using:
npm testCurrently, only fill and stroke properties are supported.
These properties will be replaced if they're set in any of the following ways:
- As attributes (
<path fill="red" stroke="blue" />) - As properties in a
styleattribute (<path style="fill: red; stroke: blue;") - In a stylesheet (
path { fill: red; stroke: blue })
This package only works with solid colors; colors with transparency aren't supported.