我有一些代码在SVG中应用文本换行,只使用一个<text>
元素,并在其中创建多个<tspan>
元素。
使用此我遇到问题,因为我认为相同的2个元素调用getBBox()
会返回不同的结果,因此会在2个圆圈中创建不同的包装效果。
这是一个截图,提供了一些背景信息。这通常是在一些重叠的动画中,但为了演示目的,我将其分开。我有一些DOM,我期望两个文本项以相同的方式包装:
我已将问题跟踪到代码的特定部分,紧随其后。一个小解释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 };
};
这是我的控制台记录的一些输出(请注意,width
和height
分别定义为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毫秒,因为特别引入了延迟。这会产生:
任何人都可以看到我可能缺少的东西,这可能会导致边界计算错误吗?不幸的是,我还没有成功进行独立复制。