javascript 具有foreignObject的SVG在用作图像src属性时具有不同的高度

ogq8wdun  于 2023-05-05  发布在  Java
关注(0)|答案(1)|浏览(167)

我正在尝试拍摄现有元素的图像。首先,我将图像复制到SVG元素中的foreignObject,然后序列化它并将其用作“数据”图像源。但由于某种原因,在Chrome中,我看到元素呈现的方式有点不同。有没有人知道为什么会这样,以及可以做些什么来纠正它?
我的HTML是这样的:

<!DOCTYPE html>
<html>

<head>
  <style>
    html,
    body {
      margin: 0
    }

    .x {
      border: 1px solid black;
      float: left;
      width: 100.3px;
    }

  </style>
  <script>
    function test() {
      let x = document.getElementById('xx')
      let i = document.getElementById('if')
      i.contentDocument.body.appendChild(document.getElementById('sv').cloneNode(true))
      let c = i.contentDocument
      let s = c.getElementById('sv')
      let t = c.getElementById('st')
      let f = c.getElementById('fo')
      i.width = x.offsetWidth * 2
      i.height = x.offsetHeight
      s.viewBox.baseVal.width = x.offsetWidth
      s.viewBox.baseVal.height = x.offsetHeight
      s.width.baseVal.value = x.offsetWidth
      s.height.baseVal.value = x.offsetHeight
      f.width.baseVal.value = x.offsetWidth
      f.height.baseVal.value = x.offsetHeight
      t.textContent = document.getElementsByTagName('STYLE')[0].textContent
      f.appendChild(x.cloneNode(true))
      d = new XMLSerializer().serializeToString(s)
      g = c.createElement('IMG')
      g.width = x.offsetWidth
      g.height = x.offsetHeight
      g.src = 'data:image/svg+xml,' + encodeURIComponent(d)
      c.body.appendChild(g)
    }
  </script>
</head>

<body onclick="test()">
  <div class="x" id="xx">
    <ul>
      <li>a</li>
      <li>b</li>
      <li>c</li>
      <li>d</li>
      <li>e</li>
    </ul>
  </div>
  <svg xmlns="http://www.w3.org/2000/svg" id="sv" viewBox="0 0 100 100" width="100px" height="100px">
    <style id="st"></style>
    <foreignObject id="fo" width="100px" height="100px" style="background:lightgray"></foreignObject>
  </svg>
  <iframe id="if"></iframe>
</body>

</html>

以下是结果(点击body中的某个位置后):

左边的列表是原始的,然后是我用于SVG的蓝图,然后是包含两个元素的iframe:一个是SVG元素,内部有一个foreignObject,显示相同的列表,另一个是IMG元素,它具有相同的SVG,序列化,作为其源。由于某种原因,它们在Chrome中的呈现方式略有不同(在Firefox中没有问题)。

bz4sfanl

bz4sfanl1#

好吧,看来确实有一个变通办法。它会在Safari中造成混乱,因此,我没有很好的跨平台代码,但问题是HTML的呈现方式会因window.devicePixelRatio而有所不同。对于图像,它始终为1。但对于主要内容,它是2(视网膜显示)。
解决方法是首先复制SVG中的内容,就像这里一样,但是用zoom = 1/devicePixelRatio将SVG Package 在DIV中;然后根据克隆内容的实际offsetHeightoffsetWidth调整所有维度,然后才执行XML序列化和其他操作。

相关问题