新年的钟声即将敲响,绚丽的烟花在夜空中绽放,将节日氛围拉满。想不想把这美好的一幕搬到你的网页上,下面跟着小编用 HTML 和 JavaScript 打造出专属的新春烟花特效吧,制造属于IT的浪漫吧!朋友们
一、准备舞台:搭建 HTML 基础框架
就像举办一场烟花秀需要一个空旷的场地,我们的新春烟花特效也需要一个 "舞台",这就是 HTML 页面。先看下面这段代码,它就是我们搭建的 "舞台" 基础:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>新春烟花🎆</title>
 <style>
  body {
  margin: 0;
  overflow: hidden;
  background: #000;
  }
  canvas {
  display: block;
  }
  </style>
</head>
<body>
<canvas id="fireworksCanvas"></canvas>
<script>
  // 这里开始写JavaScript代码
</script>
</body>
</html>
HTML 基本结构 :<!DOCTYPE html>
声明这是一个 HTML5 文档。<html lang="zh-CN">
表示文档语言是中文,就像告诉浏览器 "我们要说中文啦"。
页面头部设置 :<head>
标签里的内容是对页面的一些设置。<meta charset="UTF-8">
确保页面能正确显示中文字符,不然可能会出现乱码。<meta name="viewport" content="width=device-width, initial-scale=1.0">
让页面能适配不同尺寸的屏幕,不管是电脑、平板还是手机,都能完美展示。<title>新春烟花🎆</title>
给页面取了个名字,当你把页面最小化,在任务栏看到的就是这个标题。
页面样式设置 :<style>
标签里设置了页面的样式。body
部分,margin: 0;
去掉了页面默认的边距,让页面更紧凑;overflow: hidden;
隐藏了页面的滚动条,因为我们的烟花秀不需要滚动条来打扰;background: #000;
把背景设置成黑色,就像夜晚的天空,这样烟花会更醒目。canvas
部分,display: block;
让<canvas>
元素以块级元素显示,为后面绘制烟花做好准备。
搭建画布 :<body>
标签里的<canvas id="fireworksCanvas"></canvas>
创建了一个画布,id
为fireworksCanvas
,这就像是我们画画用的白纸,之后的烟花都会在这个画布上绘制。<script>
标签是我们放 JavaScript 代码的地方,这里先空着,等下再 "大展身手"。
二、注入灵魂:编写 JavaScript 代码
HTML 搭建好舞台后,接下来就要用 JavaScript 给这个舞台注入灵魂,让烟花在上面绽放。
1. 获取画布并设置尺寸
html
const canvas = document.getElementById("fireworksCanvas");
const ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
这几行代码就像找到了我们刚刚搭建的画布,并根据浏览器窗口的大小调整画布的尺寸,这样不管窗口怎么变化,烟花都能完美铺满整个屏幕。document.getElementById("fireworksCanvas")
通过id
找到了<canvas>
元素,canvas.getContext("2d")
获取了二维绘图上下文,就像是拿到了一支画笔,准备在画布上作画。canvas.width
和canvas.height
设置了画布的宽和高,让画布和浏览器窗口一样大。
2. 定义烟花类
html
class Firework {
  constructor(x, y, color, velocity, size) {
  this.x = x;
  this.y = y;
  this.color = color;
  this.velocity = velocity;
  this.size = size;
  this.opacity = 1;
  }
  draw() {
  ctx.save();
  ctx.globalAlpha = this.opacity;
  ctx.beginPath();
  ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
  ctx.fillStyle = this.color;
  ctx.fill();
  ctx.restore();
  }
  update() {
  this.x += this.velocity.x;
  this.y += this.velocity.y;
  this.velocity.y += gravity;
  this.opacity -= 0.01;
  }
}
Firework
类就像是烟花的 "制造工厂",每个烟花都由这个类创建。constructor
是构造函数,就像工厂的生产线,创建烟花时会设置烟花的初始位置(x, y)
、颜色color
、速度velocity
、大小size
和透明度opacity
。draw
方法是烟花的 "绘制蓝图",它告诉计算机怎么在画布上画出烟花,通过设置透明度、绘制圆形并填充颜色来实现。update
方法则是烟花的 "运动指南",它让烟花按照一定的速度和重力移动,并且随着时间推移逐渐变淡。
3. 创建烟花
html
function createFirework(x, y) {
  const colors = ["#FF5733", "#FFBD33", "#33FF57", "#33D4FF", "#AF33FF", "#FF33A6"];
  const particles = [];
  const particleCount = 100;
  for (let i = 0; i < particleCount; i++) {
  constangle = Math.random() * Math.PI * 2;
  constspeed = Math.random() * 4 + 2;
  constvelocity = {x:Math.cos(angle) * speed, y:Math.sin(angle) * speed };
  constsize = Math.random() * 2 + 1;
  constcolor = colors[Math.floor(Math.random() * colors.length)];
  particles.push(newFirework(x, y, color, velocity, size));
  }
  fireworks.push(...particles);
}
createFirework
函数就像是烟花的 "发射按钮",它会在指定位置(x, y)
创建一个烟花。这里定义了一个颜色数组colors
,里面存放了各种绚丽的颜色,就像一个颜料盒。通过循环particleCount
次,每次随机生成角度、速度、大小和颜色,创建出不同的烟花粒子,最后把这些粒子组成一个烟花并添加到fireworks
数组里。
4. 绘制文字
html
function drawMessage() {
  if (message && messageOpacity > 0) {
  ctx.save();
  ctx.globalAlpha = messageOpacity;
  ctx.fillStyle = "gold";
  ctx.font = "bold 48px 微软雅黑, SimHei, Arial, sans-serif";
  ctx.textAlign = "center";
  // 将文字放到画布的正中央
  ctx.fillText(message, canvas.width / 2, canvas.height / 2);
  ctx.restore();
  }
}
drawMessage
函数就像是在烟花秀现场挂了一个横幅,它会在画布上绘制文字。当message
存在且文字透明度messageOpacity
大于 0 时,设置文字的颜色、字体、对齐方式,然后把文字绘制在画布的正中央。
5. 动画循环
html
function animate() {
  ctx.fillStyle = "rgba(0, 0, 0, 0.2)";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  fireworks.forEach((firework, index) => {
  if (firework.opacity <= 0) {
  fireworks.splice(index, 1);
  } else {
  firework.update();
  firework.draw();
  }
  });
  drawMessage();
  if (messageOpacity > 0) {
  messageOpacity -= 0.01; // 文字逐渐淡出
  }
  requestAnimationFrame(animate);
}
animate
函数是整个烟花秀的 "总指挥",它会不断地重复执行,让烟花持续绽放。首先,用一个半透明的黑色矩形覆盖画布,就像清理舞台,准备下一次表演。然后遍历fireworks
数组,对每个烟花进行更新和绘制,如果烟花的透明度小于等于 0,就把它从数组中移除。接着调用drawMessage
函数绘制文字,并且让文字的透明度逐渐降低,实现文字淡出效果。最后,通过requestAnimationFrame(animate)
请求浏览器在下一次重绘之前调用animate
函数,形成动画循环。
6. 触发烟花和文字显示
html
// 初始加载时,立即触发一次烟花效果和文字显示
const initialFirework = () => {
  const x = Math.random() * canvas.width;
  const y = Math.random() * canvas.height;
  createFirework(x, y);
  // 显示"新春快乐"
  message = "IT小本本 祝 大家新春快乐!";
  messageOpacity = 1; // 重置文字透明度
  messageTimer = 0; // 重置计时器
}
// 页面加载时,立即执行一次效果
initialFirework();
// 每隔1秒触发一次烟花效果和文字显示
setInterval(() => {
  const x = Math.random() * canvas.width;
  const y = Math.random() * canvas.height;
  createFirework(x, y);
  // 显示"新春快乐"
  message = "IT小本本 祝 大家新春快乐!";
  messageOpacity = 1; // 重置文字透明度
  messageTimer = 0; // 重置计时器
}, 10); // 每秒执行一次
window.addEventListener("resize", () => {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
});
animate();
这部分代码就像是烟花秀的 "开场哨" 和 "定时炸弹"。initialFirework
函数在页面初始加载时被调用,随机在画布上的某个位置创建一个烟花,并显示 " 祝 大家新春快乐!" 的文字。setInterval
函数就像一个定时闹钟,每隔 1 秒(这里设置为 10 毫秒,实际测试中可根据需要调整,可能设置 1000 毫秒即 1 秒效果更好)就会触发一次,随机创建一个烟花并显示文字。window.addEventListener("resize", () => {... })
监听窗口大小变化,当窗口大小改变时,重新设置画布的尺寸,保证烟花始终能完美显示。最后调用animate
函数,运行烟花秀。
还没学会的同学,复制下面代码,然后保存为.html文件,浏览器打开就可以看到效果了!!
完整详细代码:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</style>
<title>新春烟花🎆</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #000;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="fireworksCanvas"></canvas>
<script>
const canvas = document.getElementById("fireworksCanvas");
const ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const fireworks = [];
const gravity = 0.05;
let message = null; // 当前文字信息
let messageOpacity = 0; // 文字透明度
let messageTimer = 0; // 文字显示计时器
class Firework {
constructor(x, y, color, velocity, size) {
this.x = x;
this.y = y;
this.color = color;
this.velocity = velocity;
this.size = size;
this.opacity = 1;
}
draw() {
ctx.save();
ctx.globalAlpha = this.opacity;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.fill();
ctx.restore();
}
update() {
this.x += this.velocity.x;
this.y += this.velocity.y;
this.velocity.y += gravity;
this.opacity -= 0.01;
}
}
function createFirework(x, y) {
const colors = ["#FF5733", "#FFBD33", "#33FF57", "#33D4FF", "#AF33FF", "#FF33A6"];
const particles = [];
const particleCount = 100;
for (let i = 0; i < particleCount; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = Math.random() * 4 + 2;
const velocity = { x: Math.cos(angle) * speed, y: Math.sin(angle) * speed };
const size = Math.random() * 2 + 1;
const color = colors[Math.floor(Math.random() * colors.length)];
particles.push(new Firework(x, y, color, velocity, size));
}
fireworks.push(...particles);
}
function drawMessage() {
if (message && messageOpacity > 0) {
ctx.save();
ctx.globalAlpha = messageOpacity;
ctx.fillStyle = "gold";
ctx.font = "bold 48px 微软雅黑, SimHei, Arial, sans-serif";
ctx.textAlign = "center";
// 将文字放到画布的正中央
ctx.fillText(message, canvas.width / 2, canvas.height / 2);
ctx.restore();
}
}
function animate() {
ctx.fillStyle = "rgba(0, 0, 0, 0.2)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
fireworks.forEach((firework, index) => {
if (firework.opacity <= 0) {
fireworks.splice(index, 1);
} else {
firework.update();
firework.draw();
}
});
drawMessage();
if (messageOpacity > 0) {
messageOpacity -= 0.01; // 文字逐渐淡出
}
requestAnimationFrame(animate);
}
// 初始加载时,立即触发一次烟花效果和文字显示
const initialFirework = () => {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height;
createFirework(x, y);
// 显示"新春快乐"
message = "IT小本本 祝 大家新春快乐!";
messageOpacity = 1; // 重置文字透明度
messageTimer = 0; // 重置计时器
}
// 页面加载时,立即执行一次效果
initialFirework();
// 每隔1秒触发一次烟花效果和文字显示
setInterval(() => {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height;
createFirework(x, y);
// 显示"新春快乐"
message = "IT小本本 祝 大家新春快乐!";
messageOpacity = 1; // 重置文字透明度
messageTimer = 0; // 重置计时器
}, 10); // 每秒执行一次
window.addEventListener("resize", () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
animate();
</script>
</body>
</html>