js表⽩-⼼形烟花⼼形烟花
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container{
width: 80%;
height: 600px;
border: 2px solid red;
background: #000;
margin:20px auto;
cursor: pointer;
position: relative;
left: 0;
top: 0;
overflow: hidden;
}
.fire{
width: 6px;
height:6px;
position: absolute;
animation: fireBug 3s infinite;
bottom: 0;
}
@keyframes fireBug{
0% {opacity:1;}
50% {opacity:0.2;}
100% {opacity:1;}
}
</style>
</head>
<body>
<div class="container">
</div>
<script src="./animate-opacity.js"></script>
</body>
<script>
class FireWork{
constructor(options){
//单例模式如果 FireWork上已经有选择好的元素了,那么我们就不需要重复进⾏选择了
if(FireWork.main && FireWork.main.selector === options.main){
//已经经历过元素选择了,所以直接赋值
this.main = FireWork.main.ele;
}else{
//还没有进⾏元素选择;
/
/将需要获取的DOM放⼊对象中,进⾏判断的也放⼊对象中
FireWork.main = {
ele : document.querySelector(options.main),
selector : options.main
}
this.main = FireWork.main.ele;
}
//获取烟花爆炸的⽅式,并放⼊原型中
this.blast_type = options.blast_type;
//将传⼊的需要创建的⼦元素tagName放⼊原型中
this.ele_tagName = options.children;
/
/将获取传⼊的⿏标点击位置
this.x = options.x;
this.y = options.y;
//调⽤初始化⽅法
this.init()
}
init(){
//创建DIV
this.ele = ateFireWork()
//设置边界
this.left_max = this.main.offsetWidth - this.ele.offsetWidth;
//调⽤烟花上升的⽅法
this.fireWorkUp(this.ele)
}
//创建DIV
createFireWork(){
var ele = ateElement(this.ele_tagName)
ele.className = "fire"
//调⽤⽅法设置随机颜⾊
this.randomColor(ele);
return this.main.appendChild(ele)
}
//设置烟花上升
fireWorkUp(ele){
//设置烟花上升的横坐标
ele.style.left = this.x + "px";
//调⽤封装好的运动JS ,设置元素想上运动
animate(ele , {top : this.y} , function(){
//烟花到达指定地点之后消失
//调⽤烟花的爆炸效果
this.fireWorkBlast()
}.bind(this))
}
//烟花爆炸效果
fireWorkBlast(){
//设置烟花爆炸之后散发的光点个数
for(var i = 0; i < 100; i++){
//创建对应的DIV
var ele = ateFireWork()
//设置随机颜⾊
this.randomColor(ele);
//设置随机位置
ele.style.left = this.x + "px";
p = this.y + "px";
ele.style.borderRadius = "50%";
//判断爆炸之后的形状
switch(this.blast_type){
//爆炸之后成圆形
case "circle":
//设置散发之后成⼀个圆形
animate(ele ,this.circleBlast( i , 20),function(ele){
//运动完成之后消失
}.bind(this , ele));
break;
//爆炸之后成⼼形
case "heart":
//设置散发之后成⼀个爱⼼
animate(ele , this.heartBlast(i),function(ele){
}.bind(this , ele))
break
//爆炸之后随机运动
default :
animate(ele , this.randomPosition(),function(ele){
}.bind(this , ele))
break
}
}
}
//设置随机颜⾊
randomColor(ele){
return ele.style.backgroundColor = "#" + parseInt(parseInt("ffffff" , 16) * Math.random()).toString(16).padStart(6,0);        }
//散发随机位置
randomPosition(){
return {
left : parseInt(Math.random() * (this.left_max + 1)),
top : parseInt(Math.random() * (p_max + 1))
}
}
//散发形成⼀个圆形
circleBlast(index , all){
var r  = 100;
var reg = (360 / all) * index;
var deg = Math.PI / 180 * reg;
return {
left : parseInt(r * s( deg )) + this.x,
top  : parseInt(r * Math.sin( deg )) + this.y
}
}
//散发成⼀个爱⼼
heartBlast(i){
var r  = 60;
var m = i;
var n = -r * (((Math.sin(i) * Math.sqrt(Math.s(i)))) / (Math.sin(i) + 1.4)) - 2 * Math.sin(i) + 2);
return {
left : n * s(m) + this.x,
top  : n * Math.sin(m) + this.y
}
}
}
var ele_con = document.querySelector(".container")
ele_con.addEventListener("click" , function(evt ){
var e = evt || event;
new FireWork({
main : ".container",
children : "div",
x : e.offsetX ,
y : e.offsetY,
blast_type : "heart" //设置烟花爆炸之后的形状
});
})
</script>
</html>
引⼊的的js⽂件
function animate( ele , attr_options , callback ){
for(var attr in attr_options){
// console.log(attr_options , attr_options[attr])
attr_options[attr] = {
//  ⽬标点 : 传⼊的数据;
target : attr === "opacity" ? attr_options[attr] * 100 : attr_options[attr],
//  元素当前的属性值 ;
iNow  : attr === "opacity" ? parseInt( getComputedStyle(ele)[attr] * 100 ) : parseInt( getComputedStyle(ele)[attr])        }
// console.log(attr_options , attr_options.width)
}
// 关闭开启定时器;
clearInterval( ele.timer );
ele.timer = setInterval( function(){
// 1. 获取速度; width :  height :
for(var attr in attr_options){
// attr : width | height;
var item = attr_options[attr];
表白代码手机// console.log(item , attr);
var target = item.target;
var iNow  = item.iNow;
// 运动所必须的值我们都有了;
// 计算速度;
var speed = (target - iNow) / 20;
// 速度取整;
speed = speed > 0 ? il(speed) : Math.floor(speed);
/
/ 终⽌条件 :
if( Math.abs( target - iNow) <= Math.abs(speed) ){
// 终⽌定时器 ;
// 送他⼀把;
// clearInterval( ele.timer );
// ele.style[attr] = target + "px";
// 终⽌条件不可靠,因为⽬标的不⼀致会让运动次数执⾏不同,有可能提前关闭定时器;
ele.style[attr] = attr === "opacity" ? target / 100 :  target + "px";
// ⼀条运动完成删除对象⾥⾯的数据;
delete attr_options[attr];
// 如果对象⾥⾯没有属性了,那么我们关闭定时器就可以了;
for(var num in attr_options){
// 如果attr_options⾥⾯有属性,那么此时我就不应该终⽌定时器;
return false;
}
clearInterval(ele.timer);
typeof callback === "function" ? callback() : "";
}else{
// 元素运动;
// 因为 iNow 是⼀个临时变量,所以不能再去操作iNow , 要去操作iNow 的数据源;
// 多花点经历理解这段代码;
attr_options[attr].iNow += speed;
ele.style[attr] = attr === "opacity" ? attr_options[attr].iNow / 100 : attr_options[attr].iNow + "px";            }
}
} , 30)
}