过年了,一起来放鞭炮吗?
? 提前祝大家新年快乐呀,不知道大家有没有这样的感觉,为什么越长大,越觉得过年没有了年味?回想小时候和小伙伴们一起拿着鞭炮到田里看到什么炸什么的日子,还真是遥远,现在是无法在像一起那样了,那么就在网上来一起放鞭炮吧!
预览
实现
一、vue实现
template
<template>
<div id="app">
<div class="firecrackers">
<div class="Stick"></div>
<div class="line">
<div v-for="n in crackerNum" :key="n" class="cracker"></div>
<div class="fire" v-for="n in 10" :key="n"></div>
<audio
src="./assets/鞭炮声.mp3"
controls="controls"
preload
id="music"
hidden
></audio>
</div>
</div>
<div class="play" @click="play()">点炮竹</div>
</div>
</template>
script
初始化鞭炮的样式
初始化鞭炮的样式,让鞭炮左右倾斜排布。
initCrackers() {
let crackers = document.getElementsByClassName("cracker");
let num = 0;
let j = 0;
while (crackers.length > j) {
for (let i = 0; i < 2; ++i) {
let cracker = crackers[j];
j++;
cracker.style.top = num * this.crackerHeight + "px";
if (j % 2 == 0) {
cracker.style.transform = "rotate(30deg)";
cracker.style.left = "-5px";
} else {
cracker.style.transform = "rotate(-30deg)";
}
}
num++;
}
},
初始化火花
初始化火花,生成一定范围内随机排布的火花
initFires() {
let fires = document.getElementsByClassName("fire");
for (let i = 0; i < fires.length; i++) {
fires[i].style.top =
this.crackerHeight * (this.crackerNum / 2) +
parseFloat(this.getRandom(2)) +
"px";
fires[i].style.left = parseFloat(this.getRandom(10)) + "px";
}
},
getRandom(n) {
let r = Math.random() * n;
let flag = Math.random();
if (flag > 0.5) return -r;
return r;
},
},
点燃鞭炮
点击燃烧鞭炮,添加飘落效果和鞭炮声
play(len = "") {
let crackers = document.getElementsByClassName("cracker");
let fires = document.getElementsByClassName("fire");
let audio = document.getElementById("music");
if (audio.paused) {
audio.play();
}
if (len == "") len = crackers.length - 1;
crackers[len].classList.add("to-smoke");
crackers[len - 1].classList.add("to-smoke");
setTimeout(() => {
crackers[len].remove();
crackers[len - 1].remove();
}, 5000);
for (let i = 0; i < fires.length; i++) {
fires[i].style.display = "block";
fires[i].style.top =
parseInt(fires[i].style.top) - this.crackerHeight + "px";
}
setTimeout(() => {
if (len - 2 >= 0) {
this.play(len - 2);
} else {
for (let i = fires.length - 1; i >= 0; i--) {
fires[i].remove();
audio.pause();
}
}
}, this.speed);
},
css
粒子闪烁动画简单模拟火花
@keyframes fireAni {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
鞭炮燃烧后飘落效果
@keyframes smoky {
to {
background-color: whitesmoke;
transform: translate3d(200px, 80px, 0) rotate(-40deg) skewX(70deg)
scale(1.5);
text-shadow: 0 0 20px whitesmoke;
opacity: 0;
}
}
完整代码
<template>
<div id="app">
<div class="firecrackers">
<div class="Stick"></div>
<div class="line">
<div v-for="n in crackerNum" :key="n" class="cracker"></div>
<div class="fire" v-for="n in 10" :key="n"></div>
<audio
src="./assets/鞭炮声.mp3"
controls="controls"
preload
id="music"
hidden
></audio>
</div>
</div>
<div class="play" @click="play()">点炮竹</div>
</div>
</template>
<script>
export default {
name: "app",
components: {},
data() {
return {
crackerHeight: 12, //炮竹高度
speed: 200, //燃烧速度ms
crackerNum: 80, //炮竹数量
};
},
methods: {
init() {
this.initCrackers();
this.initFires();
this.initLine();
},
//点炮竹
play(len = "") {
let crackers = document.getElementsByClassName("cracker");
let fires = document.getElementsByClassName("fire");
let audio = document.getElementById("music");
if (audio.paused) {
audio.play(); // 播放
}
if (len == "") len = crackers.length - 1;
crackers[len].classList.add("to-smoke");
crackers[len - 1].classList.add("to-smoke");
setTimeout(() => {
crackers[len].remove();
crackers[len - 1].remove();
}, 5000);
for (let i = 0; i < fires.length; i++) {
fires[i].style.display = "block";
fires[i].style.top =
parseInt(fires[i].style.top) - this.crackerHeight + "px";
}
setTimeout(() => {
if (len - 2 >= 0) {
this.play(len - 2);
} else {
for (let i = fires.length - 1; i >= 0; i--) {
fires[i].remove();
audio.pause();
}
}
}, this.speed);
},
//初始化炮竹
initCrackers() {
let crackers = document.getElementsByClassName("cracker");
let num = 0;
let j = 0;
while (crackers.length > j) {
for (let i = 0; i < 2; ++i) {
let cracker = crackers[j];
j++;
cracker.style.top = num * this.crackerHeight + "px";
if (j % 2 == 0) {
cracker.style.transform = "rotate(30deg)";
cracker.style.left = "-5px";
} else {
cracker.style.transform = "rotate(-30deg)";
}
}
num++;
}
},
//初始化炮竹线
initLine() {
let line = document.getElementsByClassName("line")[0];
line.style.height = this.crackerHeight * (this.crackerNum / 2) + "px";
},
//初始化火花
initFires() {
let fires = document.getElementsByClassName("fire");
for (let i = 0; i < fires.length; i++) {
fires[i].style.top =
this.crackerHeight * (this.crackerNum / 2) +
parseFloat(this.getRandom(2)) +
"px";
fires[i].style.left = parseFloat(this.getRandom(10)) + "px";
}
},
getRandom(n) {
let r = Math.random() * n;
let flag = Math.random();
if (flag > 0.5) return -r;
return r;
},
},
mounted() {
this.init();
},
};
</script>
<style lang="scss" scoped>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
.firecrackers {
position: relative;
width: 60%;
height: 60%;
left: 20%;
.Stick {
background-color: grey;
height: 300px;
width: 5px;
position: absolute;
transform: rotate(45deg);
}
.line {
background-color: grey;
height: 300px;
width: 2px;
position: absolute;
top: 43px;
left: 106px;
.cracker {
width: 5px;
height: 12px;
background-color: red;
position: absolute;
}
.fire {
background-color: orange;
width: 5px;
height: 5px;
border-radius: 50%;
top: 300px;
position: absolute;
animation: fireAni 1s infinite;
display: none;
}
}
}
.play {
cursor: pointer;
}
.to-smoke {
text-shadow: 0 0 0 whitesmoke;
animation: smoky 5s;
}
@keyframes fireAni {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes smoky {
to {
background-color: whitesmoke;
transform: translate3d(200px, 80px, 0) rotate(-40deg) skewX(70deg)
scale(1.5);
text-shadow: 0 0 20px whitesmoke;
opacity: 0;
}
}
}
</style>
二、原生js实现
html
<body>
<div id="app">
<div class="firecrackers">
<div class="Stick"></div>
<div class="line"></div>
</div>
<div class="play" onclick="play()">点炮竹</div>
<audio
src="./assets/鞭炮声.mp3"
controls="controls"
preload
id="music"
hidden
></audio>
</div>
</body>
script
初始化炮竹元素
初始化鞭炮的样式,让鞭炮左右倾斜排布。
function initCrackers() {
let crackers = document.getElementsByClassName("cracker");
let num = 0;
let j = 0;
while (crackers.length > j) {
for (let i = 0; i < 2; ++i) {
let cracker = crackers[j];
j++;
cracker.style.top = num * crackerHeight + "px";
if (j % 2 == 0) {
cracker.style.transform = "rotate(30deg)";
cracker.style.left = "-5px";
} else {
cracker.style.transform = "rotate(-30deg)";
}
}
num++;
}
}
初始化火花
在一定范围内随机生成闪烁的元素来模拟火花。
function initFires() {
let fires = document.getElementsByClassName("fire");
for (let i = 0; i < fires.length; i++) {
fires[i].style.top =
crackerHeight * (crackerNum / 2) + parseFloat(getRandom(2)) + "px";
fires[i].style.left = parseFloat(getRandom(10)) + "px";
}
}
function getRandom(n) {
let r = Math.random() * n;
let flag = Math.random();
if (flag > 0.5) return -r;
return r;
}
初始化页面
使用js动态生成dom元素
function initPage() {
let line = document.getElementsByClassName("line")[0];
let temp = ``;
for (let i = 0; i < crackerNum; i++) {
temp += `<div key="${i}" class="cracker"></div>`;
}
for (let i = 0; i < 10; i++) {
temp += `<div key="${i}" class="fire"></div>`;
}
line.innerHTML = temp;
initLine();
initCrackers();
initFires();
}
点燃鞭炮
点击燃烧鞭炮,添加飘落效果和鞭炮声
function play(len = "") {
let crackers = document.getElementsByClassName("cracker");
let fires = document.getElementsByClassName("fire");
let audio = document.getElementById("music");
if (audio.paused) {
audio.play();
}
if (len == "") len = crackers.length - 1;
crackers[len].classList.add("to-smoke");
crackers[len - 1].classList.add("to-smoke");
setTimeout(() => {
crackers[len].remove();
crackers[len - 1].remove();
}, 5000);
for (let i = 0; i < fires.length; i++) {
fires[i].style.display = "block";
fires[i].style.top =
parseInt(fires[i].style.top) - crackerHeight + "px";
}
setTimeout(() => {
if (len - 2 >= 0) {
play(len - 2);
} else {
for (let i = fires.length - 1; i >= 0; i--) {
fires[i].remove();
audio.pause();
}
}
}, speed);
}
css
粒子闪烁动画简单模拟火花
@keyframes fireAni {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
鞭炮燃烧后飘落效果
@keyframes smoky {
to {
background-color: whitesmoke;
transform: translate3d(200px, 80px, 0) rotate(-40deg) skewX(70deg)
scale(1.5);
text-shadow: 0 0 20px whitesmoke;
opacity: 0;
}
}
完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="app">
<div class="firecrackers">
<div class="Stick"></div>
<div class="line"></div>
</div>
<div class="play" onclick="play()">点炮竹</div>
<audio
src="./assets/鞭炮声.mp3"
controls="controls"
preload
id="music"
hidden
></audio>
</div>
</body>
<script type="text/javascript">
const crackerHeight = 12;
const speed = 200;
const crackerNum = 80;
function initPage() {
let line = document.getElementsByClassName("line")[0];
let temp = ``;
for (let i = 0; i < crackerNum; i++) {
temp += `<div key="${i}" class="cracker"></div>`;
}
for (let i = 0; i < 10; i++) {
temp += `<div key="${i}" class="fire"></div>`;
}
line.innerHTML = temp;
initLine();
initCrackers();
initFires();
}
function play(len = "") {
let crackers = document.getElementsByClassName("cracker");
let fires = document.getElementsByClassName("fire");
let audio = document.getElementById("music");
if (audio.paused) {
audio.play();
}
if (len == "") len = crackers.length - 1;
crackers[len].classList.add("to-smoke");
crackers[len - 1].classList.add("to-smoke");
setTimeout(() => {
crackers[len].remove();
crackers[len - 1].remove();
}, 5000);
for (let i = 0; i < fires.length; i++) {
fires[i].style.display = "block";
fires[i].style.top =
parseInt(fires[i].style.top) - crackerHeight + "px";
}
setTimeout(() => {
if (len - 2 >= 0) {
play(len - 2);
} else {
for (let i = fires.length - 1; i >= 0; i--) {
fires[i].remove();
audio.pause();
}
}
}, speed);
}
function initCrackers() {
let crackers = document.getElementsByClassName("cracker");
let num = 0;
let j = 0;
while (crackers.length > j) {
for (let i = 0; i < 2; ++i) {
let cracker = crackers[j];
j++;
cracker.style.top = num * crackerHeight + "px";
if (j % 2 == 0) {
cracker.style.transform = "rotate(30deg)";
cracker.style.left = "-5px";
} else {
cracker.style.transform = "rotate(-30deg)";
}
}
num++;
}
}
function initLine() {
let line = document.getElementsByClassName("line")[0];
line.style.height = crackerHeight * (crackerNum / 2) + "px";
}
function initFires() {
let fires = document.getElementsByClassName("fire");
for (let i = 0; i < fires.length; i++) {
fires[i].style.top =
crackerHeight * (crackerNum / 2) + parseFloat(getRandom(2)) + "px";
fires[i].style.left = parseFloat(getRandom(10)) + "px";
}
}
function getRandom(n) {
let r = Math.random() * n;
let flag = Math.random();
if (flag > 0.5) return -r;
return r;
}
initPage();
</script>
<style>
body {
height: 100%;
width: 100%;
background-color: rgb(19, 12, 12);
}
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.firecrackers {
position: relative;
width: 60%;
height: 60%;
left: 20%;
}
.Stick {
background-color: grey;
height: 300px;
width: 5px;
position: absolute;
transform: rotate(45deg);
}
.line {
background-color: grey;
height: 300px;
width: 2px;
position: absolute;
top: 43px;
left: 106px;
}
.cracker {
width: 5px;
height: 12px;
background-color: red;
position: absolute;
}
.fire {
background-color: orange;
width: 5px;
height: 5px;
border-radius: 50%;
top: 300px;
position: absolute;
animation: fireAni 1s infinite;
display: none;
}
.play {
cursor: pointer;
color: whitesmoke;
}
.to-smoke {
text-shadow: 0 0 0 whitesmoke;
animation: smoky 5s;
}
@keyframes fireAni {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes smoky {
to {
background-color: whitesmoke;
transform: translate3d(200px, 80px, 0) rotate(-40deg) skewX(70deg)
scale(0.5);
text-shadow: 0 0 20px whitesmoke;
opacity: 0;
}
}
</style>
</html>
说在后面
代码写得有点丑,实现效果也没有很炫酷,只是有感而发,做了这样一个页面来给自己增加一点年味,在这里提前祝大家新年快乐,虎年虎虎生威,如虎添翼。
|