简单HTML+CSS+JS写出烟花效果

  • Post author:
  • Post category:其他




效果

在这里插入图片描述



简单布局HTML结构

  • 这里只用了一个最大的盒子div
  • 其他的都是动态生成
<body>
    <div class="box"></div>
    <script src="./demo.js"></script>
    <script src="./index.js"></script>
    <script src="./use.js"></script>
</body>



设定CSS样式

<style>
        * {
            margin: 0;
            padding: 0;
        }
		/* 这里给大盒子设定样式,设定宽高背景色、溢出隐藏、盒子阴影 相对定位*/
        .box {
            width: 1000px;
            height: 600px;
            margin: 10px auto;
            background: #000;
            border: 50px solid skyblue;
            overflow: hidden;
            position: relative;
            box-shadow: 0 0 5px 10px gray;
        }
		/* 这里给大的生成的li 设定样式 宽高 绝对定位 */
        .bigFire {
            width: 10px;
            height: 10px;
            position: absolute;
        }
		/*这里给往上“飞” 的小li设定样式 宽高 绝对定位 圆*/
        .smallFire {
            width: 6px;
            height: 6px;
            border-radius: 50%;
            position: absolute;
        }
    </style>



JS代码

<script>
//这里是 ues.js 文件中的代码  主要是为了获取页面中的 节点  
//然后创建节点  调用入口函数
const oBox = document.querySelector('div');
const oFire = new Fire(oBox);
oFire.init();

</script>
//这里是 index.js 文件中的内容  主要实现功能
<script>
class Fire {
    constructor(element) {
        this.ele = element;
    }
    init() {
        this.setFire();
    }
    setFire() {
        this.ele.addEventListener('click', e => {
            let x = e.offsetX;
            let y = e.offsetY;
            if (x < 0) {
                x = 0;
            }
            if (y < 0) {
                y = 0;
            }
            if (x > 1000 - 10) {
                x = 1000 - 10;
            }
            if (y > 600 - 10) {
                y = 600 - 10;
            }

            const fUp = document.createElement('p');
            const fDown = document.createElement('p');
            fUp.className = 'bigFire';
            fDown.className = 'bigFire';
            let a = everColor();
            fUp.style.background = a;
            fDown.style.background = a;
            fDown.style.height = '20px';
            fUp.style.borderRadius = '50%';
            fDown.style.borderRadius = '50%';
            fDown.style.boxShadow = '0 0 5px 3px white';
            fUp.style.boxShadow = '0 0 5px 3px white';
            fUp.style.top = y + 'px';
            fUp.style.left = x + 'px';
            fDown.style.bottom = 0 + 'px';
            fDown.style.left = x + 'px';
            this.ele.appendChild(fDown);
            this.ele.appendChild(fUp);

            move(fDown, {
                top: y
            }, () => {
                this.ele.removeChild(fDown);
                this.ele.removeChild(fUp);

                let num = parseInt(Math.random() * (100 + 1 - 50) + 50);
                let arr = [];
                for (let i = 1; i <= num; i++) {
                    const lf = document.createElement('p');
                    lf.className = 'smallFire';
                    lf.style.background = everColor();
                    lf.style.left = x + 'px';
                    lf.style.top = y + 'px';
                    lf.style.boxShadow = '0px 0px 5px white'
                    this.ele.appendChild(lf);
                    arr.push(lf);
                    let coorX = parseInt(Math.random() * (x + 200 + 1 - (x - 200)) + (x - 200));
                    let coorY = parseInt(Math.random() * (y + 200 + 1 - (y - 200)) + (y - 200));

                    move(lf, {
                        left: coorX,
                        top: coorY
                    }, () => {
                        this.ele.removeChild(lf);
                        arr.splice(arr.indexOf(lf), 1);
                    })
                }
                let time = setInterval(() => {
                    if (arr.length === 0) {
                        clearInterval(time);
                    }
                }, 30)
            })
        })
    }
}
</script>



这是我自己封装的一个原生库 就是引入的demo.js文件


上面的函数中有用到其中一两个函数的 所以自己看着取

<script>
//1 获取参数
function getAdd() {
  var str = decodeURI(window.location.search).substr(1);
  var arr = str.split("&");
  var obj = {};
  arr.forEach(function (v) {
    arr1 = v.split("=");
    obj[arr1[0]] = arr1[1];
  });
  return obj;
}



//2 随机颜色
function everColor() {
  var str = "0123456789abcdef";
  var color = "#";
  for (var i = 1; i <= 6; i++) {
    var num = parseInt(Math.random() * str.length);
    color += str[num];
  }
  return color;
}
// 随机颜色
function evColor() {
  return `rgb(parseInt(Math.random() * 256), parseInt(Math.random() * 256), parseInt(Math.random() * 256))`;
}



//3 样式获取兼容
function myGetStyle(e, k) {
  if (window.getComputedStyle) {
    return window.getComputedStyle(e)[k];
  } else {
    return e.currentStyle(style);
  }
}




//4, table 表格删除效果
function setTable() {
  var str = '';
  arr.forEach(function (v, k) {
    str += `
      <tr>
      <td>${k+1}</td>
      <td>${v.name}</td>
      <td>${v.sex}</td>
      <td>${v.age}</td>
      <td>${v.addr}</td>
      <td>${v.tel}</td>
      <td><button name ="del" index="${k}">删除</button></td>
      </tr>
  `
  })
  oTbody.innerHTML = str;
}



//5, 获取六位随机数
function setnum() {
  var str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  var vc = '';
  while (vc.length !== 6) {
    var num = parseInt(Math.random() * str.length);
    if (vc.indexOf(str[num]) === -1) {
      vc += str[num];
    }
  }
  return vc;
}


// 6,move运动函数
// 参数1:运动的标签对象
// 参数2:运动的属性和属性值 对象类型
// 参数3:运动终止,执行的回调函数 函数名称 / 匿名函数

function move(element, type, callback) {
  // 创建对象,存储不同属性的定时器
  let obj = {};
  // 循环遍历参数2,key存储的是运动css样式属性
  for (let key in type) {
    // 创建定时器,存储在对象中,属性是运动css样式属性,属性值是 setInterval() 的返回值,也就是定时器序号
    obj[key] = setInterval(() => {
      // 获取原始属性值
      // 如果是透明度,直接获取属性值,并且乘以 100
      // 不是透明度,去除px单位,获取数值部分
      let oldStyle = key === 'opacity' ? myGetStyle(element, key) * 100 : parseInt(myGetStyle(element, key));

      // 计算步长
      // 如果是透明度,原始属性值*100 - 初始属性值 / 次数
      // 不是透明度, 原始属性值 - 初始属性值 / 次数
      let speed = key === 'opacity' ? (type[key] * 100 - oldStyle) / 5 : (type[key] - oldStyle) / 5;

      // 步长取整
      // 正数 : 向上取整
      // 负数 : 向下取整
      speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

      // 初始值累加步长
      oldStyle += speed;

      // 将改变的初始值,赋值给标签对象
      // 如果是透明度, 改变的初始值/100 赋值
      // 如果不是透明度 , 改变的初始值 拼接 px 单位
      element.style[key] = key === 'opacity' ? oldStyle / 100 : `${oldStyle}px`;
      if (key === 'opacity') {
        if (oldStyle === type[key] * 100) {
          // 清除定时器
          clearInterval(obj[key]);
          // 删除对象中的对应的数据单元
          delete(obj[key]);
        }
      } else {
        // 判断改变的初始值 等于 最终位置
        if (oldStyle === type[key]) {
          // 清除定时器
          clearInterval(obj[key]);
          // 删除对象中的对应的数据单元
          delete(obj[key]);
        }
      }

      // 获取对象的所有键名,组成新的数组
      var arr = Object.keys(obj);
      // 如果数组长度为0,证明对象没有单元,所有定时器都清除
      if (arr.length === 0) {
        // 执行回调函数
        callback();
      }
    }, 50)
  }

}
</script>



版权声明:本文为m0_49681744原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。