0

我有包含文本的 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 文档中并非如此。当然我可能会介绍一个透明的水平示例文本。

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

4

1 回答 1

0

You can get at the transform matrix that transforms from the local coordinate system the text is defined in to that of the viewport the SVG is rendered into (which would be the <object> tag in your case).

While the transformation of the SVG as a whole to fit it into the size of the <object> element is a simple scale (in most cases uniform), other transformations could have happened inside the SVG: it could have been scaled unevenly, or rotated, or skewed. That all would be mirrored in the content of the matrix, and it makes its interpretation complicated. The below code example handles only the most simple case and assumes the value of the ctm.d property is a representation of an even scaling applied to the font size.

Read more about the mathematical interpretation of matrices 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);
    }
于 2019-03-16T14:16:53.077 回答