HTML5 Canvas轻松动画制作,从入门到精通,实战案例教学

2026-08-23 0 阅读

HTML5 Canvas 是一种在网页上进行图形绘制的强大技术。它允许开发者使用 JavaScript 在网页上绘制图形、动画等,非常适合制作网页游戏、数据可视化等。本文将带你从入门到精通,通过实战案例教学,轻松掌握 HTML5 Canvas 动画制作。

一、HTML5 Canvas 基础知识

1.1 Canvas 元素

Canvas 元素是 HTML5 中新增的一个元素,用于在网页上绘制图形。它的基本属性是 widthheight,分别表示画布的宽度和高度。

<canvas id="myCanvas" width="200" height="100"></canvas>

1.2 2D 上下文

Canvas 元素创建后,可以通过 getContext('2d') 方法获取到 2D 上下文对象。2D 上下文提供了一系列绘制图形的 API。

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');

二、Canvas 基本绘制

2.1 绘制线条

使用 lineTo()moveTo() 方法可以绘制直线。lineTo() 方法用于指定直线的终点,而 moveTo() 方法用于指定起点。

ctx.moveTo(0, 0);
ctx.lineTo(100, 100);
ctx.stroke();

2.2 绘制矩形

使用 rect() 方法可以绘制矩形。该方法需要指定矩形的四个顶点坐标。

ctx.rect(0, 0, 100, 100);
ctx.stroke();

2.3 绘制圆形

使用 arc() 方法可以绘制圆形。该方法需要指定圆的半径、圆心坐标以及圆弧的角度。

ctx.arc(50, 50, 40, 0, Math.PI * 2);
ctx.stroke();

三、Canvas 动画制作

3.1 requestAnimationFrame 方法

requestAnimationFrame() 方法用于创建动画,它会在浏览器准备好绘制下一帧时调用指定的函数。该方法返回一个请求 ID,可以用于取消动画。

function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.arc(50, 50, 5, 0, Math.PI * 2);
    ctx.stroke();
    ctx.beginPath();
    ctx.arc(50 + Math.sin(Date.now() / 1000) * 50, 50 + Math.cos(Date.now() / 1000) * 50, 5, 0, Math.PI * 2);
    ctx.stroke();
    requestAnimationFrame(animate);
}
animate();

3.2 动画帧率控制

为了使动画流畅,可以使用 frameRate() 方法控制动画帧率。该方法接受一个帧率参数,单位为每秒帧数。

function frameRate(fps) {
    var frames = Math.floor(1000 / fps);
    return frames;
}

四、实战案例:制作简单的弹球游戏

4.1 游戏设计

本案例将制作一个简单的弹球游戏,玩家控制弹球撞击墙壁,游戏过程中,弹球速度逐渐加快。

4.2 代码实现

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var ballRadius = 10;
var ballX = canvas.width / 2;
var ballY = canvas.height - 30;
var ballSpeedX = 5;
var ballSpeedY = -5;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 3;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 25;
var bricks = [];
for (var c = 0; c < brickColumnCount; c++) {
    bricks[c] = [];
    for (var r = 0; r < brickRowCount; r++) {
        bricks[c][r] = { x: 0, y: 0, status: 1 };
    }
}
document.addEventListener('keydown', keyDownHandler, false);
document.addEventListener('keyup', keyUpHandler, false);
document.addEventListener('mousemove', mouseMoveHandler, false);
function keyDownHandler(e) {
    if (e.keyCode == 39) {
        rightPressed = true;
    }
    else if (e.keyCode == 37) {
        leftPressed = true;
    }
}
function keyUpHandler(e) {
    if (e.keyCode == 39) {
        rightPressed = false;
    }
    else if (e.keyCode == 37) {
        leftPressed = false;
    }
}
function mouseMoveHandler(e) {
    var relativeX = e.clientX - canvas.offsetLeft;
    if (relativeX > 0 && relativeX < canvas.width) {
        paddleX = relativeX - paddleWidth / 2;
    }
}
function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillRect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
    ctx.beginPath();
    ctx.arc(ballX, ballY, ballRadius, 0, Math.PI * 2);
    ctx.fillStyle = '#0095DD';
    ctx.fill();
    ctx.closePath();
    if (rightPressed && paddleX < canvas.width - paddleWidth) {
        paddleX += 5;
    }
    else if (leftPressed && paddleX > 0) {
        paddleX -= 5;
    }
    ballX += ballSpeedX;
    ballY += ballSpeedY;
    if (ballX + ballRadius > canvas.width || ballX - ballRadius < 0) {
        ballSpeedX = -ballSpeedX;
    }
    if (ballY + ballRadius > canvas.height || ballY - ballRadius < 0) {
        ballSpeedY = -ballSpeedY;
    }
    var collision = checkCollision(ballX, ballY, ballRadius);
    if (collision) {
        ballSpeedY = -ballSpeedY;
    }
    for (var c = 0; c < brickColumnCount; c++) {
        for (var r = 0; r < brickRowCount; r++) {
            var b = bricks[c][r];
            if (b.status == 1) {
                var brickX = (c * (brickWidth + brickPadding)) + brickOffsetLeft;
                var brickY = (r * (brickHeight + brickPadding)) + brickOffsetTop;
                ctx.beginPath();
                ctx.rect(brickX, brickY, brickWidth, brickHeight);
                ctx.fillStyle = '#0095DD';
                ctx.fill();
                ctx.closePath();
            }
        }
    }
    requestAnimationFrame(draw);
}
function checkCollision(x, y, radius) {
    for (var c = 0; c < brickColumnCount; c++) {
        for (var r = 0; r < brickRowCount; r++) {
            var b = bricks[c][r];
            if (b.status == 1) {
                var brickX = (c * (brickWidth + brickPadding)) + brickOffsetLeft;
                var brickY = (r * (brickHeight + brickPadding)) + brickOffsetTop;
                if (x > brickX && x < brickX + brickWidth &&
                    y > brickY && y < brickY + brickHeight) {
                    return true;
                }
            }
        }
    }
    return false;
}
draw();

五、总结

通过本文的学习,相信你已经掌握了 HTML5 Canvas 动画制作的基础知识和实战技巧。在实际应用中,你可以根据自己的需求对动画进行优化和扩展。希望这篇文章能对你有所帮助,祝你学习愉快!

分享到: