canvas实现烟花爆竹特效
AI 概述
这个 canvas 实现的烟花爆竹特效例子死我在网上收集的,效果很 high,关键是我想通过笨栗子来提高自己的 canvas,好了不多说了,基本的 canvas 语法就不和大家说了,我想看到这篇文章的人,基础已经学过了,所以直接上代码,看人家的思路就可以了。
CSS 代码:
body {
background: #000;
margin: 0;
}
canv...
这个 canvas 实现的烟花爆竹特效例子死我在网上收集的,效果很 high,关键是我想通过笨栗子来提高自己的 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;
结束语
效果很华丽,我只能帮到这里了,接下来就是看你得了,年轻人加油!
以上关于canvas实现烟花爆竹特效的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » canvas实现烟花爆竹特效
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » canvas实现烟花爆竹特效
微信
支付宝