Skip to content

danielbayley/svgo-plugin-chameleon

Repository files navigation

Chameleon

Chameleon

Simple SVGO plugin to change fill and stroke attribute colors. Particularly useful for processing icons.

Install

pnpm add @danielbayley/svgo-plugin-chameleon --save-dev

API

This package is ESM only, and so requires Node >= 14.16 and must be imported instead of required:

// package.json
"type": "module",
"engines": {
  "node": ">=14.16"
},
import { readFile, writeFile } from "node:fs/promises"
import { optimize } from "svgo"
import { chameleon } from "@danielbayley/svgo-plugin-chameleon"

const path = "input.svg"
const svg = await readFile(path, "utf-8")
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
  fill="#0000"
  stroke="white"
>
  <rect width="14" height="14" x="1" y="1" rx="3.5"/>
  <circle cx="8" cy="8" r="3" fill="none"/>
  <circle cx="12" cy="4" r=".1"/>
</svg>

Passing fill: or stroke: as params will forcibly override those attributes:

const { data } = optimize(svg, {
  path,
  //js2svg: { pretty: true, indent: 2 },
  plugins: [{
    ...chameleon,
    params: {
      fill: "none"
      stroke: "black"
    }
  }]
})

writeFile("output.svg", data)
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
  fill="none"
  stroke="black"
>
  <rect width="14" height="14" x="1" y="1" rx="3.5"/>
  <circle cx="8" cy="8" r="3" fill="none"/>
  <circle cx="12" cy="4" r=".1"/>
</svg>

An auto: property will instead allow the algorithm to automatically find the first existing stroke or fill attribute not already set to none, and override it with the corresponding given value. Should neither exist, it will default to adding a fill:

optimize(svg, {
  plugins: [{
    ...chameleon,
    params: { auto: "currentcolor" }
  }]
})
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
  fill="none"
  stroke="currentcolor"
>
  <rect width="14" height="14" x="1" y="1" rx="3.5"/>
  <circle cx="8" cy="8" r="3" fill="none"/>
  <circle cx="12" cy="4" r=".1"/>
</svg>

A value of currentcolor will inherit from the context of the SVG.

This plugin currently works on the root <svg> element only, and does not affect any <style> element, or style attributes.

License

MIT © Daniel Bayley