In chrome, FF, IE10 and older I have been succesfully using fabric.Image.fromURL to add svg and png pictures onto my fabric canvas.
Adding PNG Images that way is also working in IE11 but fails if the image to add is a SVG.
The object seems to be added, but it won't display and has a size of 0.
JSFiddle:
http://jsfiddle.net/xw5es/6/
I tried to find this bug in the issue list but couldn't. Is there an easy way to solve this? If possible I would like not to use loadSVGFromURL as I would rather like to rely on the browsers svg capabilities for now.
Thanks for reading and providing this awesome library.
Tim
It looks like this is a bug in Internet Explorer 11 - nothing we can do.
https://connect.microsoft.com/IE/feedback/details/809823/draw-svg-image-on-canvas-context
Thank you.
I was also trying to access the IE bugtracker today but the site was failing with some server side error.
Looks like I need to wait for microsoft to fix it.
Good luck. :smile:
If anyone runs into this issue. The problem is that in IE11 the height and width are being set to 0. If you manually set them it works fine. For example:
var fimg = fabric.Image.fromURL(img.src, function(fimg) {
fimg.set('top',20).set('width',50).set('height',50).set('left',20);
myCanvas.add(fimg);
myCanvas.setActiveObject(fimg);
});
One way to manually get the dimensions is to load the svg via Ajax and then parsing the result string as an SVG, and read the width and height:
var r = new XMLHttpRequest();
r.open('GET', 'http://example.com/example.svg', true);
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) return;
var dimensionImgStr = r.responseText;
var parser = new DOMParser();
var dimensionImg = parser.parseFromString(dimensionImgStr, 'image/svg+xml');
img.set({
width: parseInt(dimensionImg.documentElement.getAttribute('width'), 10),
height: parseInt(dimensionImg.documentElement.getAttribute('height'), 10)
});
};
r.send();
Or with jQuery:
$.get('http://example.com/example.svg', function(dimensionImg) {
img.set({
width: parseInt(dimensionImg.documentElement.getAttribute('width'), 10),
height: parseInt(dimensionImg.documentElement.getAttribute('height'), 10)
});
}, 'xml');
Loading the image twice (once using fabric.Image.fromURL() and once using Ajax), shouldn't be much of a performance issue because of caching.
Loading the image using a more traditional method, i.e.:
var dimensionImg = new Image();
dimensionImg.addEventListener('load', function (e) {
var dimensionImg = this;
img.set({
width: dimensionImg.naturalWidth,
height: dimensionImg.naturalHeight
});
}, false);
dimensionImg.src = 'http://example.com/example.svg';
doesn't work because although the naturalWidth and naturalHeight properties ought to be available whether or not the image has actually been painted to the page, in IE11 they're not.
I was able to make it work with jquery ajax in IE 11.
Basically the issue was that IE 11 does not put the svg in the file.documentElement object.
$.ajax({
url: url,
dataType: "text",
type: "GET",
cache: true,
success: function (file) {
if (file.documentElement) {
resolve($j(file.documentElement).html());
} else {
// IE Bug
resolve(file);
}
},
error: reject,
});
Any more solutions to this without using ajax? Setting the height and width as @cannontechnology mention's does get the SVG to appear on the canvas but selections get messed up for me.
what is actuallly the problem?
@asturur Using fabric.Image.fromURL to add an SVG to the canvas does not work in IE11.
This doesn't seem to be a fabric problem, just a rendering problem with IE11 and SVGs on the canvas element.
Since posting I think I found a workaround - by following @cannontechnology's recommendation by passing width and height and then what I did myself was set a short timeout wrapped around the canvas.add(oImg); method.
For reference: why setTimeout(0) is sometimes useful: http://stackoverflow.com/a/779785
Most helpful comment
If anyone runs into this issue. The problem is that in IE11 the height and width are being set to 0. If you manually set them it works fine. For example:
var fimg = fabric.Image.fromURL(img.src, function(fimg) {
fimg.set('top',20).set('width',50).set('height',50).set('left',20);
myCanvas.add(fimg);
myCanvas.setActiveObject(fimg);
});