有没有办法使用 CSS3 / Canvas 来弯曲/弧形文本

发布于 2024-11-06 22:38:06 字数 220 浏览 1 评论 0原文

我正在尝试使用 CSS3、HTML Canvas 甚至 SVG 制作弯曲文本效果(例如参见下图)?这可能吗?如果可以的话,怎样才能达到这样的效果呢?

更新:澄清一下:以这种方式设置样式的文本将是动态的。

拱形或弯曲文本示例

I'm trying to make a curved text effect using CSS3, HTML Canvas, or even SVG (see image below for example)? Is this possible? If so, how can I achieve this effect?

Update: To clarify: The text that will be styled this way will be dynamic.

Arched or Curved Text Example

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

望她远 2024-11-13 22:38:06

SVG 直接支持路径上的文本,但它不会沿路径“弯曲”各个字形。以下是如何创建它的示例

...
<defs>
  <path id="textPath" d="M10 50 C10 0 90 0 90 50"/>
</defs>
<text fill="red">
  <textPath xlink:href="#textPath">Text on a Path</textPath>
</text>
...

SVG supports text-on-a-path directly, though it does not 'bend' the individual glyphs along the path. Here's an example of how you create it:

...
<defs>
  <path id="textPath" d="M10 50 C10 0 90 0 90 50"/>
</defs>
<text fill="red">
  <textPath xlink:href="#textPath">Text on a Path</textPath>
</text>
...
指尖凝香 2024-11-13 22:38:06

您当然可以使用画布来做到这一点,请尝试以下代码作为示例:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Testing min-width and max-width</title>
    <style type="text/css">

    </style>

  </head>
  <body>
      <canvas id="cnv"></canvas>
      <script type="text/javascript" charset="utf-8">
          cnv = document.getElementById("cnv");
          cnv.width = 500;
          cnv.height = 300;
          ctx = cnv.getContext("2d");
          ctx.font = "bold 12px sans-serif";
          text = "abcdefghijklm"
          for (i = 0; i < text.length; i++) {
              ctx.fillText(text[i], 300, 100);
              ctx.rotate(0.1);
          }
      </script>
  </body>
</html>

它做得并不完全正确,但我确信您会设法根据您的喜好调整它;)

You can certainly do it with canvas, try out this code as an example:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Testing min-width and max-width</title>
    <style type="text/css">

    </style>

  </head>
  <body>
      <canvas id="cnv"></canvas>
      <script type="text/javascript" charset="utf-8">
          cnv = document.getElementById("cnv");
          cnv.width = 500;
          cnv.height = 300;
          ctx = cnv.getContext("2d");
          ctx.font = "bold 12px sans-serif";
          text = "abcdefghijklm"
          for (i = 0; i < text.length; i++) {
              ctx.fillText(text[i], 300, 100);
              ctx.rotate(0.1);
          }
      </script>
  </body>
</html>

It doesn't do it exactly right, but I'm certain you'll manage to tweak it to your likening ;)

陪我终i 2024-11-13 22:38:06

您可以使用一些 CSS 来做到这一点,但我确信您不会很快在 IE 上运行它。另一方面,最酷的事情是文本是可选的:D

.num1 {
  -webkit-transform: translate(0px, 30px) rotate(-35deg);
}
.num2 {
  -webkit-transform: translate(0px, 25px) rotate(-25deg);
}
.num3 {
  -webkit-transform: translate(0px, 23px) rotate(0deg);
}
.num4 {
  -webkit-transform: translate(0px, 25px) rotate(25deg);
}
.num5 {
  -webkit-transform: translate(0px, 30px) rotate(35deg);
}

span {display: inline-block; margin: 1px;}
<div style="width: 300px; height: 300px; margin: 50px auto">
    <span class="num1">a</span><span class="num2">b</span><span class="num3">c</span><span class="num4">d</span><span class="num5">e</span>
</div>

You can do it using some CSS, however I'm sure you won't get it running on IE any time soon. On the other hand, the cool thing is that the text is selectable :D

.num1 {
  -webkit-transform: translate(0px, 30px) rotate(-35deg);
}
.num2 {
  -webkit-transform: translate(0px, 25px) rotate(-25deg);
}
.num3 {
  -webkit-transform: translate(0px, 23px) rotate(0deg);
}
.num4 {
  -webkit-transform: translate(0px, 25px) rotate(25deg);
}
.num5 {
  -webkit-transform: translate(0px, 30px) rotate(35deg);
}

span {display: inline-block; margin: 1px;}
<div style="width: 300px; height: 300px; margin: 50px auto">
    <span class="num1">a</span><span class="num2">b</span><span class="num3">c</span><span class="num4">d</span><span class="num5">e</span>
</div>

樱&纷飞 2024-11-13 22:38:06

它不是一个纯粹的 CSS 解决方案,但 CircleType.js 对于弧形文本非常有效。

http://circletype.labwire.ca/

It's not a pure CSS solution but CircleType.js works great for arced text.

http://circletype.labwire.ca/

捂风挽笑 2024-11-13 22:38:06

有一个使用 CSS3 来弯曲文本的 jQuery 插件,名为 arctext.js。它非常好并且有一系列配置选项。我猜它在 IE8 上不起作用,但我猜大多数 CSS3 东西都不起作用!

此处还有一个演示页面,其中包含一些实际操作示例。

There is a jQuery Plugin to curve text using CSS3 called arctext.js. It's pretty good and has a range of configuration options. I guess it won't work on IE8 but I guess most CSS3 thing don't!

There's also a demo page with some example of it in action here.

生活了然无味 2024-11-13 22:38:06

这个 教程 向您展示了如何使用 HTML5 和 canvas 来完成此操作。其他答案之一提出了类似的想法,即使用 canvas.rotate 方法。这个也使用canvas.translate。

本教程的完整代码是:

function drawTextAlongArc(context, str, centerX, centerY, radius, angle) {
  var len = str.length,
    s;
  context.save();
  context.translate(centerX, centerY);
  context.rotate(-1 * angle / 2);
  context.rotate(-1 * (angle / len) / 2);
  for (var n = 0; n < len; n++) {
    context.rotate(angle / len);
    context.save();
    context.translate(0, -1 * radius);
    s = str[n];
    context.fillText(s, 0, 0);
    context.restore();
  }
  context.restore();
}
var canvas = document.getElementById('myCanvas'),
  context = canvas.getContext('2d'),
  centerX = canvas.width / 2,
  centerY = canvas.height - 30,
  angle = Math.PI * 0.8,
  radius = 150;

context.font = '30pt Calibri';
context.textAlign = 'center';
context.fillStyle = 'blue';
context.strokeStyle = 'blue';
context.lineWidth = 4;
drawTextAlongArc(context, 'Text along arc path', centerX, centerY, radius, angle);

// draw circle underneath text
context.arc(centerX, centerY, radius - 10, 0, 2 * Math.PI, false);
context.stroke();
<!DOCTYPE HTML>
<html>

<head>
  <style>
    body {
      margin: 0px;
      padding: 0px;
    }
  </style>
</head>

<body>
  <canvas id="myCanvas" width="578" height="250"></canvas>
</body>

</html>

This tutorial shows you exactly how to do it using HTML5 and canvas. One of the other answers presented a similar idea, which is to use the canvas.rotate method. This one also uses canvas.translate.

The full code from the tutorial is:

function drawTextAlongArc(context, str, centerX, centerY, radius, angle) {
  var len = str.length,
    s;
  context.save();
  context.translate(centerX, centerY);
  context.rotate(-1 * angle / 2);
  context.rotate(-1 * (angle / len) / 2);
  for (var n = 0; n < len; n++) {
    context.rotate(angle / len);
    context.save();
    context.translate(0, -1 * radius);
    s = str[n];
    context.fillText(s, 0, 0);
    context.restore();
  }
  context.restore();
}
var canvas = document.getElementById('myCanvas'),
  context = canvas.getContext('2d'),
  centerX = canvas.width / 2,
  centerY = canvas.height - 30,
  angle = Math.PI * 0.8,
  radius = 150;

context.font = '30pt Calibri';
context.textAlign = 'center';
context.fillStyle = 'blue';
context.strokeStyle = 'blue';
context.lineWidth = 4;
drawTextAlongArc(context, 'Text along arc path', centerX, centerY, radius, angle);

// draw circle underneath text
context.arc(centerX, centerY, radius - 10, 0, 2 * Math.PI, false);
context.stroke();
<!DOCTYPE HTML>
<html>

<head>
  <style>
    body {
      margin: 0px;
      padding: 0px;
    }
  </style>
</head>

<body>
  <canvas id="myCanvas" width="578" height="250"></canvas>
</body>

</html>

记忆消瘦 2024-11-13 22:38:06

您可以将 SVG 与 一起使用,如下所示:

function updateMessage(str) {
  document.getElementById("MyMessage").textContent = str;
}
<button onClick="updateMessage('The text has changed');">Change the text</button>
<svg viewBox="0 0 1000 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <path id="CurvedPath"
          d="M 0 150 Q 325 50 650 150 " />
  </defs>
  <text font-size="54" x='325' y='50'  text-anchor="middle"  fill="darkgreen" font-family=Arial,Helvetica  style="text-shadow: 2px 2px 3px gray;">
    <textPath id='MyMessage' xlink:href="#CurvedPath">THIS TEXT IS CURVED</textPath>
  </text>
</svg>

You can use SVG with <textPath> like this:

function updateMessage(str) {
  document.getElementById("MyMessage").textContent = str;
}
<button onClick="updateMessage('The text has changed');">Change the text</button>
<svg viewBox="0 0 1000 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <path id="CurvedPath"
          d="M 0 150 Q 325 50 650 150 " />
  </defs>
  <text font-size="54" x='325' y='50'  text-anchor="middle"  fill="darkgreen" font-family=Arial,Helvetica  style="text-shadow: 2px 2px 3px gray;">
    <textPath id='MyMessage' xlink:href="#CurvedPath">THIS TEXT IS CURVED</textPath>
  </text>
</svg>

旧瑾黎汐 2024-11-13 22:38:06
<embed width="100" height="100" type="image/svg+xml" src="path.svg">
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
      <path id="textPath" d="M10 50 C10 0 90 0 90 50"/>
    </defs>
  </svg>
</embed>
<embed width="100" height="100" type="image/svg+xml" src="path.svg">
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
      <path id="textPath" d="M10 50 C10 0 90 0 90 50"/>
    </defs>
  </svg>
</embed>
む无字情书 2024-11-13 22:38:06

我使用上面提到的教程(由 Simon Tewsi 编写)编写了一个关于字距调整问题的更好的解决方案。不使用库,纯 JS。

请参阅 http://jsfiddle.net/fidnut/cjccg74f/

function drawTextAlongArcInside(ctx, str, font, color, radius, angle, centerX, centerY, wspace)

注意:SO 要求我把 JSFiddle 的所有代码也放在这里。我认为这不明智,代码太多,所以我只添加函数的名称。

I used the tutorial mentioned above (by Simon Tewsi) to write a better solution, regarding the kerning issue. Uses no library, pure JS.

See it at http://jsfiddle.net/fidnut/cjccg74f/

function drawTextAlongArcInside(ctx, str, font, color, radius, angle, centerX, centerY, wspace)

Note: SO is demanding that I put all the code from JSFiddle in here too. I don't think this is wise, too much code, so I am adding only the name of the function.

小猫一只 2024-11-13 22:38:06

还有transform: skew(x, y),它不使用canvas。

There is also transform: skew(x, y), which does not use canvas.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文