用 javascript 改变 SVG 图像颜色

我试图用 javascript 改变 svg 图像的颜色。这可能吗?我可以把它作为一个对象加载,然后以某种方式访问颜色/图像数据。

每一个回复或提示都是非常感谢的!

228843 次浏览

For the background color - the fill property can be accessed like so:

svgElement.style.fill = '#fff';

To set the border color, do the same for the stroke property.

See it in action:

const svgElement = document.getElementById('svg')
const checkboxElement = document.getElementById('check')


checkboxElement.addEventListener('change', e => {
svgElement.style.fill = e.target.checked ? 'PeachPuff' : 'PapayaWhip'
})
<input type="checkbox" id="check" />
<svg id="svg" fill="AliceBlue">
<circle r="50" cx="70" cy="70" />
</svg>

Please refer to the W3C reference on SVG for more capabilities, as it's a broad issue.

Sure, here is an example (standard HTML boilerplate omitted):

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" style="width: 3.5in; height: 1in">
<circle id="circle1" r="30" cx="34" cy="34"
style="fill: red; stroke: blue; stroke-width: 2"/>
</svg>
<button onclick="circle1.style.fill='yellow';">Click to change to yellow</button>

Here's a full example that shows how to modify the fill color of an svg referenced via <embed>, <object> and <iframe>.

Also see How to apply a style to an embedded SVG?

Given some SVG:

<div id="main">
<svg id="octocat" xmlns="http://www.w3.org/2000/svg" width="400px" height="400px" viewBox="-60 0 420 330" style="fill:#fff;stroke: #000; stroke-opacity: 0.1">
<path id="puddle" d="m296.94 295.43c0 20.533-47.56 37.176-106.22 37.176-58.67 0-106.23-16.643-106.23-37.176s47.558-37.18 106.23-37.18c58.66 0 106.22 16.65 106.22 37.18z"/>
<path class="shadow-legs" d="m161.85 331.22v-26.5c0-3.422-.619-6.284-1.653-8.701 6.853 5.322 7.316 18.695 7.316 18.695v17.004c6.166.481 12.534.773 19.053.861l-.172-16.92c-.944-23.13-20.769-25.961-20.769-25.961-7.245-1.645-7.137 1.991-6.409 4.34-7.108-12.122-26.158-10.556-26.158-10.556-6.611 2.357-.475 6.607-.475 6.607 10.387 3.775 11.33 15.105 11.33 15.105v23.622c5.72.98 11.71 1.79 17.94 2.4z"/>
<path class="shadow-legs" d="m245.4 283.48s-19.053-1.566-26.16 10.559c.728-2.35.839-5.989-6.408-4.343 0 0-19.824 2.832-20.768 25.961l-.174 16.946c6.509-.025 12.876-.254 19.054-.671v-17.219s.465-13.373 7.316-18.695c-1.034 2.417-1.653 5.278-1.653 8.701v26.775c6.214-.544 12.211-1.279 17.937-2.188v-24.113s.944-11.33 11.33-15.105c0-.01 6.13-4.26-.48-6.62z"/>
<path id="cat" d="m378.18 141.32l.28-1.389c-31.162-6.231-63.141-6.294-82.487-5.49 3.178-11.451 4.134-24.627 4.134-39.32 0-21.073-7.917-37.931-20.77-50.759 2.246-7.25 5.246-23.351-2.996-43.963 0 0-14.541-4.617-47.431 17.396-12.884-3.22-26.596-4.81-40.328-4.81-15.109 0-30.376 1.924-44.615 5.83-33.94-23.154-48.923-18.411-48.923-18.411-9.78 24.457-3.733 42.566-1.896 47.063-11.495 12.406-18.513 28.243-18.513 47.659 0 14.658 1.669 27.808 5.745 39.237-19.511-.71-50.323-.437-80.373 5.572l.276 1.389c30.231-6.046 61.237-6.256 80.629-5.522.898 2.366 1.899 4.661 3.021 6.879-19.177.618-51.922 3.062-83.303 11.915l.387 1.36c31.629-8.918 64.658-11.301 83.649-11.882 11.458 21.358 34.048 35.152 74.236 39.484-5.704 3.833-11.523 10.349-13.881 21.374-7.773 3.718-32.379 12.793-47.142-12.599 0 0-8.264-15.109-24.082-16.292 0 0-15.344-.235-1.059 9.562 0 0 10.267 4.838 17.351 23.019 0 0 9.241 31.01 53.835 21.061v32.032s-.943 11.33-11.33 15.105c0 0-6.137 4.249.475 6.606 0 0 28.792 2.361 28.792-21.238v-34.929s-1.142-13.852 5.663-18.667v57.371s-.47 13.688-7.551 18.881c0 0-4.723 8.494 5.663 6.137 0 0 19.824-2.832 20.769-25.961l.449-58.06h4.765l.453 58.06c.943 23.129 20.768 25.961 20.768 25.961 10.383 2.357 5.663-6.137 5.663-6.137-7.08-5.193-7.551-18.881-7.551-18.881v-56.876c6.801 5.296 5.663 18.171 5.663 18.171v34.929c0 23.6 28.793 21.238 28.793 21.238 6.606-2.357.474-6.606.474-6.606-10.386-3.775-11.33-15.105-11.33-15.105v-45.786c0-17.854-7.518-27.309-14.87-32.3 42.859-4.25 63.426-18.089 72.903-39.591 18.773.516 52.557 2.803 84.873 11.919l.384-1.36c-32.131-9.063-65.692-11.408-84.655-11.96.898-2.172 1.682-4.431 2.378-6.755 19.25-.80 51.38-.79 82.66 5.46z"/>
<path id="face" d="m258.19 94.132c9.231 8.363 14.631 18.462 14.631 29.343 0 50.804-37.872 52.181-84.585 52.181-46.721 0-84.589-7.035-84.589-52.181 0-10.809 5.324-20.845 14.441-29.174 15.208-13.881 40.946-6.531 70.147-6.531 29.07-.004 54.72-7.429 69.95 6.357z"/>
<path id="eyes" d="m160.1 126.06 c0 13.994-7.88 25.336-17.6 25.336-9.72 0-17.6-11.342-17.6-25.336 0-13.992 7.88-25.33 17.6-25.33 9.72.01 17.6 11.34 17.6 25.33z m94.43 0 c0 13.994-7.88 25.336-17.6 25.336-9.72 0-17.6-11.342-17.6-25.336 0-13.992 7.88-25.33 17.6-25.33 9.72.01 17.6 11.34 17.6 25.33z"/>
<path id="pupils" d="m154.46 126.38 c0 9.328-5.26 16.887-11.734 16.887s-11.733-7.559-11.733-16.887c0-9.331 5.255-16.894 11.733-16.894 6.47 0 11.73 7.56 11.73 16.89z m94.42 0 c0 9.328-5.26 16.887-11.734 16.887s-11.733-7.559-11.733-16.887c0-9.331 5.255-16.894 11.733-16.894 6.47 0 11.73 7.56 11.73 16.89z"/>
<circle id="nose" cx="188.5" cy="148.56" r="4.401"/>
<path id="mouth" d="m178.23 159.69c-.26-.738.128-1.545.861-1.805.737-.26 1.546.128 1.805.861 1.134 3.198 4.167 5.346 7.551 5.346s6.417-2.147 7.551-5.346c.26-.738 1.067-1.121 1.805-.861s1.121 1.067.862 1.805c-1.529 4.324-5.639 7.229-10.218 7.229s-8.68-2.89-10.21-7.22z"/>
<path id="octo" d="m80.641 179.82 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m8.5 4.72 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m5.193 6.14 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m4.72 7.08 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m5.188 6.61 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m7.09 5.66 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m9.91 3.78 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m9.87 0 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m10.01 -1.64 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z"/>
<path id="drop" d="m69.369 186.12l-3.066 10.683s-.8 3.861 2.84 4.546c3.8-.074 3.486-3.627 3.223-4.781z"/>
</svg>
</div>

Using jQuery, for instance, you could do:

var _currentFill = "#f00"; // red
$svg = $("#octocat");
$("#face", $svg).attr('style', "fill:"+_currentFill); })

I provided a coloring book demo as an answer to another stackoverflow question: http://bl.ocks.org/4545199. Tested on Safari, Chrome, and Firefox.

This is for <object> SVG and className is .svgClass

<object class="svgClass" type="image/svg+xml" data="image.svg"></object>

So JavaScript code is like this:

// change to red
document.querySelector(".svgClass").getSVGDocument().getElementById("svgInternalID").setAttribute("fill", "red")

To change svgInternalID you have to open SVG file which is plain .txt (ie image.svg) and edit it

<path id="svgInternalID"

If it is just about the color and there is no specific need for JavaScript, you could also convert them to a font. This link gives you an opportunity to create a font based on the SVG. However, it is not possible to use img attributes afterwards - like "alt". This also limits the accessibility of your website for blind people and so on.

Built off the above but with dynamic creation and a vector image, not drawing.

function svgztruck() {
tok = "{d path value}"
return tok;
}


function buildsvg( eid ) {
console.log("building");
var zvg = "svg" + eid;
var vvg = eval( zvg );
var raw = vvg();


var svg = document.getElementById( eid );
svg.setAttributeNS(null,"d", raw );
svg.setAttributeNS(null,"fill","green");
svg.setAttributeNS(null,"onlick", eid + ".style.fill=#FF0000");
return;
}

You could call with:

<img src="" onerror="buildscript">

Now you can add colors by sub element and manipulate all elements of the dom directly. It is important to implement your viewbox and height width first on the svg html, not done in the example above.

There is no need to make your code 10 pages when it could be one... but who am I to argue. Better use PHP while your at it.

The inner element that svg builds on is a simple <svg lamencoding id=parenteid><path id=eid><svg> with nothing else.

Your SVG must be inline in your document in order to be styled with CSS. This can be done by writing the SVG markup directly into your HTML code, or by using SVG injection, which replaces the img element with the content from and SVG file with Javascript.

There is an open source library called SVGInject that does this for you. All you have to do is to add the attribute onload="SVGInject(this)" to you <img> tag.

A simple example using SVGInject looks like this:

<html>
<head>
<script src="svg-inject.min.js"></script>
</head>
<body>
<img src="image.svg" onload="SVGInject(this)" />
</body>
</html>

After the image is loaded the onload="SVGInject(this) will trigger the injection and the <img> element will be replaced by the contents of the SVG file provided in the src attribute.

I am probably replying way too late, but this is how I did it! There is so many ways you can play with the color I was actually getting the rgba from a pixel using canvas and changing it dinamically, but for this example I am just going to use ramdon colors for the rgba, also you can use whatever you want, it does not have to be an rgba

//First
const fs = require("fs");
const path = require("path");
const uuid = require('uuid');

Btw I am using uuid just to change the name dinamically every time a save an svg so it does not overwrite the original, but is not needed if you only want to use the code once I guess. Also remember that not all svg images have the property "stroke" or "fill" which is usually located in a style or a <path></path> so you need to play a little bit with that part, when the property is missing I usually just add it manually according to the color or colors of the svg for example if its black I just add fill="rgba(0,0,0,1)" or stroke="rgba(0,0,0,1)" or some times both depending on the svg

//Inside svg
<g id="#svgColor">
<path fill="rgba(0,0,0,1)".........lots of codes />
<path fill="rgba(0,0,0,1)".........lots of codes />
<path fill="rgba(0,0,0,1)".........lots of codes />
</g>

Logic Part

//svgColor.js
const fs = require("fs");
const path = require("path");
const uuid = require("uuid");


const changeSvgColor = () => {
try {
var r = Math.floor(Math.random() * 255);
var g = Math.floor(Math.random() * 255);
var b = Math.floor(Math.random() * 255);
var a = Math.floor(Math.random() * 255);


const svgCode = fs.readFileSync(
path.resolve(__dirname, "./assets/watermark.svg"),
"utf8"
);
coloredSvgXml = svgCode.replaceAll(
"rgba(0,0,0,1)",
`rgba(${r},${g},${b},${a})`
);
fs.writeFile(
`./myFolder/assets/${uuid.v4()}.svg`,
coloredSvgXml,
function (err) {
console.log(err);
}
);
} catch (error) {
console.log(error);
}
};


module.exports = {
changeSvgColor,
};

After this then just go and create an index.js file (if you want),call your function and you should be ready to go :D

//index.js


const changeColor = require('./myFolder/svgColor');
changeColor.changeSvgColor();

Run this from your terminal

node index.js

I know this is a pretty old question. But I stumbled over it searching for the same topic. Out of this and some other answers I finally built a function for precisely this topic:

  • It loads a SVG completely in JavaScript ...
  • removes the size-tags to make it scale with its parent DIV
  • even adjusts the viewbox to make it square and
  • changes the fillColor in different ways.

Maybe this is of help for some of you:

/* inspired by https://codepen.io/osublake/pen/OMRdKq */


function loadSvgIntoDiv(theDIV, pathToSvg, prefix = 'myPrefix-', fillColor = null, fillColorID = null)
{
if ( theDIV == null || typeof theDIV.appendChild != 'function' ) return null;
  

fetch(pathToSvg).then( (res) => {


// check the status
        

if (!res.ok)
{
switch (res.status)
{
case 404:
throw new Error('"' + pathToSvg + '" not found (error 404).');
                

default:
throw new Error('Failed to fetch "' + pathToSvg + '": ' + res.status + ' (' + res.statusText + ')');
}
}


let contentType = res.headers.get('content-type');


if ( typeof contentType == 'string' && contentType.indexOf('image/svg') !== -1 )
{
// hand over SVG-content to next .then
return res.text();


} else {


throw new Error('Unexpected content type (' + iconPath + ', ' + contentType + ')');
}
})
.then( (iconData) => {


// clean up SVG
    

// remove width and height from <svg ...>-tag to allow scaling
iconData = iconData.replace(/\<svg([^>]*)\>/ig, (match) => {
return match.replace(/width\=[\'\"]([^\"^\']*)[\"\']/ig, '').replace(/height\=[\'\"]([^\"^\']*)[\"\']/ig, '');
});
        

// adjust viewbox to be a square image
iconData = iconData.replace(/\<svg([^>]*)\>/ig, (match) => {
return match.replace(/viewbox\=[\'\"][^0-9^\.^\-]*([0-9\.\-]*)[^0-9^\.^\-]*([0-9\.\-]*)[^0-9^\.^\-]*([0-9\.\-]*)[^0-9^\.^\-]*([0-9\.\-]*)[^\"^\']*[\"\']/ig, (match, x, y, w, h) => {
x = Number(x);
y = Number(y);
w = Number(w);
h = Number(h);
if ( w < h ) { x=x-(h-w)/2; w=h; }
if ( h < w ) { y=y-(w-h)/2; h=w; }
return 'viewbox="' + x + ' ' + y + ' ' + w + ' ' + h + '"';
});
});
        

let origIcon = iconData;


// add fill-style to a given id
if ( fillColorID != null && fillColor != null )
{
let search = '/id\=[\"\']' + fillColorID + '[\"\']/ig';
iconData = iconData.replace(search, 'id="' + fillColorID + '" style="fill: ' + fillColor + '" ');
}


// edit all fill-statements within path-tags
if ( fillColor != null ) fillColor='fill="' + fillColor + '"';
if ( fillColor == null || fillColorID != null ) fillColor='';
iconData = iconData.replace(/\<path([^>]*)\>/ig, (match) => {
return match.replace(/fill\=[\'\"]([^\"^\']*)[\"\']/ig, fillColor);
});
iconData = iconData.replace(/\<g\ ([^>]*)\>/ig, (match) => {
return match.replace(/fill\=[\'\"]([^\"^\']*)[\"\']/ig, fillColor);
});
        

// no fill was added, as nothing was changed
if ( iconData == origIcon)
{
iconData = iconData.replace(/\<g\ ([^>]*)\>/ig, (match, p) => {
return '<g ' + replaceFill + p + '>';
});
iconData = iconData.replace(/\<path([^>]*)\>/ig, (match, p) => {
return '<path ' + replaceFill + p + '>';
});
}


// add prefix in front of every ID to prevent duplicates
iconData = iconData.replace(/id\=[\"\']([^\"^\']*)[\"\']/ig, 'id="' + prefix + '$1"');


// finally add the SVG to the div
theDIV.innerHTML = iconData;
})
.catch( (error) => {


// handle error messages
});
}

see also: https://gist.github.com/aroesler-privat/2c304d42644c72142195842b10fff781