I have an external SVG file which contains the following SVG definition:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>
The SVG has multiple paths, so for me to be able to change colours of individual paths I need to be able to load the SVG file contents into a Javascript variable like this:
var svgSource = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>';
Then I can use conditional statements to alter the colours e.g.
switch(centerId) {
case 1:
svgSource = svgSource.replace("#ffbf00", "#005D00");
break;
case 2:
svgSource = svgSource.replace("#ffbf00", "#A20000");
break;
case 3:
svgSource = svgSource.replace("#ffbf00", "#ffbf00");
break;
}
I could define and use the inline SVG code hard coded into the Javascript as shown, but for maintenance and continuity it would be much better to use existing, centralised, external SVG files.
Can I load the contents of the SVG file into a javascript variable/object?
CodePudding user response:
One solution is to load the svg image by setting the innerHTML
property of an arbitrary container to your svg string.
This then gives you two options: firstly, for heavy changes, you have access to each path as part of the DOM and can maniulate them using javascript. This simply requires making a reference to container.children[0]
; Alternatively, for simple changes such as colour changes, it makes each element directly targetable by style rules where you can specify colours in the usual way.
The snippet illustrates adding the svg to the dom using your string, and resets some colours with simple style rules. Making a reference for changes using javascript is shown commented at the foot of the code.
let svgSource = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>';
const container = document.getElementsByTagName('div')[0];
container.innerHTML = svgSource;
// for js manipulation:
// svgObject = container.children[0];
div {
width: 50%;
}
.st0 {
fill: red;
}
.st1 {
fill: yellow;
}
circle {
fill: green;
}
<div>
</div>
CodePudding user response:
Try using CSS to style the paths instead of replacing parts of source code.
Concept code example, using the style
attribute of svg elements to apply some CSS:
"use strict";
const svg = document.querySelector("svg");
const paths = svg.querySelectorAll("path");
paths[0].style = "fill: #FF0000;"
svg.querySelector("circle").style = "fill: rebeccapurple";
svg {
height: 150px;
width: 100px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>
Potentially you could improve on this by writing svg source that expects to be styled by CSS instead of being over-ridden by style attribute values.
See also: How to use external SVG in HTML?