效果图镇楼
序
不知道是在什么时候,济南就开始都在传:“今年不再限制放烟花啦!”。一些集市上也开始有了售卖烟花的摊子
大家都很兴奋,很多小伙伴开始购买烟花。特别是今年特别火的 “加特林 😱”
但是大家兴奋劲还没过呢,随着官方 一纸禁令,让咱们知道了:
2023 过春年
烟花依然了无缘
让我们这些屯了烟花的可咋办啊 😭😭😭😭😭😭
不过身为程序猿的我们,能就这么认栽了?
我们可是要用代码改变世界的人啊~~~~
所以我辛苦闭关 九九八十一秒(开玩笑~我写了好几天),终于把烟花放到了浏览器上,看着效果我是“内牛满面(泪流满面)”啊!
此时,我真想仰天长啸,大声唱道:
2023 过春年,
烟花依然了无缘;
这能难倒程序猿?
一键三连过大年!
代码
下面开始上代码咯~~~
这个代码我写了详细备注,就给大家直接放出来(我不相信你们会跟着一步一步学😏😏😏😏😏😏)
代码一共分为三个文件:
1. html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>烟花特效</title>
<!-- CSS 必须得引入 -->
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- 烟花渲染区 -->
<canvas></canvas>
<!-- 文字修改区 -->
<div class="title">
<h2>LGD_Sunday 祝大家:</h2>
<h1>2023 新年快乐😃</h1>
</div>
<!-- JS 效果全靠它了 -->
<script src="./index.js"></script>
</body>
</html>
2. css
html,
body {
padding: 0px;
margin: 0px;
background: #222;
font-family: 'Karla', sans-serif;
color: #fff;
height: 100vh;
overflow: hidden;
}
.title {
z-index: 1000;
position: fixed;
bottom: 12px;
right: 12px;
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
border: 2px solid #fff;
padding: 7.5px 15px;
background: rgba(0, 0, 0, 0.5);
border-radius: 3px;
overflow: hidden;
}
h1 {
text-align: right;
font-size: 46px;
}
h2 {
font-size: 36px;
}
canvas {
width: 100%;
height: 100%;
}
3. JavaScript
// 获取 canvas 上下文,并指定宽高
let ctx = document.querySelector('canvas').getContext('2d')
ctx.canvas.width = window.innerWidth
ctx.canvas.height = window.innerHeight
// 初始爆炸数
const OVERLAP_NUM = 66
// 刷新速度 ms
const TIME_STEP = 16
// 烟花移动的速度与方向控制
const WALK = 0.2
// 火花数组
let sparks = []
// 烟花数组
let fireworks = []
// 对烟花进行填充
for (let i = 0; i < OVERLAP_NUM; i++) {
// 填充
fireworks.push(
// 构建随机位置
new Firework(
Math.random() * window.innerWidth,
Math.random() * window.innerHeight
)
)
}
/**
* 渲染函数
*/
function render() {
// 夜幕背景色与区域
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)
// 烟花上升
for (let firework of fireworks) {
if (firework.over) {
continue
}
firework.move()
firework.draw()
}
// 火花下坠
for (let spark of sparks) {
if (spark.over) {
continue
}
spark.move()
spark.draw()
}
// 通过随机数来控制烟花产生速度
if (Math.random() < 0.05) {
fireworks.push(new Firework())
}
// 重复渲染
setTimeout(render, TIME_STEP)
}
/**
* 火花构造
*/
function Spark(x, y, color) {
// 标记爆炸点位置与色值
this.x = x
this.y = y
this.color = color
// 位置
this.dir = Math.random() * (Math.PI * 2)
// 执行完毕
this.over = false
// 火花崩裂速度
this.speed = Math.random() * 3 + 3
// 火花下坠的速度
this.gravity = Math.random() + 0.1
// 火花消失的速度
this.countdown = this.speed * 10
/**
* 火花移动方法
*/
this.move = function () {
// 倒计时处理
this.countdown--
if (this.countdown < 0) {
this.over = true
}
// 速度递减
if (this.speed > 0) {
this.speed -= 0.1
}
if (this.speed < 0) {
return
}
// x、y 坐标位置
this.x += Math.cos(this.dir + WALK) * this.speed
this.y += Math.sin(this.dir + WALK) * this.speed
this.y += this.gravity
// 下坠速度加快
this.gravity += 0.05
}
/**
* 绘制
*/
this.draw = function () {
drawCircle(this.x, this.y, 3, this.color)
}
}
/**
* 烟花构造
*/
function Firework(x, y) {
// 初始点
this.x = x || Math.random() * ctx.canvas.width
this.y = y || ctx.canvas.height
// 爆炸点
this.burstLocation = (Math.random() * ctx.canvas.height) / 2
// 爆炸是否已完毕
this.over = false
// 烟花色
this.color = randomColor()
/**
* 移动的方法
*/
this.move = function () {
// 横向偏移
this.x += WALK
// 上升与爆炸
if (this.y > this.burstLocation) {
this.y -= 1
} else {
this.burst()
}
}
/**
* 持续绘制
*/
this.draw = function () {
drawCircle(this.x, this.y, 1.5, this.color)
}
/**
* 爆炸方法
*/
this.burst = function () {
// 标记爆炸完毕
this.over = true
// 碎裂烟花数
let i = Math.floor(Math.random() * 150) + 10
// 构建碎裂对象
while (i--) {
sparks.push(new Spark(this.x, this.y, this.color))
}
}
}
/**
* 持续绘制
*/
function drawCircle(x, y, radius, color) {
color = color
ctx.fillStyle = color
ctx.fillRect(x - radius / 2, y - radius / 2, radius, radius)
}
/**
* 生成随机色值
*/
function randomColor() {
const r = Math.floor(Math.random() * 255)
const g = Math.floor(Math.random() * 255)
const b = Math.floor(Math.random() * 255)
return `rgb(${r},${g},${b})`
}
// 开始
render()
总结
好像也没啥总结的是吧。
送上一句祝福:
LGD_Sunday 祝大家:新年快乐,兔年大吉!
2023 会是一个好的年度,一起加油