gpt4 book ai didi

html - 是否可以转义 SVG View 框? (或者如何将 HTML DIV 定位在缩放/转换后的 SVG 上?)

转载 作者:搜寻专家 更新时间:2023-10-31 08:30:28 24 4
gpt4 key购买 nike

在本文档中:

html, body {
height: 100%;
margin: 0;
padding: 0;
overflow: hidden
}
#content {
width: 100%;
height: 100%
}
<div id="content">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="90%" viewBox="0 0 1920 1080" preserveAspectRatio="xMidYMid meet">
<rect style="fill:none;stroke:black" width="540" height="157" x="690" y="26"></rect>
<text style="font-size:148px;text-align:center;text-anchor:middle;fill:black;stroke:none" x="960" y="145">Test</text>
<text style="font-size:112px;text-align:center;text-anchor:middle;fill:black;stroke:none" x="960" y="340">Lorem ipsum etc etc</text>
<foreignObject x="10" y="726" width="1901" height="347">
<div xmlns="http://www.w3.org/1999/xhtml" style="width:99.6%;height:97.7%;border:4px solid blue">
<p style="text-align:center">Hello World, from HTML inside SVG.</p>
</div>
</foreignObject>
</svg>
<div style="width:99%;border:4px solid blue">
<p style="text-align:center">Hello World, from HTML outside SVG.</p>
</div>
</div>

我正在使用 viewBox 重新缩放任意大小的 SVG,以便它填满浏览器窗口(通常 svg 上的 90% 高度是 100%;出于说明目的,我在此处将其缩小)。在该 SVG 中是一个包含一些要呈现的 HTML 的 foreignObject。

就目前而言,渲染的 HTML 输出也被重新缩放以适应 viewBox 坐标;请注意内部 svg 内容的边框宽度和文本大小与外部内容有何不同,并且在调整窗口大小时它会发生变化。

我想要 foreignObject 的位置和大小来定义内部 div 的边界框,但我不希望它实际重新缩放内容,只是为了重排它们。有办法做到这一点吗?

(顶部的文本也会随窗口重新缩放,但在这种情况下这是需要的。)

请注意,我无法移动或删除 viewBox。我可以将内部 div 放在 svg 之外并使用 JavaScript 调整它的大小,但我不知道如何将其边界框(但不是缩放)设置为它在内部时的位置.

(我不明白的一个不相关的事情是我必须将 div 的宽度/高度指定为小于 100%,否则它会裁剪内部和外部的边框。这可能只是 Chrome 的事情并不是很重要;我只是好奇。)


AmeliaBR's answer 之后

编辑 ,这是我想出的代码:

function svgTransform(x, y, matrix, svg) {
var p = svg.createSVGPoint();
p.x = x;
p.y = y;
return p.matrixTransform(matrix);
}

function svgScreenBounds(svgElement) {
var matrix = svgElement.getScreenCTM();
var r = svgElement.getBBox();
var leftTop = svgTransform(r.x, r.y, matrix, svgElement.ownerSVGElement);
var rightBottom = svgTransform(r.x + r.width, r.y + r.height, matrix, svgElement.ownerSVGElement);
return {
x: leftTop.x,
y: leftTop.y,
width: rightBottom.x - leftTop.x,
height: rightBottom.y - leftTop.y
};
}

function adjustOverlay() {
var placeholder = document.getElementById('placeholder');
var overlay = document.getElementById('overlay');
var bounds = svgScreenBounds(placeholder);
overlay.style.left = bounds.x + 'px';
overlay.style.top = bounds.y + 'px';
overlay.style.width = bounds.width + 'px';
overlay.style.height = bounds.height + 'px';
overlay.style.display = 'block';
}
html,body { height: 100%; margin: 0; padding: 0; overflow: hidden }
#content { width: 100%; height: 100% }
#overlay {
display: none;
position: absolute;
border:4px solid blue;
box-sizing: border-box;
}
<body onload="adjustOverlay()" onresize="adjustOverlay()">
<div id="content">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1920 1080" preserveAspectRatio="xMidYMid meet">
<rect style="fill:none;stroke:black" width="540" height="157" x="690" y="26"></rect>
<text style="font-size:148px;text-align:center;text-anchor:middle;fill:black;stroke:none" x="960" y="145">Test</text>
<text style="font-size:112px;text-align:center;text-anchor:middle;fill:black;stroke:none" x="960" y="340">Lorem ipsum etc etc</text>
<rect style="fill:yellow;stroke:black" width="1901" height="100" x="10" y="618" rx="20" ry="20"></rect>
<text style="font-size:64px;text-align:center;text-anchor:middle;fill:black;stroke:none" x="960" y="685">Bottom banner text</text>
<rect style="visibility:hidden" x="10" y="726" width="1901" height="347" id="placeholder"></rect>
</svg>
</div>
<div id="overlay">
<p style="text-align:center">Hello World, from HTML outside SVG.</p>
</div>
</body>

它的行为似乎符合预期。 (宽度小于 100% 的原因是因为我需要 box-sizing: border-box —— 我之前在 html 元素的样式上尝试过问这个问题,但它在那里没有效果;显然它需要直接应用而不是继承。)

最佳答案

很遗憾,您的问题的答案是“否”; viewBox 改变了整个坐标系,包括其所有子项的 px 或 pt 单位的定义。

<foreignObject>中的内容被渲染到屏幕缓冲区(临时图像),其宽度和高度与本地 SVG 坐标系中的 foreignObject 的宽度和高度相同,以像素为单位,然后将结果转换为适合屏幕,就像您在转换后的 SVG 坐标系中绘制(JPEG 或 PNG)图像。

如果可以选择使用 Javascript,获得可读文本和响应式图形的最佳解决方案是绝对定位 <div>元素叠加在 SVG 上。 This CodePen I put together about tooltips应该可以帮助您开始了解如何在 SVG 坐标系和页面坐标系之间进行转换。特别是,您需要阅读 SVGPoint对象和 getScreenCTM() 功能。

虽然需要做更多的工作,但这种方法也可以解决 foreignObject 的跨浏览器问题,这些问题在 IE 中根本不受支持,并且在其他浏览器中相当不稳定(例如,并不总是获得您需要的滚动条)。

关于html - 是否可以转义 SVG View 框? (或者如何将 HTML DIV 定位在缩放/转换后的 SVG 上?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26115053/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com