getComputedStyle和getBoundingClientRect

时间:2019-03-16 09:25:00

标签: svg responsive getboundingclientrect getcomputedstyle

我有HTML文本和SVG文档,其中包含作为外部对象包含的文本。我想保持HTML文本的大小和SVG文档中的文本大小相同。

<!DOCTYPE html>
<html lang="de">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>getComputedStyle</title>
</head>

<body>
    <h3 id="headerId">Header</h3>
    <object onload="svgLoaded()" id="sampleSVG" data="sample.svg" 
        type="image/svg+xml" width="80%"></object>
    <script>
        let element = document.getElementById("headerId");
        console.log(window.getComputedStyle(element)
            .getPropertyValue("font-size"));
        console.log(element.getBoundingClientRect().height);
        var svgLoaded = function () {
            svgObject = document.getElementById("sampleSVG");
            var svgObjectIntern = svgObject.contentDocument;
            var textElement = 
               svgObjectIntern.getElementsByTagName('text');
            for (var i = 0; i < textElement.length; i++) {
                let selectedText = textElement[i];
                console.log(window
                    .getComputedStyle(selectedText)
                    .getPropertyValue("font-size"));
                console.log(selectedText.getBoundingClientRect().height);
            }
        }
    </script>
</body>
</html>

修改SVG文档中的文本大小很好用(我正在使用d3.js),但是第一步,我需要用户看到的文本大小。 如果我调整浏览器窗口的大小或更改SVG对象的“宽度”,则HTML文本大小将保持不变,而SVG内部的文本大小将按比例更改。

要测量用户看到的文本大小,我尝试了“ getComputedStyle”和“ getBoundingClientRect”。 getBoundingClientRect可以正常工作,但是getComputedStyle总是告诉我SVG文档中定义的文本大小,而与任何缩放无关。

原则上,我可以使用“ getBoundingClientRect”。唯一的缺点是,这总是需要在SVG内部使用水平文本元素,而在我的所有SVG文档中却并非如此。当然,我可能会介绍透明的水平示例文本。

我有种感觉,那不是很聪明。也许有更好的解决方案。

1 个答案:

答案 0 :(得分:0)

您可以找到transform matrix,它将从定义文本的本地坐标系转换为SVG渲染到的视口(在您的情况下为<object>标签)

虽然将SVG整体进行转换以使其适合<object>元素的大小只是一个简单的标度(在大多数情况下是统一的),但SVG内部可能发生了其他转换:缩放不均匀,旋转或倾斜。所有这些都将反映在矩阵的内容中,这会使解释变得复杂。下面的代码示例仅处理最简单的情况,并假设ctm.d属性的值表示应用于字体大小的均匀缩放。

了解有关矩阵here的数学解释的更多信息。

var svgLoaded = function () {
    svgObject = document.getElementById("sampleSVG");
    var svgObjectIntern = svgObject.contentDocument;
    var textElement = svgObjectIntern.getElementsByTagName('text');
    for (var i = 0; i < textElement.length; i++) {
        var selectedText = textElement[i];
        var fontsize = window
            .getComputedStyle(selectedText)
            .getPropertyValue("font-size"));
        var ctm = selectedText.getScreenCTM();
        console.log(parseFloat(fontsize) * ctm.d);
    }