What I want to do is load an svg, change its fill color to a random value and then draw it on the canvas. This has proved to be much more difficult than I would have thought. Here's the code I have at the moment.
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
//images
var bottomLeftTop = new Image();
var bottomRightTop = new Image();
var fullTop= new Image();
var leftMidSide = new Image();
var leftSide = new Image();
var rightMidSide = new Image();
var rightSide = new Image();
var topLeftTop = new Image();
var topRightTop = new Image();
bottomLeftTop.src = "img/bottomLeftTop.svg";
bottomRightTop.src = "img/bottomRightTop.svg";
fullTop.src = "img/fullTop.svg";
leftMidSide.src = "img/leftMidSide.svg";
leftSide.src = "img/leftSide.svg";
rightMidSide.src = "img/rightMidSide.svg";
rightSide.src = "img/rightSide.svg";
topLeftTop.src = "img/topLeftTop.svg";
topRightTop.src = "img/topRightTop.svg";
//draw
context.drawImage(fullTop,50,50);
I'm currently loading my svg's as Image objects, which works fine for just drawing but won't allow me to change the fill color.
I did try converting my svg to canvas commands, which allows me to change the fill but requires a lot of work to get scaled and positioned properly, and just isn't feasible with the amount of images I'm working with.
Is there any other way I can do this while still working with the canvas?
Complete HTML/CSS Course 2022To draw SVG onto canvas, you need to use SVG image. Firstly, use the <foreignObject> element which contains the HTML. After that, you need to draw the SVG image into the canvas.
The trick is to load your svg as XML via XHR and manipulate it any way you want, then create your image out of it using data:image
format.
E.g.
$.get('img/bottomLeftTop.svg', function(svgXml) {
var img = new Image();
var coloredSvgXml = svgXml.replace(/#3080d0/g,'#e05030');
img.src = "data:image/svg+xml;charset=utf-8,"+coloredSvgXml;
context.drawImage(img,0,0);
});
Here is a snippet I created to demonstrate the manipulation principle. It uses in-html hidden svg node to draw on 2d canvas, then changes the color via regexp and draws on the same canvas again:
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var svg = document.getElementById('tmpSvg')
var blueCircle = (new XMLSerializer).serializeToString(svg);
var img = new Image();
img.src = "data:image/svg+xml;charset=utf-8," + blueCircle;
context.drawImage(img, 0, 0);
redCircle = blueCircle.replace(/#3080d0/g, '#e05030');
img = new Image();
img.src = "data:image/svg+xml;charset=utf-8," + redCircle;
context.drawImage(img, 10, 10);
.wrapper {
display: none;
}
#canvas {
width: 400px;
height: 300px;
}
<canvas id="canvas"></canvas>
<div class="wrapper">
<svg id="tmpSvg" version="1.1" xmlns="http://www.w3.org/2000/svg" width="200" height="200">
<style>
circle {
fill-opacity: 0.5;
stroke-width: 4;
fill: #3080d0;
stroke: #3080d0;
}
</style>
<circle id="my-circle" cx="50" cy="50" r="30" />
</svg>
</div>
Of course, nothing prevents you from using JavaScript built-in XML parser and XPath-based node manipulation. But in this particular case and for particular colors, regexp is probably more efficient.
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