如何使用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
相关产品推荐
相关产品推荐

