You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用svgwrite实现文本沿路径居中对齐?

实现SVG文本沿路径居中显示(基于svgwrite)

svgwrite确实没有内置文本沿路径居中的直接功能,不过可以通过计算路径总长度与文本长度的差值,手动设置textPath的startOffset属性来实现。以下是两种实用方案:

方案1:浏览器端动态计算(适合交互式SVG)

这种方式利用浏览器的SVG API在页面加载时自动计算并调整偏移量,无需提前预估长度,精度最高:

import svgwrite

dwg = svgwrite.Drawing('text_center_on_path.svg', profile='full')

# 创建目标路径
path = dwg.path(d="M100,200 C200,100 300,300 400,200", fill="none", stroke="#333")
dwg.add(path)

# 创建文本容器与textPath(初始偏移设为0)
text_element = dwg.text("", insert=(0, 0), font_size="16px", font_family="Arial")
text_path = dwg.textPath(path, "沿路径居中的示例文本", startOffset="0")
text_element.add(text_path)
dwg.add(text_element)

# 添加JS脚本,加载时自动计算偏移量
dwg.add(dwg.script(content="""
window.addEventListener('load', () => {
  const path = document.querySelector('path');
  const textPath = document.querySelector('textPath');
  const textEl = textPath.parentElement;
  
  const totalPathLength = path.getTotalLength();
  const textLength = textEl.getComputedTextLength();
  const centerOffset = (totalPathLength - textLength) / 2;
  
  textPath.setAttribute('startOffset', centerOffset);
});
"""))

dwg.save()

原理说明

  • path.getTotalLength():获取路径的实际渲染长度
  • textEl.getComputedTextLength():获取文本的实际渲染宽度
  • 两者差值的一半就是让文本居中的起始偏移量,直接赋值给textPath的startOffset即可

方案2:静态预计算(适合生成无脚本SVG)

如果需要生成纯静态SVG(不依赖客户端JS),可以用第三方库提前计算路径和文本长度:

步骤1:安装依赖

pip install svgpathtools fonttools

步骤2:代码实现

import svgwrite
from svgpathtools import parse_path
from fontTools.ttLib import TTFont

def calculate_text_width(text, font_path, font_size):
    # 加载字体文件,计算文本的实际宽度
    font = TTFont(font_path)
    glyf_table = font['glyf']
    hmtx_table = font['hmtx']
    total_width = 0
    
    for char in text:
        glyph_name = font.getBestCmap()[ord(char)]
        width = hmtx_table[glyph_name][0]
        total_width += width
    
    # 转换为实际像素宽度(字体单位转px)
    return (total_width / font['head'].unitsPerEm) * font_size

dwg = svgwrite.Drawing('static_text_center.svg', profile='full')

# 定义路径
path_d = "M100,200 C200,100 300,300 400,200"
path = dwg.path(d=path_d, fill="none", stroke="#333")
dwg.add(path)

# 计算路径总长度
svg_path = parse_path(path_d)
path_length = svg_path.length()

# 计算文本宽度(替换为你的字体路径和文本内容)
text_content = "静态居中的路径文本"
font_path = "Arial.ttf"  # 本地字体文件路径
text_width = calculate_text_width(text_content, font_path, 16)

# 计算居中偏移量
center_offset = (path_length - text_width) / 2

# 创建文本与textPath
text_element = dwg.text("", insert=(0,0), font_size="16px", font_family="Arial")
text_path = dwg.textPath(path, text_content, startOffset=str(center_offset))
text_element.add(text_path)
dwg.add(text_element)

dwg.save()

注意事项

  • 字体路径需要指向本地存在的字体文件,确保计算的宽度与实际渲染一致
  • 如果使用系统字体,可通过系统工具(如Linux的fc-list)查找字体路径

内容的提问来源于stack exchange,提问作者Zain Rizvi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:50:31