Javascript HTML5画布文本围绕圆圈设置动画

Javascript HTML5画布文本围绕圆圈设置动画,javascript,html,canvas,html5-canvas,Javascript,Html,Canvas,Html5 Canvas,更新代码有什么问题?我知道它不会旋转,但为什么文字会扭曲 有人知道为什么吗 为了弄清楚这件事,我正在拼命工作 function showCircularNameRotating(string, startAngle, endAngle){ //context.clearRect(0, 0, canvas.width, canvas.height); context.font = '32pt Sans-Serif'; context.fillStyle = '#1826B0

更新代码有什么问题?我知道它不会旋转,但为什么文字会扭曲

有人知道为什么吗 为了弄清楚这件事,我正在拼命工作

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

    }
函数showCircularNameRotating(字符串、星形缠结、端角){
//clearRect(0,0,canvas.width,canvas.height);
context.font='32pt无衬线';
context.fillStyle='#1826B0';
圆圈={
x:canvas.width/2,
y:canvas.height/2,
半径:200
};
var半径=圆半径,
角度减量=(startAngle-endAngle/string.length-1),
角度=浮点数(startAngle),
指数=0,
性格
context.save();

虽然(索引在画布中,不太确定。但如果可以使用它,在SVG中会很简单吗

  • 放置表示圆的标记
  • 使用旋转键旋转路径
  • 是的,这是可能的

    这里是一个简单的方法,您可以在此基础上进行构建(我现在就做了这个方法,所以它肯定可以以各种方式进行优化和调整)

    • 这使用两个对象,一个用于文本本身,另一个用于每个字符
    • 字符串在文本对象的构造函数中被拆分为char对象
    • 画布是旋转的
    • 每个字符都以圆形模式相对绘制

    文本对象

    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;
            }
        };
    }
    
    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;
    }
    
    字符对象

    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;
            }
        };
    }
    
    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;
    }
    
    现在我们需要做的就是创建一个文本对象,然后在循环中调用render方法:

    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);
    })();
    
    如上所述,这里有很大的优化空间。最昂贵的部件是:

    • 文本渲染(首先将文本渲染为图像)
    • 使用“保存/还原”对每个字符进行本地旋转
    • 小事

    不过,我会把它作为OP的练习:)

    你介意看看我的代码,看看哪里出错了吗?我会把它贴在上面