canvas绘制动画效果

众所周知,我们所看到的动画实际上就是一系列静态画面快速切换,从而让肉眼因视觉残像产生了「画面在活动」的视觉效果。明白了这一点后,在canvas上绘制动画效果就显得比较简单了。我们只需要将某个静态图形先清除,然后在另外一个位置重新绘制,如此反复,让静态图形按照一定的轨迹进行移动,就可以产生动画效果了。

下面,我们在canvas上绘制一个实心小球,然后用键盘上的方向键控制小球的移动,从而产生动态效果。

示例代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>html5 canvas绘制可移动的小球入门示例</title>
</head>
<body onkeydown="moveBall(event)">

<!-- 添加canvas标签,并加上红色边框以便于在页面上查看 -->
<canvas id="myCanvas" width="400px" height="300px" style="border: 1px solid red;">
    您的浏览器不支持canvas标签。
</canvas>

<script type="text/javascript">
    //获取Canvas对象(画布)
    var canvas = document.getElementById("myCanvas");

    //表示圆球的类
    function Ball(x, y ,radius, speed){
        this.x = x || 50;   //圆球的x坐标,默认为10
        this.y = y || 50;   //圆球的y坐标,默认为10
        this.radius = radius || 50; //圆球的半径,默认为10
        this.speed = speed || 5;    //圆球的移动速度,默认为5

        //向上移动
        this.moveUp = function(){
            this.y -= this.speed;
            if(this.y < this.radius){
                //防止超出上边界
                this.y = this.radius;
            }
        };

        //向右移动
        this.moveRight = function(){
            this.x += this.speed;
            var maxX = canvas.width - this.radius;
            if(this.x > maxX){
                //防止超出右边界
                this.x = maxX;
//                alert("m")
            }
        };
        //向左移动
        this.moveLeft = function(){
            this.x -= this.speed;
            if(this.x < this.radius){
                //防止超出左边界
                this.x = this.radius;
            }
        };

        //向下移动
        this.moveDown = function(){
            this.y += this.speed;
            var maxY = canvas.height - this.radius;
            if(this.y > maxY){
                //防止超出下边界
                this.y = maxY;
            }
        };
    }

    //绘制小球
    function drawBall(ball){
        if(typeof ctx != "undefined"){
            ctx.beginPath();
            ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2, false);
            //创建一个表示放射性颜色渐变的CanvasGradient对象
            //该对象的作用域是以(100,100)为圆心、半径为10px的内圆和以(100,100)为圆心、半径为50px的外圆之间的环状区域
            var canvasGradient = ctx.createRadialGradient(ball.x,ball.y,0,ball.x,ball.y,50);
            //在offset为0的位置(即内圆的圆圈处)添加一个蓝色的渐变
            canvasGradient.addColorStop(0,"blue");
            //在offset为0.5的位置(环状区域从内到外放射50%的中间位置)添加一个绿色的渐变
            canvasGradient.addColorStop(0.5,"green");
            //在offset为0的位置(即外圆的圆圈处)添加一个红色的渐变
            canvasGradient.addColorStop(1,"red");
            //将fillStyle的属性值设为该CanvasGradient对象
            ctx.fillStyle = canvasGradient;
            ctx.fill();
        }
    }

    //清空canvas画布
    function clearCanvas(){
        if(typeof ctx != "undefined"){
            ctx.clearRect(0, 0, 400, 300);
        }
    }

    var ball = new Ball();
    //简单地检测当前浏览器是否支持Canvas对象,以免在一些不支持html5的浏览器中提示语法错误
    if(canvas.getContext){
        //获取对应的CanvasRenderingContext2D对象(画笔)
        var ctx = canvas.getContext("2d");
        drawBall(ball);
    }

    //onkeydown事件的回调处理函数
    //根据用户的按键来控制小球的移动
    function moveBall(event){
        switch(event.keyCode){
            case 37:    //左方向键
                ball.moveLeft();
                break;
            case 38:    //上方向键
                ball.moveUp();
                break;
            case 39:    //右方向键
                ball.moveRight();
                break;
            case 40:    //下方向键
                ball.moveDown();
                break;
            default:    //其他按键操作不响应
                return;
        }

        clearCanvas();  //先清空画布
        drawBall(ball); //再绘制最新的小球
    }
</script>
</body>
</html>

拓展:

①四个方向键的键码分别是37(左)、38(上)、39(右)和40(下)

②switch 语句用于基于不同的条件来执行不同的动作--语法:

switch(n)
{
case 1:
  执行代码块 1
  break;
case 2:
  执行代码块 2
  break;
default:
  n 与 case 1 和 case 2 不同时执行的代码
}

工作原理:

①首先设置表达式 n(通常是一个变量)。随后表达式的值会与结构中的每个 case 的值做比较。如果存在匹配,则与该 case 关联的代码块会被执行。请使用 break 来阻止代码自动地向下一个 case 运行。

②default 关键词,使用 default 关键词来规定匹配不存在时做的事情

.