HTML5 Canvas Circle Text

Come posso creare un testo circolare (testo a forma di cerchio) con canvas?

Come questo

Le lettere dovrebbero ora essere orientate correttamente:

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 

Esempio di utilizzo:

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

Lo spazio extra alla fine della stringa aggiunge un po 'di imbottitura extra.

Uscita di esempio:

Uscita di esempio

Può essere fatto tecnicamente, ma non esiste un modo integrato. Dovresti calcolare un arco e disegnare ogni lettera individualmente lungo quell’arco, individuando l’angolo e posizionandoti.

Molte persone finiscono per creare i propri metodi (come sopra) per il testo. Diamine, il testo multilinea non può nemmeno essere fatto di default!

EDIT: Ecco un esempio di lavoro, piggybacking del lavoro di cmptrgeekken. Se mi invidui, anche lui lo elevi: P

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

Cosa sembra:

Campione

Nel mio blog, guardo attentamente alla creazione di testo circolare usando HTML5 Canvas:

blog.graphicsgen.com

Nell’esempio, le opzioni includono l’allineamento arrotondato del testo (a sinistra, al centro e a destra) da un angolo dato, testo rivolto verso l’interno e verso l’esterno, crenatura (spazio regolabile tra i caratteri) e testo all’interno o all’esterno del raggio.

C’è anche un jsfiddle con un esempio funzionante.

È come segue:

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

Una versione in cui viene contata la dimensione dei personaggi. Gli spazi tra le lettere sono quindi sempre della stessa dimensione.

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

È la mia modifica di questo: http://jsfiddle.net/Brfp3/3/ Ma la funzione consente di visualizzare il testo in senso orario e antiorario.

 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 

Esempio di utilizzo:

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

CircleType.js non usa la canvas ma ottiene lo stesso effetto: http://circletype.labwire.ca – funziona bene anche nei layout fluidi.