2

As part of a project of mine, I need to dynamically create a canvas and then draw an SVG file (also dynamically generated) in the canvas. For my project I need the canvas to cover the whole page and the SVG to fill the whole canvas. In the interest of browser comparability I set the SVG width and height to the canvas width and height respectively (to deal with this know Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=700533 as per this answer https://stackoverflow.com/a/28692538) yet the canvas is still blank in Firefox (works fine in Chrome, Safari, and Opera). I was wondering anyone could shed some light on this problem.

I made a fiddle with a demo (not my real SVG file but the same method and the same problem). Just to show the problem is not the the SVG if you copy it out of the alert and paste into a new Firefox tab it renders just fine. My Firefox version is 47.0 This should be the part of the code that is the most important.

img.onload = function () {
  ctx.scale(ratio, ratio);
  ctx.drawImage(img, 0, 0);
}

svg = "data:image/svg+xml,"+ "<svg xmlns='http://www.w3.org/2000/svg' width='"+canvas.width+"px' height='"+canvas.height+"px' viewBox='0,0,"+canvas.width+","+canvas.height+"' >" +
        "<style type='text/css'> * { margin: 0; padding: 0; } p{background-color:blue;}</style>"+
                  '<rect x="10" y="10" width="100" height="100"/>' +
               "</svg>"
img.src = svg

Full fiddle demo of the problem: https://jsfiddle.net/9are9tzx/5/ Thank you!

Community
  • 1
  • 1
zevnicsca
  • 543
  • 1
  • 3
  • 8

1 Answers1

3

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.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • Since you said that my demo worked for you I checked it again. Here is what I found out. The demo does not work in Firefox 47.0 (which is what I tested the demo and my project on) but the demo works just fine on Firefox 46.0.1 (I downgraded to test). What version did you use? Thank you for the advice about # anyway though, I will defiantly write a data:URI sanitizer before I publish my project. – zevnicsca Jun 09 '16 at 20:07
  • I just re-updated Firefox and restarted my computer and it works now for me (both the demo and my project). I did get FF 47.0 right after it came out so maybe the version I had was not stable or my first update was bad or something. Sorry about that! – zevnicsca Jun 09 '16 at 20:23
  • 1
    @zevnicsca, no need to write it yourself, `encodeURIComponent()` is already in your 'window' object. Also, some UAs need the encoding header so the only full cross-browser dataURI header is `'data:image/svg+xml; charset=utf8, '` – Kaiido Jun 10 '16 at 06:16