用JavaScript实现萤火虫案例
这边我用是ES6面向对象的一种写法
<!DOCTYPE html>
<!--
* @Author: 橘子不酸
* @Date: 2020-03-17 23:13:48
* @LastEditTime: 2020-03-18 20:52:14
* @LastEditors: Please update automatically
* @FilePath: \js面向对象\萤火虫.html
* @错把陈醋当成墨,写尽半生纸上酸
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.drop{
width: 700px;
height: 500px;
position: relative;
margin: 0 auto;
background-color: rebeccapurple
}
.ball{
border-radius: 5px 5px;
width: 10px;
height: 10px;
position: absolute;
background-color: salmon;
animation: firebug 3s infinite;
}
@keyframes firebug{
0% {opacity:1;}
50% {opacity:0.2;}
100% {opacity:1;}
}
</style>
</head>
<body>
<div class="drop">
<!-- <div class="ball"></div> -->
</div>
<script src="./工具类.js"></script>
<script>
// 原型对象
function Fire(opction){
this.drop = document.querySelector(opction);
this.inint();
}
// 初始化实例
Fire.prototype= {
constructor : Fire,
inint:function(){
this.worm = this.createEle();
var boundbody =this.RandomLocation();
this.worm.style.left = boundbody.left+"px";
this.worm.style.top = boundbody.top+"px";
// 这边调用了一个工具类 我会把工具类代码放在下面
// 萤火虫的运动
animate(this.worm,this.RandomLocation(),function(){
animate(this.worm , this.RandomLocation() , arguments.callee.bind(this) );
}.bind(this))
},
// 创造元素
createEle:function(){
var ele = document.createElement("div");
ele.className = "ball";
this.drop.appendChild(ele);
return ele;
},
RandomLocation:function(){
// 考虑边界的问题
var left_max = this.drop.offsetWidth-this.worm.offsetWidth;
var top_max = this.drop.offsetHeight-this.worm.offsetHeight;
return{
left : parseInt(left_max*Math.random()+1),
top: parseInt(top_max*Math.random()+1)
}
}
}
for(var i=0;i<30;i++){
new Fire(".drop");
}
</script>
</body>
</html>
上述就是我写的萤火虫的实例 在代码中我调用了一个萤火虫运动的封装 下面我把封装的函数放在下面 供大家参考
// 传入的参数 元素 以对象的形式传入left和top的值,回调函数,运动特效默认是缓冲运动
function animate(ele, attr_options, callback,timingfunction = "swing") {
// 获取
// console.log(1);
for(var attr in attr_options){
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].iNow,attr);
}
if( timingfunction === "liner"){
// 判定speed是否存在;
speed = speed === undefined ? 5 : speed;
// 判定speed的正负;
speed = iNow < target ? Math.abs(speed) : -Math.abs(speed);
}
// 判断spend是否存在
// 判断spend正负 根据元素本身的位置 和 用户输入的位置进行对比
// 如果用户输入的大于元素的 就是spend向前走
// 如果用户输入的小于元素的 就是spend向后走
clearInterval(ele.timer);
ele.timer = setInterval(function () {
// 判断如果用户输入的目标 - 元素移动的总距离 小于 下一次运动的大小
// 则给元素赋值到最终的距离
for (var attr in attr_options) {
var item = attr_options[attr];
var targent = item.target;
var iNow = item.iNow;
if(timingfunction ==="swing"){
var spend = (targent - iNow) / 10;
spend = spend > 0 ? Math.ceil(spend) : Math.floor(spend);
}
if (Math.abs(targent - iNow) <= Math.abs(spend)) {
ele.style[attr] = attr === "opacity" ? targent / 100 : targent + "px";
delete attr_options[attr];
for (var num in attr_options) {
return false;
}
clearInterval(ele.timer);
typeof callback === "function" ? callback() : "";
} else {
// 给元素不断的进行移动
attr_options[attr].iNow += spend;
ele.style[attr] = attr === "opacity" ? attr_options[attr].iNow / 100 : attr_options[attr].iNow + "px";
}
}
}, 30)
}
效果图