过年了,一起来放鞭炮吗?
提前祝大家新年快乐呀,不知道大家有没有这样的感觉,为什么越长大,越觉得过年没有了年味?回想小时候和小伙伴们一起拿着鞭炮到田里看到什么炸什么的日子,还真是遥远,现在是无法在像一起那样了,那么就在网上来一起放鞭炮吧!
预览
实现
一、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; } } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9
完整代码
<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; //燃烧速度ms 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>
说在后面
代码写得有点丑,实现效果也没有很炫酷,只是有感而发,做了这样一个页面来给自己增加一点年味,在这里提前祝大家新年快乐,虎年虎虎生威,如虎添翼。