I created an SVG file that I intend to use as a background image in CSS. I want to be able to change the fill color in the SVG using a query-string parameter, like so:
#rect { background-image: url( 'rect.svg' ); }
#rect.red { background-image: url( 'rect.svg?color=red' ); }
As I understand, using a script tag in the SVG, I am able to get the color
parameter and update the fill color. Here is an example SVG:
<!DOCTYPE svg PUBLIC "-//W3C//DDTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" />
<script>
<![CDATA[
var params = { };
location.href.split( '?' )[1].split( '&' ).forEach(
function( i )
{
params[ i.split( '=' )[0] ] = i.split( '=' )[1];
}
);
if( params.color )
{
var rect = document.getElementsByTagName( "rect" )[0];
rect.setAttribute( "fill", params.color );
}
]]>
</script>
</svg>
Going to the file directly, or using an object tag seems to work, but for CSS background images or img tags, the color parameter is ignored.
I'm not exactly sure what is going on here, and I was hoping that there would be an explanation or alternative solution to what I'm trying to accomplish (preferably without resorting to server-side processing).
Here is a jsFiddle showing the different render methods: http://jsfiddle.net/ehb7S/
You can use an inline SVG that is hidden, change that and dynamically encode it as a data URL that you put into the background-image
property. Your HTML could look like:
<div id="backgroundContainer" style="display:none">
<svg width="100px" height="100px" id="backgroundSvg" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" fill="green"/>
</svg>
</div>
<div id="divWithBackground" onclick="changeBackground(event)">
Click to change background SVG to random color
</div>
and your JavaScript like
changeBackground = function(event) {
var backgroundSvg = document.getElementById("backgroundSvg");
var backgroundContainer = document.getElementById("backgroundContainer");
backgroundSvg.getElementsByTagName("circle")[0].setAttribute(
"fill",
["red","green","blue","black"][Math.floor(4*Math.random())]
);
event.target.setAttribute(
"style",
"background-image:url(data:image/svg+xml,"
+ encodeURI(backgroundContainer.innerHTML)
+ ")"
);
}
See the proof of concept on jsFiddle.
I ended up created a server-side solution that allows me to inject the color fill into the SVG file. Essentially, I redirect all SVG requests to a PHP file that does the following on them:
$filename = $_SERVER['SCRIPT_FILENAME'];
$svg = simplexml_load_file( $filename );
if( isset( $_GET['color'] ) )
{
$svg->path->addAttribute( 'fill', '#' . $_GET['color'] );
}
header( "Content-type: image/svg+xml" );
echo $svg->asXML( );
Obviously, there's a little more to it than that, what with handling caching and such, but that's the meat-n-potatoes. Might want to check if the fill
attribute already exists, as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With