getComputedStyle и getBoundingClientRect - PullRequest
0 голосов
/ 16 марта 2019

У меня есть текст 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 голосов
/ 16 марта 2019

Вы можете получить матрицу преобразования , которая преобразуется из локальной системы координат, в которой определен текст, в область просмотра, в которую визуализируется SVG (в вашем случае это будет тег <object>). ).

Хотя преобразование SVG в целом для его соответствия размеру элемента <object> представляет собой простую шкалу (в большинстве случаев равномерную), другие преобразования могли происходить внутри SVG: она могла быть неравномерно масштабирована или повернут, или перекошен. Это все будет отражено в содержании матрицы, и это усложнит ее интерпретацию. Приведенный ниже пример кода обрабатывает только самый простой случай и предполагает, что значение свойства ctm.d является представлением равномерного масштабирования, примененного к размеру шрифта.

Подробнее о математической интерпретации матриц здесь .

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);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...