`getBBox()`为相同的DOM

时间:2018-05-18 10:55:38

标签: javascript html css svg

我有一些代码在SVG中应用文本换行,只使用一个<text>元素,并在其中创建多个<tspan>元素。

使用此我遇到问题,因为我认为相同的2个元素调用getBBox()会返回不同的结果,因此会在2个圆圈中创建不同的包装效果。

这是一个截图,提供了一些背景信息。这通常是在一些重叠的动画中,但为了演示目的,我将其分开。我有一些DOM,我期望两个文本项以相同的方式包装:

enter image description here

我已将问题跟踪到代码的特定部分,紧随其后。一个小解释textNode代表一个<tspan>,它修改了单词,在添加每个单词后,使用一个名为getScaledBBox()的函数测量文本。如果超出宽度,则会在下方添加新的<tspan>并重复该过程。

// Go through each word to be text wrapped except the first one
(let i = 0; i < len; i++) {
     word = wordsToWrap[i];

     // If our text goes outside the height boundary, 
     // remove lines until suitable and add an ellipsis through truncate()
     if (getScaledBBox(textNode).height > height) {
         truncate();
         break;

         // Otherwise check if our text goes outside the width boundary. 
         // If so, create an ellipsis
      } else if (getScaledBBox(textNode).width > width) {
         ellipsis();
         break;
      }

      // Debug logging
     console.log("words", textNode.innerHTML, getScaledBBox(textNode), textNode.getBBox());

     let node = textNode;
     while(Array.from(node.classList).indexOf("planet-group") === -1) {
          node = node.parentNode;
     }
     console.log("html", node.parentNode.innerHTML);
 }

 placeWord(word);
} 

我遇到的一个特殊问题是getScaledBBox()正在返回不同的值,而<tspan>的操作看起来与我所说的相同。

export const getScaledBBox = (node) => {
    const devicePixelRatio = window ? window.devicePixelRatio || 1 : 1;
    const boundingBox = node.getBBox();
    const height = boundingBox.height / devicePixelRatio;
    const width = boundingBox.width / devicePixelRatio;
    return { height, width };
};

这是我的控制台记录的一些输出(请注意,widthheight分别定义为280,140)。适用于第一次(黑色)运行:

<tspan x="-140px" dx="140px" dy="44px" dominant-baseline="alphabetic" style="baseline-shift: 0%;">TH</tspan> {height: 48, width: 52.38125}   
<tspan x="-140px" dx="140px" dy="44px" dominant-baseline="alphabetic" style="baseline-shift: 0%;">TH test</tspan> {height: 48, width: 130.23125} 
<tspan x="-140px" dx="140px" dy="44px" dominant-baseline="alphabetic" style="baseline-shift: 0%;">TH test save</tspan> {height: 48, width: 222.5375} 

对于第二个(橙色)圈子,我得到:

<tspan x="-140px" dx="140px" dy="44px" dominant-baseline="alphabetic" style="baseline-shift: 0%;">TH</tspan> {height: 19.7875, width:
20.94375}
<tspan x="-140px" dx="140px" dy="44px" dominant-baseline="alphabetic" style="baseline-shift: 0%;">TH test</tspan> {height: 19.7875, width: 52.35}  
<tspan x="-140px" dx="140px" dy="44px" dominant-baseline="alphabetic" style="baseline-shift: 0%;">TH test save</tspan> {height: 19.7875, width: 89.3125}

从最后的日志记录中可以看出,值完全不同。有趣的是它们恰好是2.5输出的因子,这是window.devicePixelRatio的值,但是getScaledBBox()已经考虑到这一点,并且两个跨度的代码路径相同。

我还记录了HTML以查看是否有任何不同,因为其中一个的包装代码在另一个之后运行大约500毫秒,因为特别引入了延迟。这会产生:

在第一个单词之后,这是工作黑圈的DOM enter image description here

在第一个单词之后,这是失败的橙色圆圈的DOM enter image description here

任何人都可以看到我可能缺少的东西,这可能会导致边界计算错误吗?不幸的是,我还没有成功进行独立复制。

0 个答案:

没有答案