【问题标题】:Draw resized SVG image in HTML canvas in Firefox在 Firefox 的 HTML 画布中绘制调整大小的 SVG 图像
【发布时间】:2013-05-26 17:34:22
【问题描述】:

我想在 HTML 画布上绘制一个调整大小的 SVG 图像。

它在 Chromium 中运行良好,但在 Firefox 中却不行。在 Firefox 中,图像是像素化的。

这是 SVG 图像:

<?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>

这里是代码:

<!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>

结果是:

我想在 Firefox 中像在 Chromium 中一样,在没有像素化的情况下绘制调整大小的 SVG 图像。

目前,我将&lt;img/&gt;放在画布上以获得没有像素化的SVG图像,但是由于图像很多,所以速度很慢。

【问题讨论】:

  • 您是否考虑过仅使用本机画布 api 绘制圆:context.arc(x,y,radius,0,Math.PI*2,false)?许多 SVG 原始形状也可以在画布中使用——甚至路径也相当容易转换。
  • 这只是一个例子。我想绘制更复杂的 SVG 图像。
  • 这是一个很好的问题,它表明 Firefox 的 Gecko 渲染引擎会立即将 SVG 转换为位图,而 Webkit 将其保留为 SVG 并在需要时直接渲染。这就解释了为什么我的 20000 单位宽的 SVG 无法在 Firefox 中呈现,即使绘制为 400 像素宽。它在 webkit 上运行良好。

标签: firefox canvas svg


【解决方案1】:

我终于找到了一种在 Firefox 中在画布上绘制调整大小的 SVG 的方法。这个想法是通过 AJAX 获取 SVG 源并通过 JavaScript 更改 SVG,例如:

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);

这是一个jsFiddle(没有 AJAX,但很容易更改)。

由于修改和创建图像很慢,我添加了一个简单的缓存机制(小提琴中没有显示,但再次,它很容易实现),速度真的很快。

它可以在 Chromium、Firefox 和 Opera 中使用(但由于某种原因,小提琴在 Opera 中无法使用,尽管它可以在我的开发服务器中使用)。

P.S.:如果有 jQuery 替代 document.createElementNS,我想知道。

【讨论】:

猜你喜欢
  • 2019-01-03
  • 2017-06-12
  • 1970-01-01
  • 1970-01-01
  • 2012-06-26
  • 2018-06-27
  • 2012-08-27
  • 2017-06-02
相关资源
最近更新 更多