2011-05-19 13 views
17

¿Cómo crear texto círculo (texto en forma de círculo) con una lona?HTML5 círculo lienzo texto

Like this

+0

Es una idea de colocar cada letra separados en una forma circular, pero no puede realmente "doblar" que? –

+0

Te recomiendo que uses svg, que es más poderoso para hacer que estas cosas –

+0

Jeah es posible. –

Respuesta

21

Las cartas deben ahora ser debidamente orientados: el uso

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(); 
} 

Muestra :

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

El espacio extra en el extremo de la cuerda añade un poco de acolchado adicional.

Salida de ejemplo:

Sample Output

+0

Ya pensé en hacer esto, gracias por empezar. Todavía necesita algunas mejoras que veo: P –

+0

Claro que sí. Fue solo un código rápido como una prueba de concepto :) – cmptrgeekken

+0

+1 para el ejemplo! He modificado el código de cmptrgeekken para rotar las letras también, así que ahora tenemos un ejemplo de trabajo que ha llegado al "círculo completo". –

5

Es técnicamente se puede hacer, pero no hay construido en camino. Tendrás que calcular un arco y dibujar cada letra individualmente a lo largo de ese arco, calculando el ángulo y posicionándote.

Muchas personas terminan haciendo sus propios métodos (como la anterior) para el texto. Demonios, ¡el texto de líneas múltiples ni siquiera se puede hacer de forma predeterminada!

EDIT: Aquí hay un ejemplo de trabajo, aprovechando el trabajo de cmptrgeekken. Si me Upvote, lo upvote demasiado: P

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

Lo que parece:

Sample

1

Es mi modificación de este: http://jsfiddle.net/Brfp3/3/ Pero función le permite mostrar texto en sentido horario y antihorario.

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(); 
     } 

Ejemplo de uso:

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); 
2

Una versión en la que se cuenta el tamaño de los caracteres. Los espacios entre las letras son, por lo tanto, siempre del mismo tamaño.

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(); 
} 
4

En mi blog, me eche un vistazo bastante cerca a la creación de texto circular usando HTML5 Canvas:

blog.graphicsgen.com

En el ejemplo, las opciones incluyen redondeado alineación del texto (izquierda, centro y derecha) desde un ángulo dado, texto orientado hacia adentro y hacia afuera, kerning (espacio ajustable entre caracteres) y texto dentro o fuera del radio.

También hay un jsfiddle con un ejemplo de trabajo.

Es como sigue:

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); 
}