【问题标题】:Scaling canvas on Firefox doesn't effect SVG images在 Firefox 上缩放画布不会影响 SVG 图像
【发布时间】:2018-10-13 02:41:06
【问题描述】:

Firefox 不支持 SVG 图像的 2D 画布转换,但它支持 PNG 图片。

以下代码 sn-p 创建两个带有 2D 绘图上下文的 HTML 画布。对它们都应用了简单的缩放变换,然后在上面的一个上绘制一个 20px 大小的方形 PNG 图像,在下一个上绘制一个相同尺寸的 SVG。

在我的 Chromium (v65.0.3325.162) 上,图像按预期放大。但是,在 Firefox (v58.0.2) 上,底部的画布(带有 SVG 的画布)没有缩放,这与带有 PNG 源图像的画布不同。

function createPng(xSize, ySize) {
  var canvas = document.createElement("canvas");
  canvas.width = 20;
  canvas.height = 20;
  var ctx = canvas.getContext("2d")
  ctx.fillStyle = "000000";
  ctx.fillRect(0, 0, xSize, ySize);
  
  var img = new Image()
  prom = new Promise(function(resolve, reject) {
    img.onload = function() {resolve(img)}
    img.onerror = function(err) {reject(err)}
  })
  img.src = canvas.toDataURL("image/png");
  return prom
}

function createSvg() {
  var img = new Image()
  var prom = new Promise(function(resolve, reject) {
    img.onload = function() {resolve(img)}
    img.onerror = function(err) {reject(err)}
  })
  img.src =  "https://cdn.rawgit.com/AttilaVM/4e0987aae8bc37b2067fbde591088758/raw/95dcffd67b37540d739f4bd5f33f6bead625a90f/test.svg"
  return prom
}

var containerPng = document.getElementById("container-png")
var canvasPng = document.createElement("canvas")

canvasPng.width = containerPng.clientWidth;
canvasPng.height = containerPng.clientHeight;

containerPng.appendChild(canvasPng);

var ctxPng = canvasPng.getContext("2d");

createPng(20, 20)
.then(function(img) {
  ctxPng.scale(5, 1); 
  ctxPng.drawImage(img, 0, 0)
})
.catch(function(err) {console.error(err)});

var containerSvg = document.getElementById("container-svg")
var canvasSvg = document.createElement("canvas")

canvasSvg.width = containerSvg.clientWidth;
canvasSvg.height = containerSvg.clientHeight;

containerSvg.appendChild(canvasSvg);
var ctxSvg = canvasSvg.getContext("2d");

createSvg()
.then(function(img) {
  ctxSvg.scale(5, 1); 
  ctxSvg.drawImage(img, 0, 0)
})
.catch(function(err) {console.error(err)});
.container {
  position: relative;
  margin: 15px 0 0 0;
  width: 100%;
  height: 20px;
  background-color: #aaaaaa
}

.container > canvas {
  position: absolute;
  top: 0;
  left: 0;
}
<div id="container-png" class="container"></div>
<div id="container-svg" class="container"></div>

截图

铬:

火狐:

问题:

编写代码以在 HTML 画布上绘制缩放的 SVG 图像的最佳方法是什么,在 Firefox 和 Chromium 上给出相同的结果?

【问题讨论】:

    标签: javascript firefox cross-browser html5-canvas


    【解决方案1】:

    这实际上不是一个错误。在您的原始 svg 中,缺少 preserveAspectRatio 属性。这意味着使用默认值XMidYMid。如果 svg 的 viewBox 纵横比 与目标 viewPort 的纵横比(您的图像)不匹配,则会产生问题。要关闭此功能,您需要将 preserveAspectRatio="none" 添加到您的 svg。我去了 svg 的源代码,添加了 preserveAspectRatio="none" 属性,然后这样做了:

    var x = "data:image/svg+xml;base64,"+ btoa(ser.serializeToString(document.querySelector("svg")))
    

    上面的ser 是一个XMLSerializer 实例。这会给我一个我可以使用的数据 url:

    "data:image/svg+xml;base64,PHN2ZyB4bWxuczpvc2I9Imh0dHA6Ly93d3cub3BlbnN3YXRjaGJvb2sub3JnL3VyaS8yMDA5L29zYiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmlld0JveD0iMCAwIDI2LjQ1OCAyNi40NTgiIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PGRlZnM+PGxpbmVhckdyYWRpZW50IG9zYjpwYWludD0iZ3JhZGllbnQiIGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlMjVlNWUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMxMjkwMzMiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCB5Mj0iMjk1LjQ4MiIgeDI9IjEyLjYxNCIgeTE9IjI3Mi4xNjQiIHgxPSIxMi4xOSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxLjExMzQ3IDAgMCAxLjExMzQ3IC0xLjUwMSAtMzIuMTk4KSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGlkPSJiIiB4bGluazpocmVmPSIjYSIvPjwvZGVmcz48cGF0aCBmaWxsPSJ1cmwoI2IpIiBkPSJNMCAyNzAuNTQyaDI2LjQ1OFYyOTdIMHoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTI3MC41NDIpIi8+PC9zdmc+"
    

    接下来,我创建了一个小提琴并修改了这些:

    function createSvg() {
      var img = new Image()
      var prom = new Promise(function(resolve, reject) {
        img.onload = function() {resolve(img)}
        img.onerror = function(err) {reject(err)}
      })
      img.src =  "data:image/svg+xml;base64,PHN2ZyB4bWxuczpvc2I9Imh0dHA6Ly93d3cub3BlbnN3YXRjaGJvb2sub3JnL3VyaS8yMDA5L29zYiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmlld0JveD0iMCAwIDI2LjQ1OCAyNi40NTgiIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PGRlZnM+PGxpbmVhckdyYWRpZW50IG9zYjpwYWludD0iZ3JhZGllbnQiIGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlMjVlNWUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMxMjkwMzMiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCB5Mj0iMjk1LjQ4MiIgeDI9IjEyLjYxNCIgeTE9IjI3Mi4xNjQiIHgxPSIxMi4xOSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxLjExMzQ3IDAgMCAxLjExMzQ3IC0xLjUwMSAtMzIuMTk4KSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGlkPSJiIiB4bGluazpocmVmPSIjYSIvPjwvZGVmcz48cGF0aCBmaWxsPSJ1cmwoI2IpIiBkPSJNMCAyNzAuNTQyaDI2LjQ1OFYyOTdIMHoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTI3MC41NDIpIi8+PC9zdmc+";
      return prom
    }
    

    在此处查看小提琴:

    https://fiddle.jshell.net/ibowankenobi/4ntq2qLz/1/

    似乎它解决了我正在测试的Firefox浏览器中的问题。

    【讨论】:

    • 谢谢。我将您的建议应用于我的原始代码,现在它也适用于 Firefox。
    猜你喜欢
    • 2014-10-08
    • 2013-11-27
    • 1970-01-01
    • 2021-08-29
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    相关资源
    最近更新 更多