【疯狂的菊花系列】Canvas绘制Loading动画

23:43 by Azrael

上回说到用png图片来做帧动画, 总的来说也没什么大问题, 但是画个菊花, 按固定角度旋转N次做图实在是蛋疼.

既然怎么样都要画个菊花, 那不如就用canvas来画算了. 对于不支持canvas的浏览器, 可以用svg, 原理都差不多.

这个canvas动画的原理跟帧动画也类似, 先绘制第一帧的画面, 然后擦掉, 接着绘制第二帧, 以此循环. 时间间隔短的话看上去就变成动画了.

具体解释请看代码, 有足够的注释, 或者也可以点这里看看结果. canvas的api说明可以在这里找到.

window.onload = function(){
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    if(!ctx){
        return;
    }
    ctx.clearRect(0,0,128,128);//擦除画布
    ctx.fillStyle = 'transparent';
    ctx.fillRect(0,0,128,128);
    ctx.fillStyle = 'black'; //定义点的颜色
    var base = 0;
    var update = function(){
        ctx.save(); //把当前的绘图状态保存起来(如旋转角度的初始位置, 填充颜色, 坐标原点等)
        ctx.clearRect(0,0,128,128);//擦除画布
        ctx.translate(64, 64);//把坐标原点移动到画布中央
        base = (++base === 13) ? (base - 12) : base;//使用base来指示最大的圆点所在的位置, 实现旋转动画的效果
        var angle = Math.PI / 6;//画12个点, 所以每个点之间的角度是 1/6 PI
        var beginAngle = angle * base ;
        for(var i = 1; i <= 12; i ++){
            ctx.beginPath();//开始一个路径
            if(i === 1){
                ctx.rotate(beginAngle);
            }else{
                ctx.rotate(angle);//每次调用rotate之后, 其旋转角度并不会还原, 而是接着上一次的位置
            }
            ctx.arc(0, -48, i * 0.8 + 1, 0, 2 * Math.PI, true);//绘制一个圆点
            ctx.closePath();//闭合路径
            //如果不是用beginPath和closePath, 在调用fill方法时, 会导致画布上的所有圆都重叠在一起了
            ctx.fill();//填充(使用上面最后定义的fillStyle)
        }
        ctx.restore();//还原绘图状态, 如果不还原, 则下一次调用rotate时会接着这次的位置旋转, 而不是初始位置
    }
    update();
    setInterval(update, 50);
};

菊花系列暂时就到这里了, 有时间再去用svg整个.

blog