Reputation: 53345
I'm trying to add some polyfill functionality to SVG. In order to do that I'm adding some javascript code to the SVG, in which I create a canvas element, draw on it, get the dataURL of the canvas and add it as image
element inside the SVG. Following is the SVG
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
height="297mm"
width="210mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg11346"
>
<script type="application/ecmascript"> <![CDATA[
var svg = document.querySelector('svg');
svg.onload = function () {
var canvas = document.createElementNS('http://www.w3.org/1999/xhtml','canvas');
canvas.width = 50;
canvas.height = 50;
var ctx = canvas.getContext('2d');
ctx.clearRect(0,0,50,50);
ctx.fillStyle = '#0f0';
ctx.fillRect(20,20,20,20);
var img = document.createElementNS('http://www.w3.org/2000/svg','image');
img.setAttribute('xlink:href', canvas.toDataURL());
img.setAttribute('x',0);
img.setAttribute('y',0);
img.setAttribute('width',50);
img.setAttribute('height',50);
svg.appendChild(img);
};
]]> </script>
<rect
style="fill:#f00;fill-opacity:1;"
id="rect11482"
width="100"
height="100"
x="200"
y="0" />
</svg>
With this code I'm expecting to see a small green rectangle near top-left corner besides the red SVG rect element. But I do not see it when I load this SVG in Chrome or Firefox. However when I inspect the DOM, I see that the image
tag has been added to the svg element. When I hover over it in the Devtools, I can see a rectangle highlighted on the page. That means the image
element is getting added, but is not being rendered.
To verify that the canvas drawing is working, I copied the image
from the dev tools, then manually inserted it into the SVG file, disabled the script code and reloaded the SVG in the browser. I can see the expected green rectangle.
This tells me that probably the SVG implementation does not refresh the rendering of the document after I've dynamically inserted the image element. I tried to dynamically insert a native SVG element (a circle) from the script and it showed properly. So it probably only has to do with the image element.
Any thoughts? Can I do something to trigger the redraw? Is there any other method by which I can show dynamically generated canvas content in the SVG?
Upvotes: 0
Views: 57
Reputation: 137014
You need setAttributeNS
for NameSpaced attributes (at least in SVG1.1) and xlink:href
is one of these.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
height="297mm"
width="210mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg11346"
>
<script type="application/ecmascript"> <![CDATA[
var svg = document.querySelector('svg');
var canvas = document.createElementNS('http://www.w3.org/1999/xhtml','canvas');
canvas.width = 50;
canvas.height = 50;
var ctx = canvas.getContext('2d');
ctx.clearRect(0,0,50,50);
ctx.fillStyle = '#0f0';
ctx.fillRect(20,20,20,20);
var img = document.createElementNS('http://www.w3.org/2000/svg','image');
img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', canvas.toDataURL());
img.setAttribute('x',0);
img.setAttribute('y',0);
img.setAttribute('width',50);
img.setAttribute('height',50);
svg.appendChild(img);
]]> </script>
<rect
style="fill:#f00;fill-opacity:1;"
id="rect11482"
width="100"
height="100"
x="200"
y="0" />
</svg>
Upvotes: 1