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

如何在网页嵌入的SVG中使用自定义字体并动态编辑文本?

自定义字体在img嵌入SVG中失效&动态编辑SVG文本的解决方案

一、问题背景

网页已通过CSS的@font-face加载非预装的Omnes Pro字体,网页内文本显示正常:

@font-face {
    font-family: "Omnes Pro Bold";
    src: url("fonts/Omnes_Pro_Bold.otf") format("opentype");
}

但使用<img>标签嵌入包含该字体文本的SVG时,文本显示为默认字体,无法调用已加载的自定义字体。

同时需要通过JavaScript动态修改SVG中的文本元素,当前SVG是Inkscape创建的文件(而非内嵌<svg>标签),不确定常规方案是否适用,以下是SVG中的文本元素示例:

<text
   xml:space="preserve"
   style="font-size:22.5778px;line-height:0.9;font-family:'Omnes Pro';-inkscape-font-specification:'Omnes Pro';direction:rtl;fill:#000000;fill-opacity:1;stroke-width:0.545999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.4;stroke-dasharray:1.05833, 0.264583"
   x="71.448624"
   y="103.02882"
   id="text16-2-2"
   inkscape:label="Second"><tspan
     sodipodi:role="line"
     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.87778px;font-family:'Omnes Pro';-inkscape-font-specification:'Omnes Pro, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:end;direction:ltr;text-anchor:end;stroke-width:0.546"
     x="73.127846"
     y="103.02882"
     id="tspan17-4-3">Second </tspan></text>

已知将文本转为路径的方案不可行(无法动态编辑),核心需求是实现带动态文本的图片,若有更优方案也请告知。


解决方案

1. 解决SVG字体加载问题(img嵌入场景)

用<img>加载SVG时,SVG处于独立文档上下文,无法访问主页面的CSS和字体资源,可通过以下两种方式解决:

  • 方案一:在SVG内部嵌入字体规则
    打开SVG文件,在<defs>标签内添加字体加载代码(无<defs>则新建):

    <defs>
      <style type="text/css">
        @font-face {
          font-family: "Omnes Pro Bold";
          src: url("fonts/Omnes_Pro_Bold.otf") format("opentype");
        }
        @font-face {
          font-family: "Omnes Pro";
          src: url("fonts/Omnes_Pro.otf") format("opentype");
        }
      </style>
    </defs>
    

    注意:字体文件路径需相对于SVG文件位置,确保路径正确。

  • 方案二:将SVG内嵌到页面
    把SVG文件内容直接复制到HTML中作为<svg>标签,这样SVG可共享主页面的CSS和字体资源,同时方便后续JS编辑。

2. 动态编辑SVG文本的实现

  • 内嵌SVG场景
    直接通过JS选中目标元素修改文本:

    // 修改tspan文本内容
    document.getElementById('tspan17-4-3').textContent = '新的文本内容';
    // 如需修改样式,直接操作style属性
    document.getElementById('text16-2-2').style.fontFamily = 'Omnes Pro Bold';
    
  • img加载SVG场景
    通过AJAX获取SVG内容,修改后转为Data URL赋值给img的src:

    fetch('your-svg-file.svg')
      .then(response => response.text())
      .then(svgText => {
        // 替换目标文本
        const updatedSvg = svgText.replace('Second ', '新文本内容');
        // 转为Data URL
        const dataUrl = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(updatedSvg);
        // 更新img标签
        document.getElementById('your-img-id').src = dataUrl;
      });
    

    此方式需确保SVG内部已嵌入字体规则,否则修改后的文本仍会显示默认字体。

3. 替代方案:Canvas绘制

若SVG方案存在局限,可使用Canvas实现带动态文本的图片:

  • 利用主页面加载的自定义字体,在Canvas中设置字体并绘制文本
  • 可随时通过JS修改文本内容后重新绘制
  • 最终可将Canvas转为PNG等图片格式展示

示例代码:

<canvas id="dynamic-canvas" width="200" height="100"></canvas>
<script>
  const canvas = document.getElementById('dynamic-canvas');
  const ctx = canvas.getContext('2d');

  // 确保字体加载完成后绘制
  document.fonts.ready.then(() => {
    ctx.font = '9.87778px "Omnes Pro"';
    ctx.fillStyle = '#000';
    ctx.textAlign = 'end';
    ctx.fillText('动态文本内容', 73.127846, 103.02882);
  });

  // 动态更新文本的函数
  function updateText(newText) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillText(newText, 73.127846, 103.02882);
  }
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:00:16