【问题标题】:HTML5 Canvas Circle TextHTML5 画布圆形文本
【发布时间】:2011-08-29 01:06:36
【问题描述】:

如何使用画布创建圆形文本(圆形文本)?

【问题讨论】:

  • 将每个字母分开放置成圆形是一个想法,但我真的不能“弯曲”它吗?
  • 我推荐你使用 svg,它更强大来做这些事情
  • 耶图像是可能的..

标签: javascript html canvas


【解决方案1】:

技术上可以做到,但没有内置方法。您必须计算一个弧线,然后沿着该弧线单独绘制每个字母,计算出角度并自行定位。

许多人最终为文本创建了自己的方法(如上所示)。哎呀,默认情况下甚至无法完成多行文本!

编辑:这是一个工作示例,借鉴了 cmptrgeekken 的工作。如果你支持我,也支持他:P

http://jsfiddle.net/c3Y8M/1/

它的样子:

【讨论】:

  • 感谢演示。因此,如果我不希望字母散布在圆圈中,我是否只需将 numDegreesPerLetter 乘以小于 1 的比率?我在这里修改了你的代码jsfiddle.net/thoakun/1zmL9rwd
【解决方案2】:

字母现在应该是正确的方向了:

CanvasRenderingContext2D.prototype.fillTextCircle = function(text,x,y,radius,startRotation){
   var numRadsPerLetter = 2*Math.PI / text.length;
   this.save();
   this.translate(x,y);
   this.rotate(startRotation);

   for(var i=0;i<text.length;i++){
      this.save();
      this.rotate(i*numRadsPerLetter);

      this.fillText(text[i],0,-radius);
      this.restore();
   }
   this.restore();
}

示例用法:

var ctx = document.getElementById('canvas').getContext('2d');
ctx.font = "bold 30px Serif";
ctx.fillTextCircle("Circle Text ",150,150,75,Math.PI / 2);

字符串末尾的额外空格添加了一些额外的填充。

示例输出:

【讨论】:

  • 我已经考虑过做这个,谢谢你的开始。我看到它仍然需要一些改进:P
  • 当然可以。只是作为概念证明的快速代码:)
  • +1 为例!我已经修改了 cmptrgeekken 的代码以旋转字母,所以现在我们有了一个“完整的循环!”的工作示例!
  • cmptrgeekken 没有提及,但他已经更新了他的代码以实现与我的相同的效果,但使用了更通用的方法。以他为起点。另外,在这里:jsfiddle.net/D5JWa/5 你必须记住在你创建它之后调用 init(),并记住 strokeStyle 不是一个函数(将其更改为 ='s)
  • 是的,我意识到ctx.fillText() 调用中的位置实际上决定了字母的方向。考虑到这一点,您可以尝试各种定位来实现您想要的任何字母方向。
【解决方案3】:

这是我的修改:http://jsfiddle.net/Brfp3/3/ 但功能允许您顺时针和逆时针显示文本。

function textCircle(text,x,y,radius,space,top){
           space = space || 0;
           var numRadsPerLetter = (Math.PI - space * 2) / text.length;
           ctx.save();
           ctx.translate(x,y);
           var k = (top) ? 1 : -1; 
           ctx.rotate(-k * ((Math.PI - numRadsPerLetter) / 2 - space));
           for(var i=0;i<text.length;i++){
              ctx.save();
              ctx.rotate(k*i*(numRadsPerLetter));
              ctx.textAlign = "center";
             ctx.textBaseline = (!top) ? "top" : "bottom";
             ctx.fillText(text[i],0,-k*(radius));
              ctx.restore();
           }
           ctx.restore();
        }

示例用法:

ctx.font = "bold 30px Courier";
textCircle("Half circle Text",150,150,75,Math.PI/12,1);
textCircle("Half circle Text",150,150,75,Math.PI/12);

【讨论】:

  • 谢谢。您的演示非常酷,它帮助我解决了我遇到的问题。
【解决方案4】:

CircleType.js 不使用画布,但实现了相同的效果:http://circletype.labwire.ca - 也适用于流体布局。

【讨论】:

    【解决方案5】:

    计算字符大小的版本。因此,字母之间的空格总是相同的大小。

    function drawTextAlongArc(context, str, centerX, centerY, radius, angle) {
        var len = str.length, s, letterAngle;
    
        context.save();
        context.textAlign = 'center';
        context.translate(centerX, centerY);
        context.rotate(angle + Math.PI / 2);
    
        for (var n = 0; n < len; n++) {
            s = str[n];
            letterAngle = 0.5*(context.measureText(s).width / radius);
    
            context.rotate(letterAngle);
            context.save();
    
            context.translate(0, -radius);
            context.fillText(s, 0, 0);
            context.restore();
    
            context.rotate(letterAngle);
        }
        context.restore();
    }
    

    【讨论】:

      【解决方案6】:

      在我的博客上,我仔细研究了使用 HTML5 Canvas 创建圆形文本:

      html5graphics.blogspot.com

      在示例中,选项包括从给定角度圆角文本对齐(左、中和右)、向内和向外的文本、字距调整(字符之间的可调整间距)以及半径内或外的文本。

      还有一个带有工作示例的jsfiddle

      如下:

      document.body.appendChild(getCircularText("ROUNDED TEXT LOOKS BEST IN CAPS!", 250, 0, "center", false, true, "Arial", "18pt", 2));
      
      function getCircularText(text, diameter, startAngle, align, textInside, inwardFacing, fName, fSize, kerning) {
          // text:         The text to be displayed in circular fashion
          // diameter:     The diameter of the circle around which the text will
          //               be displayed (inside or outside)
          // startAngle:   In degrees, Where the text will be shown. 0 degrees
          //               if the top of the circle
          // align:        Positions text to left right or center of startAngle
          // textInside:   true to show inside the diameter. False to show outside
          // inwardFacing: true for base of text facing inward. false for outward
          // fName:        name of font family. Make sure it is loaded
          // fSize:        size of font family. Don't forget to include units
          // kearning:     0 for normal gap between letters. positive or
          //               negative number to expand/compact gap in pixels
       //------------------------------------------------------------------------
      
          // declare and intialize canvas, reference, and useful variables
          align = align.toLowerCase();
          var mainCanvas = document.createElement('canvas');
          var ctxRef = mainCanvas.getContext('2d');
          var clockwise = align == "right" ? 1 : -1; // draw clockwise for aligned right. Else Anticlockwise
          startAngle = startAngle * (Math.PI / 180); // convert to radians
      
          // calculate height of the font. Many ways to do this
          // you can replace with your own!
          var div = document.createElement("div");
          div.innerHTML = text;
          div.style.position = 'absolute';
          div.style.top = '-10000px';
          div.style.left = '-10000px';
          div.style.fontFamily = fName;
          div.style.fontSize = fSize;
          document.body.appendChild(div);
          var textHeight = div.offsetHeight;
          document.body.removeChild(div);
      
          // in cases where we are drawing outside diameter,
          // expand diameter to handle it
          if (!textInside) diameter += textHeight * 2;
      
          mainCanvas.width = diameter;
          mainCanvas.height = diameter;
          // omit next line for transparent background
          mainCanvas.style.backgroundColor = 'lightgray'; 
          ctxRef.fillStyle = 'black';
          ctxRef.font = fSize + ' ' + fName;
      
          // Reverse letters for align Left inward, align right outward 
          // and align center inward.
          if (((["left", "center"].indexOf(align) > -1) && inwardFacing) || (align == "right" && !inwardFacing)) text = text.split("").reverse().join(""); 
      
          // Setup letters and positioning
          ctxRef.translate(diameter / 2, diameter / 2); // Move to center
          startAngle += (Math.PI * !inwardFacing); // Rotate 180 if outward
          ctxRef.textBaseline = 'middle'; // Ensure we draw in exact center
          ctxRef.textAlign = 'center'; // Ensure we draw in exact center
      
          // rotate 50% of total angle for center alignment
          if (align == "center") {
              for (var j = 0; j < text.length; j++) {
                  var charWid = ctxRef.measureText(text[j]).width;
                  startAngle += ((charWid + (j == text.length-1 ? 0 : kerning)) / (diameter / 2 - textHeight)) / 2 * -clockwise;
              }
          }
      
          // Phew... now rotate into final start position
          ctxRef.rotate(startAngle);
      
          // Now for the fun bit: draw, rotate, and repeat
          for (var j = 0; j < text.length; j++) {
              var charWid = ctxRef.measureText(text[j]).width; // half letter
              // rotate half letter
              ctxRef.rotate((charWid/2) / (diameter / 2 - textHeight) * clockwise); 
              // draw the character at "top" or "bottom" 
              // depending on inward or outward facing
              ctxRef.fillText(text[j], 0, (inwardFacing ? 1 : -1) * (0 - diameter / 2 + textHeight / 2));
      
              ctxRef.rotate((charWid/2 + kerning) / (diameter / 2 - textHeight) * clockwise); // rotate half letter
          }
      
          // Return it
          return (mainCanvas);
      }
      

      【讨论】:

        猜你喜欢
        • 2015-08-24
        • 1970-01-01
        • 2017-12-04
        • 1970-01-01
        • 2014-03-25
        • 2019-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多