<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./utils.js"></script>
</head>
<body>
<div id="tips"><a id="auto" href="javascript:;" class="">自动放烟花</a></div>
<script>
window.onload = function () {
let auto = document.querySelector('#auto');
let flag = true;
let timer;
document.onclick = function (e) {
if (flag) {
new Fire(e.clientX, e.clientY);
}
}
auto.onclick = function (e) {
if (flag) {
timer = setInterval(() => {
new Fire();
flag = false;
}, 1500)
} else {
flag = true;
clearInterval(timer);
}
e.stopPropagation()
}
function Fire(x, y) {
this.left = x || getRandomNum(5, window.innerWidth - 5);
this.top = y || getRandomNum(20, window.innerHeight - 100);
this.qty = getRandomNum(15, 30);
this.r = getRandomNum(100, 200);
this.init()
this.move();
}
Fire.prototype = {
constructor: Fire,
init: function () {
this.dv = document.createElement('div');
this.dv.classList.add('fire');
this.dv.style.left = this.left + 'px';
document.body.appendChild(this.dv);
return this;
},
move: function () {
move(this.dv, { top: this.top, height: 3 }, () => {
this.boom();
})
},
boom: function () {
let deg = 360 / this.qty;
for (let i = 0; i < this.qty; i++) {
this.dv.style.background = 'rgba(0,0,0,0)'
new Spark(deg * i, this.r, this.dv)
}
}
}
Object.defineProperty(Fire.prototype, "constructor", { enumerable: false, writable: false });
function Spark(deg, r, parent) {
this.deg = deg;
this.r = r;
this.bgColor = getRandomColor();
this.rad = Math.PI * this.deg / 180;
this.left = this.r * Math.cos(this.rad);
this.top = this.r * Math.sin(this.rad);
this.parent = parent;
this.init().move();
}
Spark.prototype = {
constructor: Spark,
init: function () {
this.span = document.createElement('span');
this.span.classList.add('spark');
this.span.style.background = this.bgColor;
this.parent.appendChild(this.span);
return this;
},
move: function () {
move(this.span, { left: parseInt(this.left), top: parseInt(this.top), opacity: 30 }, () => {
this.remove();
})
},
remove: function () {
this.parent.remove()
}
}
Object.defineProperty(Spark.prototype, "constructor", { enumerable: false, writable: false });
}
</script>
</body>
</html>
html,
body {
overflow: hidden;
height: 100%;
}
body,
div,
p {
margin: 0;
padding: 0;
}
body {
background: #000;
font: 12px/1.5 arial;
color: #7A7A7A;
}
a {
text-decoration: none;
outline: none;
}
#tips,
#copyright {
position: absolute;
width: 100%;
height: 50px;
text-align: center;
background: #171717;
border: 2px solid #484848;
}
#tips {
top: 0;
border-width: 0 0 2px;
}
#tips a {
font: 14px/30px arial;
color: #FFF;
background: #F06;
display: inline-block;
margin: 10px 5px 0;
padding: 0 15px;
border-radius: 15px;
}
#tips a.active {
background: #FE0000;
}
.fire {
width: 3px;
height: 30px;
background: white;
position: absolute;
top: 100%;
}
.spark {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
left: 0;
top: 0;
}
function getRandomNum(a, b) {
if (a > b) {
return parseInt(Math.random() * (a - b + 1)) + b
}
return parseInt(Math.random() * (b - a + 1)) + a
}
function getRandomColor(a) {
if (a === 16) {
var str = '0123456789abcdef';
var res = '';
for (var i = 0; i < 6; i++) {
var idx = parseInt(Math.random() * 16);
res += str[idx];
}
return '#' + res;
}
var r = parseInt(Math.random() * 256);
var g = parseInt(Math.random() * 256);
var b = parseInt(Math.random() * 256);
return 'rgb(' + r + ',' + g + ',' + b + ')'
}
function getEle(ele) {
var str1 = ele.substr(0, 1);
var str2 = ele.substr(1);
if (str1 === '#') {
return document.getElementById(str2)
} else if (str1 === '.') {
return document.getElementsByClassName(str2);
} else {
return document.getElementsByTagName(ele);
}
}
function getStyle(ele, attr) {
var style;
if (window.getComputedStyle) {
style = window.getComputedStyle(ele)[attr];
} else {
style = ele.currentStyle[attr];
}
return style;
}
function move(ele, obj, callback) {
let timerLen = 0;
for (const attr in obj) {
clearInterval(ele[attr]);
timerLen++;
ele[attr] = setInterval(() => {
let curStyle;
if (attr === 'opacity') {
curStyle = getStyle(ele, attr) * 100;
} else {
curStyle = parseInt(getStyle(ele, attr));
}
let speed = (obj[attr] - curStyle) / 5;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (curStyle === obj[attr]) {
clearInterval(ele[attr]);
timerLen--
if (timerLen === 0) {
callback && callback();
}
} else {
if (attr === 'opacity') {
ele.style[attr] = (speed + curStyle) / 100;
} else {
ele.style[attr] = speed + curStyle + 'px';
}
}
}, 30)
}
}