Change svg fill color and then draw on canvas

What I want to do is load svg, change its fill color to a random value and then draw it on the canvas. It turned out to be much more complicated than I thought. Here is the code that 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 am currently loading svg as Image objects that are great for drawing, but won't let me change the fill color.

I tried converting svg commands to canvas, which allows me to change the padding, but it takes a lot of work to get the scaling and positioning right, and it is simply impossible to complete the number of images that I work with.

Is there any other way I can do this while still working on the canvas?

+6
source share
1 answer

The trick is to load your svg as XML via XHR and manipulate it in any way, and then create your image from it using the data:image format.

eg.

 $.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 that I created to demonstrate the principle of manipulation. It uses a hidden svg node in html to paint on a 2-dimensional canvas, then changes color using a regular expression 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 the built-in XML parser JavaScript and XPath-based node manipulation. But in this particular case and for specific colors, regular expression is probably more efficient.

+7
source

Source: https://habr.com/ru/post/980020/


All Articles