下面就是JavaScript实现烟花绽放动画效果的完整攻略。
前置知识
在进行本教程之前,你需要掌握以下的前置知识:
- HTML、CSS基础
- JavaScript基础语法
- Canvas基础
如果你还不熟悉这些,可以先去学习一下。
实现思路
要实现烟花绽放动画效果,我们需要做以下的一些事情:
- 在页面中创建一个Canvas元素,用来绘制烟花图案。
- 监听鼠标点击事件,当用户点击页面时,在点击位置创建一个烟花。
- 在创建的烟花中,随机生成一些花瓣,然后让它们向外扩散。
- 在每个扩散的花瓣中再次生成一些小花瓣,让它们向外扩散。
- 等到所有花瓣都扩散完毕之后,烟花会变成一个白色的圆,然后逐渐消失。
下面我们就来一步一步实现这个效果。
步骤一:创建Canvas元素
首先在HTML的body中创建一个Canvas元素:
<canvas id="fireworks"></canvas>
然后在JavaScript中获取这个元素,并设置它的大小:
const canvas = document.getElementById('fireworks');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
步骤二:监听鼠标点击事件
接下来我们要监听鼠标点击事件,当用户点击页面时,就在点击位置创建一个烟花。这里我们可以使用canvas的addEventListener
方法来实现:
canvas.addEventListener('click', function(event) {
createFirework(event.clientX, event.clientY);
}, false);
这个方法会在canvas上监听鼠标点击事件,并在点击位置创建一个烟花。
步骤三:随机生成花瓣并扩散
在创建的烟花中,我们需要随机生成一些花瓣,并让它们向外扩散。我们可以先在烟花的构造函数中生成这些花瓣:
function Firework(x, y) {
this.x = x;
this.y = y;
this.age = 0;
this.lifespan = 100;
this.particles = [];
for (let i = 0; i < 100; i++) {
const particle = {
x: this.x,
y: this.y,
vx: Math.random() * 3 - 1.5,
vy: Math.random() * 3 - 1.5,
color: `hsl(${Math.random() * 360}, 50%, 50%)`
};
this.particles.push(particle);
}
}
这段代码会在烟花对象中创建一个particles
数组,并在其中生成100个花瓣。
然后,在烟花对象的update
方法中,我们需要让每个花瓣向外扩散:
Firework.prototype.update = function() {
for (let i = 0; i < this.particles.length; i++) {
const particle = this.particles[i];
particle.vx *= 0.9;
particle.vy *= 0.9;
particle.x += particle.vx;
particle.y += particle.vy;
particle.color = `hsl(${Math.random() * 360}, 50%, 50%)`;
}
this.age++;
};
这段代码会让每个花瓣的速度逐渐减小,并使其向外扩散。
步骤四:生成小花瓣并扩散
接下来我们要在每个扩散的花瓣中再次生成一些小花瓣,并让它们向外扩散。我们可以先在烟花对象的update
方法中,检查花瓣是否到达了极限速度,然后在它们的位置生成一些小花瓣:
Firework.prototype.update = function() {
for (let i = 0; i < this.particles.length; i++) {
const particle = this.particles[i];
particle.vx *= 0.9;
particle.vy *= 0.9;
particle.x += particle.vx;
particle.y += particle.vy;
particle.color = `hsl(${Math.random() * 360}, 50%, 50%)`;
if (Math.abs(particle.vx) < 0.05 && Math.abs(particle.vy) < 0.05) {
this.createParticles(particle.x, particle.y);
}
}
this.age++;
};
这段代码会在花瓣速度达到一定程度之后,在当前位置生成一些小花瓣。
然后,我们需要在烟花对象中添加一个方法createParticles
,用来生成小花瓣:
Firework.prototype.createParticles = function(x, y) {
for (let i = 0; i < 50; i++) {
const particle = {
x: x,
y: y,
vx: Math.random() * 3 - 1.5,
vy: Math.random() * 3 - 1.5,
color: `hsl(${Math.random() * 360}, 50%, 50%)`
};
this.particles.push(particle);
}
};
这段代码会在指定位置生成50个小花瓣,并加入到烟花对象的particles
数组中。
步骤五:变成白色圆并逐渐消失
等到所有花瓣都扩散完毕之后,烟花会变成一个白色的圆,然后逐渐消失。我们可以在烟花对象的update
方法中,检查是否到达了寿命极限,然后将烟花变成一个白色圆:
Firework.prototype.update = function() {
if (this.age > this.lifespan) {
this.particles = [{
x: this.x,
y: this.y,
vx: 0,
vy: 0,
color: '#ffffff'
}];
} else {
for (let i = 0; i < this.particles.length; i++) {
const particle = this.particles[i];
particle.vx *= 0.9;
particle.vy *= 0.9;
particle.x += particle.vx;
particle.y += particle.vy;
particle.color = `hsl(${Math.random() * 360}, 50%, 50%)`;
if (Math.abs(particle.vx) < 0.05 && Math.abs(particle.vy) < 0.05) {
this.createParticles(particle.x, particle.y);
}
}
this.age++;
}
};
这段代码会在烟花寿命结束之后,将烟花对象的particles
数组中只保留一个白色的花瓣。
然后,我们需要在烟花对象的draw
方法中,绘制花瓣:
Firework.prototype.draw = function(context) {
for (let i = 0; i < this.particles.length; i++) {
const particle = this.particles[i];
context.beginPath();
context.fillStyle = particle.color;
context.arc(particle.x, particle.y, 2, 0, Math.PI * 2, false);
context.fill();
}
};
这段代码会将烟花对象的所有花瓣绘制出来。
示例说明一:在火箭上实现烟花绽放
我们可以先在页面中创建一个火箭对象,然后让它在页面上飞行。当火箭到达指定位置时,就在它所在位置创建一个烟花对象。
可以参考以下的示例代码:
const canvas = document.getElementById('fireworks');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const context = canvas.getContext('2d');
class Rocket {
constructor(x, y, width, height, vx, vy) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.vx = vx;
this.vy = vy;
this.exploded = false;
this.explosion = null;
}
move() {
this.x += this.vx;
this.y += this.vy;
}
draw() {
if (this.exploded) {
this.explosion.draw(context);
} else {
context.fillStyle = '#000000';
context.fillRect(this.x, this.y, this.width, this.height);
}
}
checkPosition() {
if (this.y < window.innerHeight / 2) {
this.explode();
}
}
explode() {
this.exploded = true;
this.explosion = new Firework(this.x + this.width / 2, this.y + this.height);
}
}
class Firework {
constructor(x, y) {
this.x = x;
this.y = y;
this.age = 0;
this.lifespan = 100;
this.particles = [];
for (let i = 0; i < 100; i++) {
const particle = {
x: this.x,
y: this.y,
vx: Math.random() * 3 - 1.5,
vy: Math.random() * 3 - 1.5,
color: `hsl(${Math.random() * 360}, 50%, 50%)`
};
this.particles.push(particle);
}
}
createParticles(x, y) {
for (let i = 0; i < 50; i++) {
const particle = {
x: x,
y: y,
vx: Math.random() * 3 - 1.5,
vy: Math.random() * 3 - 1.5,
color: `hsl(${Math.random() * 360}, 50%, 50%)`
};
this.particles.push(particle);
}
}
update() {
if (this.age > this.lifespan) {
this.particles = [{
x: this.x,
y: this.y,
vx: 0,
vy: 0,
color: '#ffffff'
}];
} else {
for (let i = 0; i < this.particles.length; i++) {
const particle = this.particles[i];
particle.vx *= 0.9;
particle.vy *= 0.9;
particle.x += particle.vx;
particle.y += particle.vy;
particle.color = `hsl(${Math.random() * 360}, 50%, 50%)`;
if (Math.abs(particle.vx) < 0.05 && Math.abs(particle.vy) < 0.05) {
this.createParticles(particle.x, particle.y);
}
}
this.age++;
}
}
draw() {
for (let i = 0; i < this.particles.length; i++) {
const particle = this.particles[i];
context.beginPath();
context.fillStyle = particle.color;
context.arc(particle.x, particle.y, 2, 0, Math.PI * 2, false);
context.fill();
}
}
}
function animate() {
requestAnimationFrame(animate);
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
rocket.move();
rocket.draw();
rocket.checkPosition();
if (rocket.exploded) {
rocket.explosion.update();
rocket.explosion.draw();
}
}
const rocket = new Rocket(0, window.innerHeight - 50, 50, 50, 2, -5);
animate();
这段代码会创建一个Rocket对象,并让它在页面上飞行。当Rocket对象到达指定位置时,就在它所在位置创建一个烟花对象。
示例说明二:多个烟花同时绽放
我们可以在火箭到达指定位置之后,随机生成一些烟花对象。可以参考以下的示例代码:
const canvas = document.getElementById('fireworks');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const context = canvas.getContext('2d');
class Rocket {
constructor(x, y, width, height, vx, vy) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.vx = vx;
this.vy = vy;
this.exploded = false;
this.explosions = [];
}
move() {
this.x += this.vx;
this.y += this.vy;
}
draw() {
if (this.exploded) {
for (let i = 0; i < this.explosions.length; i++) {
this.explosions[i].draw(context);
}
} else {
context.fillStyle = '#000000';
context.fillRect(this.x, this.y, this.width, this.height);
}
}
checkPosition() {
if (this.y < window.innerHeight / 2) {
this.explode();
}
}
explode() {
this.exploded = true;
for (let i = 0; i < 10; i++) {
const explosion = new Firework(this.x + this.width / 2, this.y + this.height);
this.explosions.push(explosion);
}
}
}
class Firework {
constructor(x, y) {
this.x = x;
this.y = y;
this.age = 0;
this.lifespan = 100;
this.particles = [];
for (let i = 0; i < 100; i++) {
const particle = {
x: this.x,
y: this.y,
vx: Math.random() * 3 - 1.5,
vy: Math.random() * 3 - 1.5,
color: `hsl(${Math.random() * 360}, 50%, 50%)`
};
this.particles.push(particle);
}
}
createParticles(x, y) {
for (let i = 0; i < 50; i++) {
const particle = {
x: x,
y: y,
vx: Math.random() * 3 - 1.5,
vy: Math.random() * 3 - 1.5,
color: `hsl(${Math.random() * 360}, 50%, 50%)`
};
this.particles.push(particle);
}
}
update() {
if (this.age > this.lifespan) {
this.particles = [{
x: this.x,
y: this.y,
vx: 0,
vy: 0,
color: '#ffffff'
}];
} else {
for (let i = 0; i < this.particles.length; i++) {
const particle = this.particles[i];
particle.vx *= 0.9;
particle.vy *= 0.9;
particle.x += particle.vx;
particle.y += particle.vy;
particle.color = `hsl(${Math.random() * 360}, 50%, 50%)`;
if (Math.abs(particle.vx) < 0.05 && Math.abs(particle.vy) < 0.05) {
this.createParticles(particle.x, particle.y);
}
}
this.age++;
}
}
draw() {
for (let i = 0; i < this.particles.length; i++) {
const particle = this.particles[i];
context.beginPath();
context.fillStyle = particle.color;
context.arc(particle.x, particle.y, 2, 0, Math.PI * 2, false);
context.fill();
}
}
}
function animate() {
requestAnimationFrame(animate);
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
rocket.move();
rocket.draw();
rocket.checkPosition();
if (rocket.exploded) {
for (let i = 0; i < rocket.explosions.length; i++) {
rocket.explosions[i].update();
rocket.explosions[i].draw();
}
}
}
const rocket = new Rocket(0, window.innerHeight - 50, 50, 50, 2, -5);
animate();
这段代码会创建一个Rocket对象,并让它在页面上飞行。当Rocket对象到达指定位置时,会随机生成10个烟花对象。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript实现烟花绽放动画效果 - Python技术站