Firefox error rendering an SVG image to HTML5 canvas with drawImage
Firefox does not support drawing SVG images to canvas unless the svg file has width/height attributes on the root <svg>
element and those width/height attributes are not percentages. This is a longstanding bug.
You will need to edit the icon.svg file so it meets the above criteria.
Not able to draw SVG to HTMl5 canvas in Firefox (even with height and width set)
Your demo is working fine for me in FF. I see a black rectangle.
Did you accidentally use an SVG in your example that works?
If some other of your SVGs don't work, it may be because of a common issue people strike when working with SVG DataURIs in Firefox: the hash/pound symbol (#).
Technically '#' is a reserved character in URLs. It marks a fragment identifier. It appears in SVGs both as a fragment identifier (eg. url(#mygradient)
and in colours (#ffcc88
).
Chrome and other browsers are more forgiving if there are '#'s in the DataURI, but Firefox isn't. This is not a bug in Firefox. It is behaving correctly.
The solution to this is to escape any '#'s in your SVG the way you would any reserved URL characters - by using percentage encoding. For '#' the encoding is %23
.
Canvas drawImage inline svg doesn't work on Firefox
The SVG image data must have width and height attributes that are not percentages.
Canvas Draw Image issue on firefox, works well in chrome
Your problem is that the image your are trying to draw are svg images, and that these svg documents have relative width
and height
attributes.
The browser can't set a height nor a width to the image it has to draw, and hence it can't render it to the canvas. (It is able to do an estimation in the document, since it can be relative to something, but not in the canvas).
So the solution is to set absolute width
and height
attributes in your svg files,
Or, more complicated, to first draw it into an <iframe>
or an <object>
, then draw a serialized version where you'll have set these attributes.
function initialize() {
var canvas = document.getElementById("char1Canvas");
var canvasContext = canvas.getContext("2d");
var image = document.getElementById("char1Img");
resizeSVG(image, function(e){
canvasContext.clearRect(0, 0, 1280, 1280);
canvasContext.drawImage(this, 0, 0);
});
};
var resizeSVG = function(svgImg, callback){
// create an iframe
var iframe = document.createElement('iframe');
// so we don't see it
iframe.height = 0;
iframe.width = 0;
iframe.onload = function(){
var doc = iframe.contentDocument;
var svg = doc.querySelector('svg');
// get the computed width and height of your img element
// should probably be tweaked
var bbox = svgImg.getBoundingClientRect();
// if it's a relative width
if (svg.width.baseVal.unitType !== 1) {
svg.setAttribute('width', bbox.width);
}
// or a relative height
if (svg.height.baseVal.unitType !== 1) {
svg.setAttribute('height', bbox.height);
}
// serialize our updated svg
var svgData = (new XMLSerializer()).serializeToString(svg);
var svgURL = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData);
// create a new Image Object that ill be draw on the canvas
var img = new Image();
img.onload = callback;
img.src = svgURL;
// remove the iframe
document.body.removeChild(iframe);
};
iframe.src = svgImg.src;
document.body.appendChild(iframe);
}
Problems calling drawImage() with svg on a canvas context object in Firefox
Add a width attribute to the outer <svg>
element. E.g. width="450"
The first case has width and height, the second only height and Firefox currently required both width and height to be present.
Cannot Draw Canvas Image On Image's Load
I figured out the issue I was having here. I needed to add width
/height
attributes to the SVG element I was using as an image.
Draw resized SVG image in HTML canvas in Firefox
I finally found a way of drawing a resized SVG on a canvas in Firefox. The idea is to get the SVG source via AJAX and change the SVG via JavaScript with something like:
var transformTag;
transformTag = $(document.createElementNS('http://www.w3.org/2000/svg', 'g'))
.attr('transform', 'scale(' + scaleX + ', ' + scaleY + ')');
svgElement.attr({
'height': dh,
'viewbox': '0 0 ' + dw + ' ' + dh,
'width': dw
})
.wrapInner(transformTag);
Here is a jsFiddle (without AJAX but it is simple to change).
Since the modification and image creation is slow, I added a simple cache mechanism (not shown in the fiddle, but once again, it is easy to implement) and the speed is really fast.
It works in Chromium, Firefox and Opera (but for some reason, the fiddle does not work in Opera, though it works in my development server).
P.S.: if there is a jQuery alternative to document.createElementNS
, I would like to know.
Firefox can't draw an image with a data uri onto a canvas: NS_ERROR_NOT_AVAILABLE
Unfortunately, the answer seems to be that it's a bug in Firefox at the moment, specifically relating to SVG's: https://bugzilla.mozilla.org/show_bug.cgi?id=700533
Firefox's own documentation says it should work: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#drawImage()
Related Topics
Javascript: Simple Way to Check If Variable Is Equal to One of Two or More Values
Remove HTML Tags in JavaScript with Regex
Random Alpha-Numeric String in JavaScript
Clearrect Function Doesn't Clear the Canvas
Check If Jquery Has Been Loaded, Then Load It If False
How to Stop Babel from Transpiling 'This' to 'Undefined' (And Inserting "Use Strict")
Date.Setmonth' Causes the Month to Be Set Too High If 'Date' Is at the End of the Month
Split String Only on First Instance of Specified Character
Check Whether an Array Exists in an Array of Arrays
How to Create a Web Worker from a String
Node.Js Shell Command Execution
JavaScript Accessing Inner Dom of Svg
How to Check If a Number Is Between Two Values
How to Smoothly Scroll to an Element in Pure JavaScript
Using Number as "Index" (JSON)