Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw resized SVG image in HTML canvas in Firefox

I want to draw a resized SVG image to a HTML canvas.

It works fine in Chromium, but not in Firefox. In Firefox, the image is pixelated.

Here is the SVG image:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200" viewbox="0 0 200 200">
  <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
</svg>

And here is the code:

<!DOCTYPE html>
<html>
    <head>
        <title>Resized SVG in Canvas</title>
        <meta charset="utf-8"/>

        <script>
        window.addEventListener('load', function() {
            var canvas = document.getElementById('canvas'),
                context = canvas.getContext('2d'),
                image = new Image();
            image.src = 'circle1.svg';
            image.height = 400;
            image.width = 400;

            image.addEventListener('load', function() {
                try {
                    context.drawImage(image, 0, 0, 400, 400);
                }
                catch(error) {
                    console.log(error);
                }
            }, false);
        }, false);
        </script>
    </head>
    <body>
        <canvas height="600" id="canvas" width="600"></canvas>
    </body>
</html>

The result is:

enter image description here

I would like to have the resized SVG image drawn without pixelation in Firefox, as in Chromium.

Currently, I put <img/> on top on the canvas to get SVG image without pixelation, but it is quite slow because there are a lot of images.

like image 414
antoyo Avatar asked May 31 '13 00:05

antoyo


1 Answers

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.

like image 174
antoyo Avatar answered Oct 16 '22 07:10

antoyo