canvas实现烟花爆竹特效

这个 canvas 实现的烟花爆竹特效例子死我在网上收集的,效果很 high,关键是我想通过笨栗子来提高自己的 canvas,好了不多说了,基本的 canvas 语法就不和大家说了,我想看到这篇文章的人,基础已经学过了,所以直接上代码,看人家的思路就可以了。

canvas 实现烟花爆竹特效

CSS 代码:

body {
    background: #000;
    margin: 0;
}
canvas {
    cursor: crosshair;
    display: block
}

HTML 代码:

<canvas id="canvas"></canvas>

Javascript 代码:

// 当在 canvas 上动画时,最好使用 requestAnimationFrame 而不是 setTimeout 或 setInterval

window.requestAnimFrame = (function () {

return window.requestAnimationFrame ||

window.webkitRequestAnimationFrame ||

window.mozRequestAnimationFrame ||

function (callback) {

window.setTimeout(callback, 1000 / 60);

};

})();

// 现在我们将为演示设置我们的基本变量

var canvas = document.getElementById('canvas'),

ctx = canvas.getContext('2d'),

// 全屏尺寸

cw = window.innerWidth,

ch = window.innerHeight,

//烟花汇集

fireworks = [],

// 颗粒收集

particles = [],

// 开始调色

hue = 120,

// 当点击发射烟花时,限制每 5 个循环一次启动一次

limiterTotal = 5,

limiterTick = 0,

// 自动启动烟花爆竹,每 80 个循环一次启动一次

timerTotal = 80,

timerTick = 0,

mousedown = false,

// 鼠标 x 坐标,mx,

// 鼠标 y 坐标, my;

// 设置画布尺寸

canvas.width = cw;

canvas.height = ch;

//现在我们要为整个演示设置我们的函数占位符

// 获得一个范围内的随机数

function random(min, max) {

return Math.random() * (max - min) + min;

}

// 计算两点之间的距离

function calculateDistance(p1x, p1y, p2x, p2y) {

var xDistance = p1x - p2x,

yDistance = p1y - p2y;

return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));

}

// 创造烟火

function Firework(sx, sy, tx, ty) {

// 实际坐标

this.x = sx;

this.y = sy;

// 开始坐标

this.sx = sx;

this.sy = sy;

// 目标坐标

this.tx = tx;

this.ty = ty;

// 从起点到目标的距离

this.distanceToTarget = calculateDistance(sx, sy, tx, ty);

this.distanceTraveled = 0;

// 跟踪每个烟花的过去坐标以创建尾迹效果,增加坐标数量以创建更显眼的尾迹

this.coordinates = [];

this.coordinateCount = 3;

// 用当前坐标填充初始坐标集合

while (this.coordinateCount--) {

this.coordinates.push([this.x, this.y]);

}

this.angle = Math.atan2(ty - sy, tx - sx);

this.speed = 2;

this.acceleration = 1.05;

this.brightness = random(50, 70);

// 圆圈目标指标半径

this.targetRadius = 1;

}

// 更新烟火

Firework.prototype.update = function (index) {

// 删除坐标数组中的最后一项

this.coordinates.pop();

// 将当前坐标添加到数组的开头

this.coordinates.unshift([this.x, this.y]);

// 循环圆目标指示半径

if (this.targetRadius < 8) {

this.targetRadius += 0.3;

} else {

this.targetRadius = 1;

}

// 加快烟火

this.speed *= this.acceleration;

// 根据角度和速度获取当前速度

var vx = Math.cos(this.angle) * this.speed,

vy = Math.sin(this.angle) * this.speed;

// 随着速度的施加,烟花会走多远?

this.distanceTraveled = calculateDistance(this.sx, this.sy, this.x + vx, this.y + vy);

// 如果行进的距离(包括速度)大于到目标的初始距离,则目标已达到

if (this.distanceTraveled >= this.distanceToTarget) {

createParticles(this.tx, this.ty);

// 删除烟花,使用传入更新函数的索引来确定要删除的内容

fireworks.splice(index, 1);

} else {

// 目标未达到,继续旅行

this.x += vx;

this.y += vy;

}

}

// 画烟花

Firework.prototype.draw = function () {

ctx.beginPath();

// 移动到集合中最后一个被跟踪的坐标,然后画一条线到当前的 x 和 y

ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][

1

]);

ctx.lineTo(this.x, this.y);

ctx.strokeStyle = 'hsl(' + hue + ', 100%, ' + this.brightness + '%)';

ctx.stroke();

ctx.beginPath();

// 用脉冲圈画出这个烟花的目标

ctx.arc(this.tx, this.ty, this.targetRadius, 0, Math.PI * 2);

ctx.stroke();

}

// 创造粒子

function Particle(x, y) {

this.x = x;

this.y = y;

// 跟踪每个粒子的过去坐标以创建一个跟踪效果,增加坐标数量以创建更显眼的轨迹

this.coordinates = [];

this.coordinateCount = 5;

while (this.coordinateCount--) {

this.coordinates.push([this.x, this.y]);

}

// 在所有可能的方向上以弧度设置一个随机角度

this.angle = random(0, Math.PI * 2);

this.speed = random(1, 10);

// 摩擦会减慢粒子的速度

this.friction = 0.95;

// 重力将被应用并将粒子拉下

this.gravity = 1;

// 将色调设置为整个色调变量的随机数字+20

this.hue = random(hue - 20, hue + 20);

this.brightness = random(50, 80);

this.alpha = 1;

// 设置粒子消失的速度

this.decay = random(0.015, 0.03);

}

// 更新粒子

Particle.prototype.update = function (index) {

// 删除坐标数组中的最后一项

this.coordinates.pop();

// 将当前坐标添加到数组的开头

this.coordinates.unshift([this.x, this.y]);

// 减慢粒子

this.speed *= this.friction;

// 施加速度

this.x += Math.cos(this.angle) * this.speed;

this.y += Math.sin(this.angle) * this.speed + this.gravity;

// 淡出粒子

this.alpha -= this.decay;

// 基于传入的索引,一旦 alpha 足够低,就移除粒子

if (this.alpha <= this.decay) {

particles.splice(index, 1);

}

}

// 画出粒子

Particle.prototype.draw = function () {

ctx.beginPath();

// 移动到集合中最后一个跟踪的坐标,然后画一条线到当前的 x 和 y

ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][

1

]);

ctx.lineTo(this.x, this.y);

ctx.strokeStyle = 'hsla(' + this.hue + ', 100%, ' + this.brightness + '%, ' + this.alpha + ')';

ctx.stroke();

}

// 创建粒子群/爆炸

function createParticles(x, y) {

//增加更大的爆炸颗粒数量,但要注意增加颗粒的帆布性能

var particleCount = 30;

while (particleCount--) {

particles.push(new Particle(x, y));

}

}

// 主演示循环

function loop() {

// 这个函数将在 requestAnimationFrame 中运行

requestAnimFrame(loop);

//随着时间的推移,增加色彩以获得不同颜色的烟花

hue += 0.5;

// 通常,clearRect()将用于清除画布

// 我们想要创建一个拖尾效果

// 将复合操作设置为 destination-out 将允许我们以特定的不透明度清除画布,而不是完全擦除画布

ctx.globalCompositeOperation = 'destination-out';

// 减少 alpha 属性以创建更显着的路径

ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';

ctx.fillRect(0, 0, cw, ch);

// 将复合操作更改回主模式

// 当烟火和微粒相互重叠时,打火机会产生明亮的高光点

ctx.globalCompositeOperation = 'lighter';

var text = "HAPPY NEW YEAR !";

ctx.font = "50px sans-serif";

var textData = ctx.measureText(text);

ctx.fillStyle = "rgba(" + parseInt(random(0, 255)) + "," + parseInt(random(0, 255)) + "," + parseInt(random(0,

255)) + ",0.3)";

ctx.fillText(text, cw / 2 - textData.width / 2, ch / 2);

//循环遍历每个烟花,绘制它,更新它

var i = fireworks.length;

while (i--) {

fireworks[i].draw();

fireworks[i].update(i);

}

// 循环遍历每个粒子,绘制它,更新它

var i = particles.length;

while (i--) {

particles[i].draw();

particles[i].update(i);

}

//当鼠标未关闭时,自动将烟火发射到随机坐标

if (timerTick >= timerTotal) {

if (!mousedown) {

// 在屏幕的中下部开始烟火,然后设置随机目标坐标,随机 y 坐标将设置在屏幕上半部分的范围内

for (var h = 0; h < 50; h++) {

fireworks.push(new Firework(cw / 2, ch / 2, random(0, cw), random(0, ch)));

}

timerTick = 0;

}

} else {

timerTick++;

}

// 限制鼠标关闭时启动烟花的速度

if (limiterTick >= limiterTotal) {

if (mousedown) {

// 在屏幕底部中间启动烟火,然后将当前鼠标坐标设置为目标

fireworks.push(new Firework(cw / 2, ch / 2, mx, my));

limiterTick = 0;

}

} else {

limiterTick++;

}

}

// 鼠标事件绑定

// 更新 mousemove 上的鼠标坐标

canvas.addEventListener('mousemove', function (e) {

mx = e.pageX - canvas.offsetLeft;

my = e.pageY - canvas.offsetTop;

});

// 切换 mousedown 状态并防止选择画布

canvas.addEventListener('mousedown', function (e) {

e.preventDefault();

mousedown = true;

});

canvas.addEventListener('mouseup', function (e) {

e.preventDefault();

mousedown = false;

});

// 一旦窗户加载,我们准备好了一些烟花!

window.onload = loop;

结束语

效果很华丽,我只能帮到这里了,接下来就是看你得了,年轻人加油!

「点点赞赏,手留余香」

4

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » canvas实现烟花爆竹特效

发表回复