【问题标题】:HTML 5 draw curved text on a imageHTML 5 在图像上绘制弯曲文本
【发布时间】:2015-01-16 20:34:14
【问题描述】:

我们如何在图像上的特定位置绘制弯曲的文本,如下所示。

【问题讨论】:

标签: html svg html5-canvas


【解决方案1】:

您可以使用<textPath> SVG 元素在路径上绘制文本。这可能有点繁琐,但我会引导你完成它。

首先,您需要创建一个<defs> 部分,其中包含您希望文本遵循的路径。如果您可以只使用<circle> 元素,事情会变得更容易,但这不起作用;它必须是 <path> 元素。幸运的是,SVG 的路径绘制确实支持circular arcs,因此无需为贝塞尔曲线而烦恼。

这里我定义了两个以 (0,0) 为中心、半径为 120 的半圆弧; cp1 顺时针越过顶部,cp2 逆时针绕底部:

  <defs>
    <path id="cp1" d="M-120 0A120 120 0 0 1 120 0" fill="none" stroke="red" />
    <path id="cp2" d="M-120 0A120 120 0 0 0 120 0" fill="none" stroke="red" />
  </defs>

SVG 的实际绘图部分被包裹在 &lt;g&gt; 元素中,以将原点移动到 SVG 的中心(在本例中为 300×300 尺寸):

  <g transform="translate(150,150)">

现在创建一个具有所需外观属性的&lt;text&gt; 元素,并将&lt;textPath&gt; 元素放入其中。使用text-anchor="middle" 使文本居中对齐,并将startOffset 属性设置为沿着您希望文本锚定的路径的距离。在这种情况下,偏移量等于直径为 120 的圆的周长的四分之一,即 2 × π × 120 / 4,即 188.5。 dominant-baseline 属性表示文本如何与曲线对齐; middle 的设置意味着文本的中心线与路径对齐,因此我们可以对上下曲线使用相同的半径。 (在某些情况下,这会使文本看起来有点挤压。您可以通过设置 letter-spacing 属性来解决此问题。)

    <text font-size="36" font-family="Courier New" font-weight="bold" fill="white">
      <textPath xlink:href="#cp1" startOffset="188.5" text-anchor="middle"
                dominant-baseline="central">Smooth Roast</textPath>
      <textPath xlink:href="#cp2" startOffset="188.5" text-anchor="middle"
                dominant-baseline="central">Coffee Company</textPath>
    </text>

logo中间的横排文字也可以用同样的方法,但是用普通的&lt;tspan&gt;元素代替&lt;textPath&gt;元素:

    <text font-size="12" font-family="Arial" font-weight="bold" fill="#c97">
      <tspan x="-120" y="0" text-anchor="middle" dominant-baseline="central">SINCE</tspan>
      <tspan x="120" y="0" text-anchor="middle" dominant-baseline="central">1981</tspan>
    </text>

这是完成的结果:

<svg width="300" height="300" viewBox="0 0 300 300" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <path id="cp1" d="M-120 0A120 120 0 0 1 120 0" fill="none" stroke="red" />
    <path id="cp2" d="M-120 0A120 120 0 0 0 120 0" fill="none" stroke="red" />
  </defs>
  <g transform="translate(150,150)">
    <!-- Circular background: -->
    <circle x="0" y="0" r="150" fill="#820" stroke="none" />
    <circle x="0" y="0" r="145" fill="none" stroke="white" stroke-width="4" />
    <circle x="0" y="0" r="98" fill="none" stroke="white" stroke-width="2" />
    <!-- This is supposed to look like a coffee cup: -->
    <rect x="-45" y="-40" width="80" height="80" fill="white" stroke="none" />
    <rect x="-45" y="30" width="80" height="20" rx="10" ry="10" fill="white" stroke="none" />
    <ellipse cx="45" cy="0" rx="15" ry="20" fill="none" stroke="white" stroke-width="8" />
    <!-- Text manipulation starts here: -->
    <text font-size="36" font-family="Courier New" font-weight="bold" fill="white">
      <textPath xlink:href="#cp1" startOffset="188.5" text-anchor="middle" dominant-baseline="central">Smooth Roast</textPath>
      <textPath xlink:href="#cp2" startOffset="188.5" text-anchor="middle" dominant-baseline="central">Coffee Company</textPath>
    </text>
    <text font-size="12" font-family="Arial" font-weight="bold" fill="#c97">
      <tspan x="-120" y="0" text-anchor="middle" dominant-baseline="central">SINCE</tspan>
      <tspan x="120" y="0" text-anchor="middle" dominant-baseline="central">1981</tspan>
    </text>
  </g>
</svg>

【讨论】:

  • +1 是的,SVG 内置的 textPath 很好地完成了这项任务。 Canvas 也可以在路径上做文字,但您必须手动计算角度和字母宽度。
  • 我注意到你使用了 xlink:href,但你没有使用 xmlns:xlink="http://www.w3.org/1999/xlink" ...浏览器是否理解 xlink:href 没有命名空间声明?
  • @dsdsdsdsd 好点。我当然不打算把它排除在外,尽管没有它浏览器似乎很开心。无论如何我都会编辑我的答案
  • 我也注意到了......我正在考虑发布一个关于是否真的需要它以及为什么......
猜你喜欢
  • 1970-01-01
  • 2014-12-11
  • 2016-11-07
  • 2011-06-15
  • 1970-01-01
  • 2014-07-19
  • 2019-09-21
  • 1970-01-01
  • 2019-12-10
相关资源
最近更新 更多