技术揭秘
在html5中,
初始化画布:设置画布尺寸,确保画布能够适应不同的屏幕大小。
定义烟花行为:通过编写javascript函数来定义烟花的运动轨迹、颜色和消失方式。
绘制烟花:使用路径(path)和填充(fill)命令在画布上绘制圆形,模拟烟花的爆炸效果。
动画循环:通过requestanimationframe实现动画循环,不断地更新和重绘烟花的位置和状态。
1、创建一个 index.html 复制以下代码
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.canvasbox {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
canvas {
border: 1px solid;
background-color: #000;
}
2、创建一个 index.js 复制以下代码
// 爆炸碎片类
class explosivedebris {
constructor(opt) {
this.firework = opt.firework
this.x = opt.x
this.y = opt.y
this.color = math.random() > 0.2 ? opt.color : '#fff'
this.radius = opt.radius || 2
this.angle = getrandom(0, 2 * math.pi)
this.speed = opt.speed || getrandom(0.1, 4)
this.vx = math.cos(this.angle) * this.speed
this.vy = math.sin(this.angle) * this.speed
this.g = opt.g || 0.98
this.time = getrandom(0.5, 1)
this.starttime = 0
// 痕迹碎片数量
this.debriscount = opt.debriscount || 3
// 是否要进行二次爆炸
this.secondburst = opt.secondburst || false
}
start() {
this.starttime = date.now()
}
update() {
const duration = (date.now() - this.starttime) / 1000
const vy = this.vy - this.g * duration
this.x = this.vx
this.y = vy
const progress = duration / this.time
let opacity = progress > 0.7 ? 1 - 1 * progress : 1
if (opacity < 0) opacity = 0
drawcircle({
x: this.x,
y: this.y,
color: this.color,
radius: this.radius,
opacity: opacity
})
// 添加痕迹碎片
if (this.debriscount > 0 && math.random() > 0.8) {
this.debriscount--
this.firework.adddebris({
x: this.x getrandom(-2, 2),
y: this.y getrandom(-2, 2),
color: this.color,
radius: 0.5,
g: 0.1
})
}
return {
x: this.x,
y: this.y,
isend: progress >= 1
}
}
}
// 爆炸器类
class explosive {
constructor(opt) {
this.firework = opt.firework
this.x = opt.x
this.y = opt.y
this.color = opt.color
// 爆炸碎片列表
this.debrislist = []
// 爆炸碎片数量
this.debrisnum = opt.debrisnum || getrandom(50, 400)
// 是否要二次爆炸
this.secondburst = opt.secondburst || this.debrisnum <= 100
//是否是第一次爆炸
this.isfirstburst = true
}
start(debrisnum, opt = {}) {
const num = debrisnum || this.debrisnum
opt.x = opt.x || this.x
opt.y = opt.y || this.y
opt.secondburst = this.secondburst && this.isfirstburst
for (let i = 0; i < num; i ) {
const explosivedebris = new explosivedebris({
firework: this.firework,
color: this.color,
...opt
})
explosivedebris.start()
this.debrislist.push(explosivedebris)
}
this.isfirstburst = false
}
update() {
const list = [...this.debrislist]
list.foreach(debris => {
const res = debris.update()
if (res.isend) {
deletefromlist(this.debrislist, debris)
// 二次爆炸
if (debris.secondburst) {
this.start(5, {
x: res.x,
y: res.y,
speed: 1
})
}
}
})
return {
isend: list.length <= 0
}
}
}
// 痕迹碎片类
class debris {
constructor(opt = {}) {
// 颜色
this.color = opt.color || '#fff'
// 透明度
this.opacity = getrandom(0.1, 0.5)
// 半径
this.radius = opt.radius || 1
// 存在时间
this.time = getrandom(0.5, 1)
// 重力,px/s2
this.g = opt.g || 0.98
// 位置
this.x = opt.x
this.y = opt.y
// 创建的时间
this.starttime = 0
}
start() {
this.starttime = date.now()
}
update() {
const duration = (date.now() - this.starttime) / 1000
this.y -= this.g * duration
drawcircle({
opacity: this.opacity,
x: this.x,
y: this.y,
radius: this.radius,
color: this.color
})
return {
x: this.x,
y: this.y,
isend: duration > this.time
}
}
}
// 发射器类
class launcher {
constructor(opt = {}) {
// 烟花实例
this.firework = opt.firework
// 颜色
this.color = opt.color
// 初始位置
this.x = opt.x || canvaswidth * getrandom(0.2, 0.8)
this.y = opt.y || 0
// 目标位置
this.ty = canvasheight * getrandom(0.6, 0.8)
// 半径
this.radius = opt.radius || getrandom(2, 5)
// 发射的持续时间
this.duration = opt.duration || getrandom(2000, 3500)
// 发射时的时间
this.starttime = 0
}
start() {
this.starttime = date.now()
}
easeoutcubic(t, b, c, d) {
return c * ((t = t / d - 1) * t * t 1) b
}
update() {
const x = this.x
let y = this.easeoutcubic(
date.now() - this.starttime,
this.y,
this.ty - this.y,
this.duration
)
y = math.min(y, this.ty)
// 透明度变小
let opacity = 1 - 1 * (y / this.ty)
if (opacity < 0) opacity = 0
this.draw(x, y, opacity)
// 添加痕迹碎片
if (math.random() > 0.7 && opacity >= 0.1) {
this.firework.adddebris({
x: x getrandom(-2, 2), // x坐标添加一段随机量
y
})
}
return {
x,
y,
isend: y >= this.ty //返回true代表发射结束
}
}
draw(x, y, opacity) {
// 外圆,烟花的颜色
drawcircle({
opacity: opacity,
x: x,
y: y,
radius: this.radius,
color: this.color
})
// 内圆,白色
drawcircle({
opacity: opacity,
x: x,
y: y,
radius: this.radius / 2,
color: '#fff'
})
}
}
// 烟花类
class firework {
constructor(opt = {}) {
// 颜色
this.color = opt.color || tinycolor.random().tohexstring()
// 发射器
this.launcher = null
// 爆炸器
this.explosive = null
// 烟花状态:waiting(等待发射)、launching(发射中)、bursting(爆炸中)、end(烟花结束)
this.status = 'waiting'
// 痕迹碎片列表
this.debrislist = []
}
// 发射
launch() {
this.launcher = new launcher({
firework: this,
color: this.color
})
this.launcher.start()
this.status = 'launching'
}
// 爆炸
burst({ x, y }) {
this.explosive = new explosive({
firework: this,
x,
y,
color: this.color
})
this.explosive.start()
}
// 更新
update() {
if (this.status === 'launching') {
const res = this.launcher.update()
if (res.isend) {
this.status = 'bursting'
this.burst(res)
}
} else if (this.status === 'bursting') {
const res = this.explosive.update()
if (res.isend) {
this.status = 'end'
}
}
// 更新痕迹碎片
this.updatedebris()
}
// 添加痕迹碎片
adddebris(opt = {}) {
const debris = new debris({
...opt,
color: opt.color || this.color
})
debris.start()
this.debrislist.push(debris)
}
// 更新痕迹碎片
updatedebris() {
const list = [...this.debrislist]
list.foreach(debris => {
const res = debris.update()
if (res.isend) {
deletefromlist(this.debrislist, debris)
}
})
}
isend() {
return this.status === 'end'
}
}
3、给自己放个烟花秀吧
创建一个文件夹,将以上两个文件 index.html & index.js 放到创建的文件夹中
在电脑端双击打开 index.html,即可在浏览器中打开页面,点击屏幕给自己放个烟花秀吧
!!!
免责声明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,云顶4008手机登录网页的版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!