过年了,你有多久没有放鞭炮了呢?

·  阅读 1241
过年了,你有多久没有放鞭炮了呢?

过年了,一起来放鞭炮吗?

PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛”。

在这里提前祝大家新年快乐呀,不知道大家有没有这样的感觉,为什么越长大,越觉得过年没有了年味?回想小时候和小伙伴们一起拿着鞭炮到田里看到什么炸什么的日子,还真是遥远,现在是无法在像一起那样了,那么就在网上来一起放鞭炮吧!

预览

鞭炮.gif

实现

一、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; //燃烧速度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>

复制代码

说在后面

代码写得有点丑,实现效果也没有很炫酷,只是有感而发,做了这样一个页面来给自己增加一点年味,在这里提前祝大家新年快乐,虎年虎虎生威,如虎添翼。

分类:
前端
收藏成功!
已添加到「」, 点击更改