【问题标题】:Is there a way to curve / arc text using CSS3 / Canvas有没有办法使用 CSS3/Canvas 来弯曲/弧形文本
【发布时间】:2010-05-15 16:29:58
【问题描述】:

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

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

【问题讨论】:

标签: javascript html canvas css


【解决方案1】:

SVG 直接支持 text-on-a-path,尽管它不会沿路径“弯曲”单个字形。以下是 an example 的创建方式:

...
<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>
...

【讨论】:

  • 为什么这不是答案?似乎是迄今为止最好的解决方案?
【解决方案2】:

你当然可以用画布来做,试试这个代码作为例子:

<!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>

它并不完全正确,但我敢肯定你会设法根据自己的喜好对其进行调整;)

【讨论】:

【解决方案3】:

或者你可以使用一些 CSS 来实现,但是我相信你不会很快让它在 IE 上运行。另一方面,很酷的事情是文本是可选择的:D

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

  </head>
  <body>
    <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>
</body>
</html>

【讨论】:

  • 坦率地说,我不关心 IE。这适用于 iPhone 优化的网站,所以我只担心它在 Webkit 中正确显示。我也许可以使用一些 JavaScript 技巧来实现您对动态文本的建议。谢谢。
  • IE9+ 支持 CSS3 2d 变换,IE8 及以下支持微软的矩阵变换,但处理方式略有不同。
  • @JayC 是的,这篇文章已有 2 年历史。我相信使用-ms- 前缀应该大部分都可以工作,虽然我没有办法测试。
【解决方案4】:

它不是纯 CSS 解决方案,但 CircleType.js 非常适合弧形文本。

http://circletype.labwire.ca/

【讨论】:

  • 好东西!它很容易工作。请注意,它需要另一个插件(“需要 Lettering.js”)
  • 加载需要很长时间。
【解决方案5】:

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

还有一个演示页面,其中包含一些正在运行的示例here

【讨论】:

    【解决方案6】:
    <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>
    

    【讨论】:

      【解决方案7】:

      您可以像这样将 SVG 与 TextPath 一起使用:

      <html>
      <head>
      <script>
       function updateMessage(str) {
      document.getElementById("MyMessage").textContent = str;
       }
      </script>
      </head>
      <body >
      <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>
      </body>
      
      </html>

      【讨论】:

        【解决方案8】:

        这个tutorial 向您展示了如何使用 HTML5 和画布来做到这一点。其他答案之一提出了类似的想法,即使用 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>

        【讨论】:

          【解决方案9】:

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

          查看http://jsfiddle.net/fidnut/cjccg74f/

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

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

          【讨论】:

            【解决方案10】:

            还有transform: skew(x, y, z),不使用画布。

            【讨论】:

              猜你喜欢
              • 2016-04-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-12-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-11-28
              相关资源
              最近更新 更多