【canvas】动画
文章目录
- 动画基本步骤
- 动画示例
- 1. 时钟
- 2. 循环全景照片
- 3. 小球边界碰撞检测
动画基本步骤
- 清空 canvas :使用
clearRect
- 绘制动画图形: 这一步才是重绘动画帧
- 操控动画:定时执行重绘的方法,可以用
setInterval()
、setTimeout()
和requestAnimationFrame()
示例:
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制动画内容
requestAnimationFrame(draw);
}
draw();
动画示例
1. 时钟
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas Animation</title>
<style>
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" width="300" height="300">1</canvas>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
function draw() {
ctx.save();
ctx.clearRect(0, 0, 300, 300);
ctx.translate(150, 150);
ctx.rotate(-Math.PI / 2);
ctx.strokeStyle = "blue";
ctx.lineWidth = 8;
ctx.beginPath();
ctx.arc(0, 0, 100, 0, 2 * Math.PI);
ctx.stroke();
ctx.strokeStyle = "black";
ctx.lineCap = "round";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
for (let i = 0; i < 60; i++) {
ctx.beginPath();
if (i % 5 === 0) {
// 小时刻度
ctx.lineWidth = 4;
ctx.moveTo(90, 0);
ctx.lineTo(75, 0);
ctx.fillText(i / 5, 65, 0);
} else {
// 分钟刻度
ctx.lineWidth = 2;
ctx.moveTo(90, 0);
ctx.lineTo(85, 0);
}
ctx.stroke();
ctx.rotate(Math.PI / 30);
}
const time = new Date();
const seconds = time.getSeconds();
const minutes = time.getMinutes();
const hours = time.getHours();
// 时针
ctx.save();
ctx.rotate((Math.PI / 6) * hours + (Math.PI / 360) * minutes + (Math.PI / 21600) * seconds);
ctx.beginPath();
ctx.lineWidth = 8;
ctx.moveTo(-10, 0);
ctx.lineTo(60, 0);
ctx.stroke();
ctx.restore();
// 分针
ctx.save();
ctx.rotate((Math.PI / 30) * minutes + (Math.PI / 1800) * seconds);
ctx.beginPath();
ctx.lineWidth = 4;
ctx.moveTo(-15, 0);
ctx.lineTo(80, 0);
ctx.stroke();
ctx.restore();
// 秒针
ctx.save();
ctx.strokeStyle = "red";
ctx.rotate((Math.PI / 30) * seconds);
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(80, 0);
ctx.stroke();
ctx.restore();
ctx.restore();
requestAnimationFrame(draw);
}
draw();
</script>
</body>
</html>
2. 循环全景照片
图片地址:测试图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas Animation</title>
<style>
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" width="800" height="200">1</canvas>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const image = new Image();
image.src = "./assets/park.jpg";
var CanvasXSize = 800;
var CanvasYSize = 200;
var speed = 30;
var dx = 0.75;
var x = 0;
var imgW;
var imgH;
var clearX;
var clearY;
image.onload = () => {
imgW = image.width;
imgH = image.height;
if (imgW > CanvasXSize) {
clearX = imgW;
} else {
clearX = CanvasXSize;
}
if (imgH > CanvasYSize) {
clearY = imgH;
} else {
clearY = CanvasYSize;
}
setInterval(draw, speed);
};
function draw() {
ctx.clearRect(0, 0, clearX, clearY);
if (x > CanvasXSize) {
x = CanvasXSize - imgW;
}
// draw aditional image
if (x > CanvasXSize - imgW) {
ctx.drawImage(image, x - imgW + 1, 0, imgW, imgH);
}
ctx.drawImage(image, x, 0, imgW, imgH);
x += dx;
}
</script>
</body>
</html>
3. 小球边界碰撞检测
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>鼠标追踪动画</title>
<style>
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" width="600" height="400">1</canvas>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
var ball = {
x: 100,
y: 100,
radius: 25,
vx: 5,
vy: 2,
color: "blue",
draw: function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 长尾效果效果(注释上面clearRect)
// ctx.fillStyle = "rgba(255, 255, 255, 0.4)";
// ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
},
};
function anim() {
requestAnimationFrame(anim);
ball.draw();
ball.x += ball.vx;
ball.y += ball.vy;
ball.vy *= 0.99;
ball.vy += 0.25;
if (ball.x + ball.radius > canvas.width || ball.x - ball.radius < 0) {
ball.vx = -ball.vx;
}
if (ball.y + ball.radius > canvas.height || ball.y - ball.radius < 0) {
ball.vy = -ball.vy;
}
}
anim();
</script>
</body>
</html>