我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛
一转眼2023年就过去半个月了,还清晰地记得除夕那天晚上的烟花,因此用canvas来写个烟花纪念一下.
实现过程
前期工作我们需要准备好,必须有 <canvas id="fireworks"></canvas>,同时将整个文档的背景色设置为黑色,接下来就是随机数生成每个烟花粒子的数据,同时需要将粒子数据不断地进行变化且重复绘制.
1.获取屏幕的宽度在进行改变屏幕需要重新执行,同时初始化数据
var SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight,
mousePos = {
x: 400,
y: 300
},
canvas = document.getElementById("fireworks"),
context = canvas.getContext("2d"),
particles = [],
rockets = [],
MAX_PARTICLES = 400,
colorCode = 0;
2.执行我们生产烟花粒子数据的函数和循环渲染的函数.
window.onload = function () {
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
setInterval(launch, 800);
setInterval(loop, 1000 / 50);
};
3.生成烟花粒子数据
function launch() {
launchFrom(mousePos.x);
}
function launchFrom(x) {
if (rockets.length < 10) {
var rocket = new Rocket(x);
rocket.explosionColor = Math.floor((Math.random() * 360) / 10) * 10;
rocket.vel.y = Math.random() * -3 - 4;
rocket.vel.x = Math.random() * 6 - 3;
rocket.size = 8;
rocket.shrink = 0.999;
rocket.gravity = 0.01;
rockets.push(rocket);
}
}
4.循环改变粒子数据和重复渲染,在每一次执行完之后需要清空整个的canvas画布,使他动态的改变达到烟花火流动的效果.
function loop() {
// update screen size
if (SCREEN_WIDTH !== window.innerWidth) {
canvas.width = SCREEN_WIDTH = window.innerWidth;
}
if (SCREEN_HEIGHT !== window.innerHeight) {
canvas.height = SCREEN_HEIGHT = window.innerHeight;
}
// clear canvas
context.fillStyle = "rgba(0, 0, 0, 0.05)";
context.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
var existingRockets = [];
for (var i = 0; i < rockets.length; i++) {
// update and render
rockets[i].update();
rockets[i].render(context);
// calculate distance with Pythagoras
var distance = Math.sqrt(
Math.pow(mousePos.x - rockets[i].pos.x, 2) +
Math.pow(mousePos.y - rockets[i].pos.y, 2)
);
// random chance of 1% if rockets is above the middle
var randomChance =
rockets[i].pos.y < (SCREEN_HEIGHT * 2) / 3
? Math.random() * 100 <= 1
: false;
/* Explosion rules
- 80% of screen
- going down
- close to the mouse
- 1% chance of random explosion
*/
if (
rockets[i].pos.y < SCREEN_HEIGHT / 5 ||
rockets[i].vel.y >= 0 ||
distance < 50 ||
randomChance
) {
rockets[i].explode();
} else {
existingRockets.push(rockets[i]);
}
}
}