提问人:MigMit 提问时间:5/4/2023 更新时间:11/2/2023 访问量:83
带有 foreignObject 的 SVG 在用作图像 src 属性时具有不同的高度
SVG with foreignObject has a different height when used as an image src attribute
问:
我正在尝试拍摄现有元素的图像。首先,我将图像复制到 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>
左边的列表是原始列表,然后是我用于 SVG 的蓝图,然后是包含两个元素的 iframe:一个是 SVG 元素,里面有一个 foreignObject,显示相同的列表,另一个是 IMG 元素,它具有完全相同的 SVG,序列化,作为其源代码。出于某种原因,它们在 Chrome 中的渲染略有不同(在 Firefox 中很好)。
答:
0赞
MigMit
5/5/2023
#1
好吧,所以,似乎确实有一个解决方法。它在 Safari 中使事情陷入混乱,因此,我没有一个很好的跨平台代码,但问题是 HTML 的呈现方式略有不同,具体取决于 .对于图像,它始终为 1。但对于主要内容,它是 2(视网膜显示)。window.devicePixelRatio
解决方法是首先将 SVG 中的内容复制为此处的内容,但将该 SVG 包装在 DIV 中;然后根据克隆内容的实际 和 调整所有维度,然后才进行 XML 序列化和其余部分。zoom = 1/devicePixelRatio
offsetHeight
offsetWidth
评论