【问题标题】:Ready event of SVG text elementSVG 文本元素的就绪事件
【发布时间】:2019-12-21 12:54:09
【问题描述】:

有没有办法知道SVG文本元素已经完成了页面上的所有渲染步骤?

例如,将文本设置为不同的字体系列时,文本首先更改其大小,然后将其外观更改为新字体, 然后它再次改变它的大小(它甚至发生了几次),然后它变得更清晰。

这些步骤在不同的浏览器中有所不同,并且取决于许多过程,例如,字体回退和加载新字体文件。

在不知情的情况下,当文本元素完成准备后,无法获得文本元素的实际尺寸(宽度和高度),因为浏览器可以随时调整它们以获得更好的外观或其他东西别的。如果没有这个事件,就无法在基于 SVG 的在线编辑器中正常处理文本。

我必须做一个长计时器,希望在它被触发时文本已经准备好。但是在文本元素很多的情况下,这太长了,如果我们需要串联设置它们的参数,并且在下一步之前有之前的文本大小结果。

【问题讨论】:

    标签: javascript html svg dom-events


    【解决方案1】:

    您的问题归结为能够知道特定 FontFace 何时加载。

    为此,您可以使用FontFace API

    对于在 CSS 中声明并在页面加载时直接使用的字体,Document 公开了一个 fonts.ready 属性,这是一个 Promise,当 DOMContentLoaded 中使用的所有字体都准备好时,该属性将得到解决:

    // only for demo (avoids cache)
    const style = document.createElement('style');
    style.textContent = `@font-face {
      font-family: 'Shadows Into Light';
      src: url("https://fonts.gstatic.com/s/shadowsintolight/v7/UqyNK9UOIntux_czAvDQx_ZcHqZXBNQzdcD55TecYQ.woff2?t=${ Math.random()}") format('woff2');
    }`;
    document.head.append(style);
    // end only for demo
    
    const text = document.querySelector('text');
    console.log('before', text.getComputedTextLength());
    
    document.fonts.ready.then(() => {
      console.log('after', text.getComputedTextLength());
    });
    text {
      font-family: 'Shadows Into Light', monospace;
      font-size: 30px;
    }
    <svg>
      <text y="60">Hello world</text>
    </svg>

    如果您希望在页面加载后添加字体,则可以使用document.fonts.load 方法:

    const text = document.querySelector('text');
    document.fonts.ready.then(() => {
      console.log('font.ready fires too soon');
    });
    
    document.addEventListener('click', e => {
      document.fonts.load("30px 'Shadows Into Light'")
        .then(() => {
          console.log('at font load', text.getComputedTextLength());
        });
      text.classList.add('use-font');
      console.log('before', text.getComputedTextLength());
    }, {once: true});
    @font-face {
      font-family: 'Shadows Into Light';
      src: url("https://fonts.gstatic.com/s/shadowsintolight/v7/UqyNK9UOIntux_czAvDQx_ZcHqZXBNQzdcD55TecYQ.woff2") format('woff2');
    }
    text.use-font {
      font-family: 'Shadows Into Light';
    }
    text { font-size: 30px; }
    <svg>
      <text y="60">Click to change the font</text>
    </svg>

    【讨论】:

    • 非常感谢!只有在加载新字体时,文本才会真正多次更改其大小。字体加载完毕后,没有大小变化,只是切换到这个字体。
    猜你喜欢
    • 2016-08-22
    • 2016-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    相关资源
    最近更新 更多