SVG text 自动换行算法_svg text超出换行

最近做的项目涉及到 web 绘图,采用 d3 操作 svg 实现。图中通常会用到文本,而 svg 里的 text 元素不像普通 DOM 元素那样能很好地处理文本换行,所以要用到一些技巧。

通常有两种做法。

1.用 tspan 把 text 拆成多行,重新计算每个tspan 的 y 坐标。

<svg xmlns="http://www.w3.org/2000/svg">
  <text font-size="14">
    <tspan x="0" y="10">较长文文本一行</tspan>
    <tspan x="0" y="28">放不下就换行</tspan>
  </text>
</svg>

2.用 foreignObject 包裹 DOM 元素,利用 DOM 的文本布局能力自动处理换行。

<svg xmlns="http://www.w3.org/2000/svg">
  <foreignObject width="120" height="50">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p style="font-size:14px;margin:0;">较长文文本一行放不下就换行</p>
      </body>
    </foreignObject>
</svg>

两种方法各有千秋,方法1可以精确控制换行位置,但是需要计算具体的坐标。方法2无需计算内部坐标,但它是根据单词来分割的,针对长英文单词也无能为力。

笔者碰到的就是单个长英文单词也要换行显示,所以只能用方法1。产品需求是文本根据屏幕大小自动适配,如果宽度不够就换行显示。效果如下图所示:

Outperformance 这个单词被截断。原理就是先在 text 元素下插入一个tspan,将单词里的字母逐个填进去,判断元素宽度是否达到限制。如果超过限制就再插入一个 tspan,同时计算新 tspany坐标。由于事先知道 text的具体位置,x保持一致就可以了。代码如下:

function wrapWord(text, width) {
  text.each(function() {
    var text = d3.select(this),
      words = text.text().split('').reverse(),
      word,
      line = [],
      lineNumber = 0,
      lineHeight = text.node().getBoundingClientRect().height,
      x = +text.attr('x'),
      y = +text.attr('y'),
      tspan = text.text(null).append('tspan').attr('x', x).attr('y', y);
    while (word = words.pop()) {
      line.push(word);
      const dash = lineNumber > 0 ? '-' : '';
      tspan.text(dash + line.join(''));
      if (tspan.node().getComputedTextLength() > width) {
        line.pop();
        tspan.text(line.join(''));
        line = [word];
        tspan = text.append('tspan').attr('x', x).attr('y', ++lineNumber * lineHeight + y).text(word);
      }
    }
  });
}

div或者p标签单行和多行超出显示省略号

❤️ 谢谢支持

喜欢的话别忘了 关注、点赞哦~。

前端校招面试题精编解析大全

❤️ 谢谢支持

喜欢的话别忘了 关注、点赞哦~。

[外链图片转存中…(img-0Jg62HXk-1718718537686)]

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值