Reputation: 55
Updated what is wrong with the code? I know it doesnt rotate but why is the text screwy.
Does anyone know why I am tearing my hair out trying to figure this out
function showCircularNameRotating(string, startAngle, endAngle){
//context.clearRect(0, 0, canvas.width, canvas.height);
context.font = '32pt Sans-Serif';
context.fillStyle = '#1826B0';
circle = {
x: canvas.width/2,
y: canvas.height/2,
radius: 200
};
var radius = circle.radius,
angleDecrement = (startAngle - endAngle/string.length-1),
angle = parseFloat(startAngle),
index = 0,
character;
context.save();
while(index <string.length){
character = string.charAt(index);
context.save();
context.beginPath();
context.translate(circle.x + Math.cos(angle) * radius,
circle.y - Math.sin(angle) * radius);
context.rotate(Math.PI/2 - angle);
context.fillText(character, 0,0);
context.strokeText(character,0,0);
angle -= angleDecrement;
index++;
context.restore();
}
context.restore();
}
Upvotes: 0
Views: 2058
Reputation:
Yes, it's possible.
Here is a simple approach which you can build upon (I made it right now so it can certainly be optimized and tweaked in various ways).
Text object
function Text(ctx, cx, cy, txt, font, radius) {
this.radius = radius; // expose so we can alter it live
ctx.textBaseline = 'bottom'; // use base of char for rotation
ctx.textAlign = 'center'; // center char around pivot
ctx.font = font;
var charsSplit = txt.split(''), // split string to chars
chars = [], // holds Char objects (see below)
scale = 0.01, // scales the space between the chars
step = 0.05, // speed in steps
i = 0, ch;
for(; ch = charsSplit[i++];) // create Char objects for each char
chars.push(new Char(ctx, ch));
// render the chars
this.render = function() {
var i = 0, ch, w = 0;
ctx.translate(cx, cy); // rotate the canvas creates the movement
ctx.rotate(-step);
ctx.translate(-cx, -cy);
for(; ch = chars[i++];) { // calc each char's position
ch.x = cx + this.radius * Math.cos(w);
ch.y = cy + this.radius * Math.sin(w);
ctx.save(); // locally rotate the char
ctx.translate(ch.x, ch.y);
ctx.rotate(w + 0.5 * Math.PI);
ctx.translate(-ch.x, -ch.y);
ctx.fillText(ch.char, ch.x, ch.y);
ctx.restore();
w += ch.width * scale;
}
};
}
The Char object
function Char(ctx, ch) {
this.char = ch; // current char
this.width = ctx.measureText('W').width; // width of char or widest char
this.x = 0; // logistics
this.y = 0;
}
Now all we need to do is to create a Text object and then call the render method in a loop:
var text = new Text(ctx, cx, cy, 'CIRCULAR TEXT', '32px sans-serif', 170);
(function loop() {
ctx.clearRect(0, 0, w, h);
text.render();
requestAnimationFrame(loop);
})();
As said, there is plenty of room for optimizations here. The most expensive parts are:
I'll leave that as an exercise for OP though :)
Upvotes: 1
Reputation: 1450
In Canvas, not so sure. But would be trivial in SVG if you can use that?
Upvotes: 0