Wrap text to a circle shape in svg or canvas -
what solution fitting text circle on website, flows curves of circle, instead of rectangular bounding box?
here's i'm trying achieve: there number of black circles (of fixed size) on page, textarea next each of them. when text entered textarea, appears in black circle, centered on both axes. if text entered line becomes longer radius of circle, minus specified value margin, line break expect regular wrapping, block of text still being centered. lines nearer top or bottom will, of course, shorter ones near middle.
the text have fixed size , when circle filled text, content should not shown (like overflow hidden).
the black circles text speech bubbles, meant printed , glued onto poster.
do of fantastic svg/canvas libraries support or have figure our method scratch?
there proposed css feature call "exclusions" make possible flow text inside defined areas: http://www.w3.org/tr/css3-exclusions/
this means svg , canvas paths defined containers , text flow/wrap inside containers.
i did "proposed" -- it's ways off being reality in browsers.
however...
you can wrap text inside circle using html canvas
the width available display text on line changes move down circle.
here’s how determine maximum available width of horizontal line on circle
// var r radius of circle // var h distance top of circle horizontal line you’ll put text on var maxwidth=2*math.sqrt(h*(2*r-h));
you fit text line measuring width of text—adding 1 word @ time, until you’ve used available width of line.
here’s how use canvas measure text using current context.font:
var width=ctx.measuretext(“this test text.”).width;
the rest adding text each line maximum line width , starting new line.
if prefer svg, can similar in svg using element.getcomputedtextlength method text metrics.
here code , fiddle: http://jsfiddle.net/m1erickson/upq6l/
<!doctype html> <html lang="en"> <head> <style> body{ background-color: ivory; padding:20px; } canvas{ border:1px solid red;} </style> <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script> $(function() { var canvas=document.getelementbyid("canvas"); var ctx=canvas.getcontext("2d"); var text = "'twas night before christmas, when through house, not creature stirring, not mouse. , begins story of day of christmas"; var font="12pt verdana"; var textheight=15; var lineheight=textheight+5; var lines=[]; var cx=150; var cy=150; var r=100; initlines(); wraptext(); ctx.beginpath(); ctx.arc(cx,cy,r,0,math.pi*2,false); ctx.closepath(); ctx.strokestyle="skyblue"; ctx.linewidth=2; ctx.stroke(); // pre-calculate width of each horizontal chord of circle // max width allowed text function initlines(){ for(var y=r*.90; y>-r; y-=lineheight){ var h=math.abs(r-y); if(y-lineheight<0){ h+=20; } var length=2*math.sqrt(h*(2*r-h)); if(length && length>10){ lines.push({ y:y, maxlength:length }); } } } // draw text on each line of circle function wraptext(){ var i=0; var words=text.split(" "); while(i<lines.length && words.length>0){ line=lines[i++]; var linedata=calcallowablewords(line.maxlength,words); ctx.filltext(linedata.text, cx-linedata.width/2, cy-line.y+textheight); words.splice(0,linedata.count); }; } // calculate how many words fit on line function calcallowablewords(maxwidth,words){ var wordcount=0; var testline=""; var spacer=""; var fittedwidth=0; var fittedtext=""; ctx.font=font; for(var i=0;i<words.length; i++){ testline+=spacer+words[i]; spacer=" "; var width=ctx.measuretext(testline).width; if(width>maxwidth){ return({ count:i, width:fittedwidth, text:fittedtext }); } fittedwidth=width; fittedtext=testline; } } }); // end $(function(){}); </script> </head> <body> <p>text wrapped , clipped inside circle</p> <canvas id="canvas" width=300 height=300></canvas> </body> </html>
Comments
Post a Comment