user2441511
user2441511

Reputation: 11116

How to use JS to dynamically change the color of a complex svg

I want to use JavaScript to dynamically change the color of an image. I was able to use JavaScript to load an svg path and change the color, but I also want to use a more complex image. (E.g., the center oval should be black while I dynamically change the outer image color.)

Here's my simpler example: an oval with a hole missing; I can dynamically color this in JavaScript.

var color = 'red';
var svgSource = "<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='250' height='150'><path stroke='black' stroke-width='2' fill='" + color + "' d='M 122.55664 14.691406 A 93.393089 51.964569 0 0 0 30.900391 67.289062 A 93.393089 51.964569 0 0 0 124.86133 118.61133 A 93.393089 51.964569 0 0 0 217.67969 66.648438 L 217.65039 65.365234 A 93.393089 51.964569 0 0 0 122.55664 14.691406 z M 91.923828 63.494141 A 47.749851 20.034533 0 0 1 140.54297 83.03125 L 140.55664 83.525391 A 47.749851 20.034533 0 0 1 93.101562 103.56055 A 47.749851 20.034533 0 0 1 45.060547 83.773438 A 47.749851 20.034533 0 0 1 91.923828 63.494141 z' /></svg>";

// display image
document.getElementById("image").innerHTML = "<img src=\"data:image/svg+xml;utf8," + svgSource + "\">";;
<div id="image"></div>

Question: How can I do this with a more complicated path?

My more complicated object is made up of two paths, the color changing outer shape:

M 217.67871,66.647797 A 93.393089,51.964569 0 0 1 124.86224,118.61138 93.393089,51.964569 0 0 1 30.899652,67.289449 93.393089,51.964569 0 0 1 122.55587,14.692141 93.393089,51.964569 0 0 1 217.65023,65.364589

and a solid black inner oval defined by

M 140.55713,83.526031 A 47.749851,20.034533 0 0 1 93.102092,103.56018 47.749851,20.034533 0 0 1 45.061071,83.773416 47.749851,20.034533 0 0 1 91.922895,63.494936 47.749851,20.034533 0 0 1 140.54257,83.031301

Upvotes: 0

Views: 2831

Answers (2)

user2441511
user2441511

Reputation: 11116

I ended up experimenting enough with the svg tag and figured out how to get the inner circle as a different color. I thought I needed two path elements in my svg tag (@Paul LeBeau is correct), but I kept messing up the syntax. Each path should be in its own set of angle brackets:

var svgSource = "<svg ... ><path ... /><path ... /></svg>"

Full working example:

var color = 'red',
    color2 = 'black';

var svgSource = "<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='250' height='150'>" 
      + "<path stroke='black' stroke-width='2' fill='" + color 
      + "' d='M 122.55664 14.691406 A 93.393089 51.964569 0 0 0 30.900391 67.289062 A 93.393089 51.964569 0 0 0 124.86133 118.61133 A 93.393089 51.964569 0 0 0 217.67969 66.648438 L 217.65039 65.365234 A 93.393089 51.964569 0 0 0 122.55664 14.691406 z' />"
      + "<path stroke='black' stroke-width='2' fill='" + color2 
      + "' d='M 91.923828 63.494141 A 47.749851 20.034533 0 0 1 140.54297 83.03125 L 140.55664 83.525391 A 47.749851 20.034533 0 0 1 93.101562 103.56055 A 47.749851 20.034533 0 0 1 45.060547 83.773438 A 47.749851 20.034533 0 0 1 91.923828 63.494141 z' />"
      + "</svg>";

// display image
document.getElementById("image").innerHTML = "<img src=\"data:image/svg+xml;utf8," + svgSource + "\">";;
<div id="image"></div>

Note that I've broken up the svgSource variable into multiple strings for readability and because my color variables change as I add several differently colored icons. If you're not trying to dynamically add color, the <svg> can just written be one long string.

Upvotes: 1

Paul LeBeau
Paul LeBeau

Reputation: 101918

If the two shapes are combined into one path, you are not going to have two filled shapes. You will normally just end up with one shape with a hole in it. And you won't be able to change the colour of the hole.

What you need to do is have two separate <path> elements

Upvotes: 1

Related Questions