2023 过春年,烟花依然了无缘;这能难倒程序猿?一键三连过大年!

效果图镇楼

在这里插入图片描述

不知道是在什么时候,济南就开始都在传:“今年不再限制放烟花啦!”。一些集市上也开始有了售卖烟花的摊子

image.png

大家都很兴奋,很多小伙伴开始购买烟花。特别是今年特别火的 “加特林 😱”

image.png

但是大家兴奋劲还没过呢,随着官方 一纸禁令,让咱们知道了:

2023 过春年

烟花依然了无缘

image.png

让我们这些屯了烟花的可咋办啊 😭😭😭😭😭😭

image.png

不过身为程序猿的我们,能就这么认栽了?

我们可是要用代码改变世界的人啊~~~~

image.png

所以我辛苦闭关 九九八十一秒(开玩笑~我写了好几天),终于把烟花放到了浏览器上,看着效果我是“内牛满面(泪流满面)”啊!

image.png

此时,我真想仰天长啸,大声唱道:

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 会是一个好的年度,一起加油

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Sunday

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值