Spacing between string characters in arced text isn't quite right. (HTML Canvas)
-
14-07-2021 - |
Question
See here - http://schnell.dreamhosters.com/nysbc/test6.php
JSFiddle - http://jsfiddle.net/VauFH/
The piece that draws text...
function draw_arc_text(ctx, str, radius){
ctx.save();
str = str.toUpperCase();
var radians_per_letter = 8 * Math.PI/180;
ctx.rotate((105 - (radius/60)) * Math.PI/180);
for (var n = 0; n < str.length; n++) {
ctx.save();
ctx.rotate(n * radians_per_letter);
ctx.fillText(str[n], 0, -radius);
ctx.restore();
}
ctx.restore();
}
As you can probably tell the spacing between the text on top of the colored discs is a little off. I've tried having a set amount of radians/degrees per letter, but the further out in radius you go the more that spacing becomes, so outermost text starts separating at a rapid pace. I've also tried working out some kind of formula that will incorporate radius into how much spacing each letter gets, but I can't seem to get that quite right either. Anyone have any ideas?
Also any tweaks in efficiency would be appreciated as well. I like to be as optimized as I can whenever possible.
Solution
probably a mathematicians worst nightmare :P. The following works though. Basically I just divide the result by the radius / 100. It gives the impression of equal spacing.
Another change I made, was to use requestAnimationFrame instead of interval. Intervals aren't very performant when compared to setTimeout
and especially when compare to requestAnimationFrame
for canvas. You'll notice you don't get a nasty hangup anymore when you leave the tab and go back to it.
I also got rid of the jQuery dependency because all you were using was document.ready
so it seemed unneeded.
function draw_arc_text(ctx, str, radius){
ctx.save();
str = str.toUpperCase();
var textWidth = Math.round(ctx.measureText(str).width);
var radians_per_letter = (((textWidth/str.length)) * Math.PI/180)/(radius*.01);
ctx.rotate(95 * Math.PI/180);
for (var n = 0; n < str.length; n++) {
ctx.save();
ctx.rotate(n * radians_per_letter);
ctx.fillText(str[n], 0, -radius);
ctx.restore();
}
ctx.restore();
}
OTHER TIPS
I don't have much experience with the canvas element, but is there any way you could use CSS' letter-spacing
property on the text?