HTML5 Canvas 烟花动画代码示例 - 炫酷特效实现
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>放烟花</title>
<style>
body {
background-color: black;
}
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
</style>
</head>
<body>
<canvas></canvas>
<pre><code><script>
// 烟花数量
var fireworksCount = 20;
// 烟花数组
var fireworks = [];
// 页面加载完成后执行
window.onload = function() {
// 获取canvas元素
var canvas = document.getElementsByTagName('canvas')[0];
// 设置canvas宽度和高度
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 获取2d上下文
var ctx = canvas.getContext('2d');
// 创建烟花
for (var i = 0; i < fireworksCount; i++) {
fireworks.push(new Firework(Math.random() * canvas.width, canvas.height));
}
// 执行动画
requestAnimationFrame(function animate() {
// 清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 更新并绘制烟花
for (var i = 0; i < fireworksCount; i++) {
fireworks[i].update();
fireworks[i].draw(ctx);
}
// 继续执行动画
requestAnimationFrame(animate);
});
};
// 烟花类
function Firework(x, y) {
// 烟花位置
this.x = x;
this.y = y;
// 烟花速度
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * -30;
// 烟花颜色
this.color = 'hsl(' + Math.random() * 360 + ', 100%, 50%)';
// 烟花爆炸半径
this.radius = 2;
// 烟花碎片数组
this.particles = [];
// 烟花是否已经爆炸
this.exploded = false;
}
// 更新烟花
Firework.prototype.update = function() {
// 如果烟花还没有爆炸
if (!this.exploded) {
// 更新速度
this.x += this.vx;
this.y += this.vy;
// 更新加速度
this.vy += 1;
// 如果烟花到达顶部,触发爆炸
if (this.vy >= 0) {
this.explode();
}
}
// 如果烟花已经爆炸
if (this.exploded) {
// 更新碎片
for (var i = 0; i < this.particles.length; i++) {
this.particles[i].update();
}
// 如果所有碎片都已经消失,把烟花从数组中移除
if (this.particles.length === 0) {
fireworks.splice(fireworks.indexOf(this), 1);
}
}
};
// 绘制烟花
Firework.prototype.draw = function(ctx) {
// 如果烟花还没有爆炸
if (!this.exploded) {
// 绘制圆形烟花
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.fill();
}
// 如果烟花已经爆炸
if (this.exploded) {
// 绘制碎片
for (var i = 0; i < this.particles.length; i++) {
this.particles[i].draw(ctx);
}
}
};
// 爆炸
Firework.prototype.explode = function() {
// 添加碎片
for (var i = 0; i < 50; i++) {
this.particles.push(new Particle(this.x, this.y, this.color));
}
// 标记烟花已经爆炸
this.exploded = true;
};
// 碎片类
function Particle(x, y, color) {
// 碎片位置
this.x = x;
this.y = y;
// 碎片速度
this.vx = Math.random() * 6 - 3;
this.vy = Math.random() * 6 - 3;
// 碎片颜色
this.color = color;
// 碎片半径
this.radius = 2;
// 碎片生命值
this.life = 100;
}
// 更新碎片
Particle.prototype.update = function() {
// 更新速度
this.x += this.vx;
this.y += this.vy;
// 更新生命值
this.life--;
// 更新透明度
var alpha = this.life / 100;
// 如果碎片透明度小于0,把碎片从数组中移除
if (alpha <= 0) {
this.alpha = 0;
this.radius = 0;
this.vx = 0;
this.vy = 0;
this.color = '';
this.life = 0;
this.remove();
}
};
// 绘制碎片
Particle.prototype.draw = function(ctx) {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(' + hexToRgb(this.color).r + ',' + hexToRgb(this.color).g + ',' + hexToRgb(this.color).b + ',' + this.life / 100 + ')';
ctx.fill();
};
// 从数组中移除
Particle.prototype.remove = function() {
this.particles.splice(this.particles.indexOf(this), 1);
};
// 将16进制颜色转换为rgb颜色
function hexToRgb(hex) {
var r = parseInt(hex.substring(1, 3), 16);
var g = parseInt(hex.substring(3, 5), 16);
var b = parseInt(hex.substring(5, 7), 16);
return {r: r, g: g, b: b};
}
</script>
</code></pre>
</body>
</html>
原文地址: https://www.cveoy.top/t/topic/n5fb 著作权归作者所有。请勿转载和采集!