应用CSS后SVG文本的getBBox

qvtsj1bj  于 2023-03-09  发布在  其他
关注(0)|答案(1)|浏览(125)

我使用JavaScript将文本元素添加到SVG中,并使用以下CSS设置了文本元素的样式:

text {
    font: normal 15px sans-serif;
    fill: black;
    text-anchor: middle;
}

我的代码中有以下两行,记录文本元素的实际文本(txt)、文本元素的连接状态(label.isConnected)和文本元素的边界框(label.getBBox()):

console.log (txt, label.isConnected, label.getBBox());
setTimeout (function () {console.log (txt, label.isConnected, label.getBBox())}, 1000);

控制台输出如下信息:

Text true SVGRect { x: 0, y: 14, width: 28.08333396911621, height: 21 }
Text true SVGRect { x: -15.175000190734863, y: 16, width: 30.350000381469727, height: 18 }

在我看来,CSS修饰改变了边界框的位置和大小,但我不知道这是什么时候发生的,当然也不能随意等待。
在应用了CSS修饰的修改之后,如何获得文本元素的边界框?

3qpi33ja

3qpi33ja1#

我明白你的问题在哪里吗?
您希望在由异步加载的CSS文件强制执行的重画/重排完成后执行getBBox。
我使用onerror而不是onload,因为到CSS文件的链接现在是404
如果在setTimeout(或rAF)中调用getBBox,那么DOM的状态不正确吗?

<template id=MY-ELEMENT>
  <style onload='log("template style loaded")'>
  </style>
</template>
<my-element></my-element>
<script>
  function log() { console.log(...arguments) }
  customElements.define('my-element', class extends HTMLElement {
    constructor() {
      log('constructor');
      super().attachShadow({mode:'open'}).append(document.getElementById(this.nodeName).content.cloneNode(true));
      log('template appended');
    }
    connectedCallback() {
      log('connectedCallback');
      let link = document.createElement('link');
      link.setAttribute('rel', 'stylesheet');
      link.setAttribute('href', 'https://ceving.github.io/sociato/wf-graph.css');
      link.onerror = (evt) => {
        log('external CSS loaded');
        window.requestAnimationFrame(()=>log("rAF executed"));
        setTimeout(() => log('timeout after CSS load'))
      }
      this.shadowRoot.append(link);
      log('appended link');
    }
  });
</script>

相关问题