JAVAscript实现萤火虫----面向对象
前言:写这个主要是想试试自己的脑子还好不好使,也是为了重新想想面向对象。
实现思路
- 创建萤火虫(一闪一闪的星星图写起来太累,所以我直接用bulingbuling的动图代替)
- 背景也是随机找的图。
- 给萤火虫加随机位置,并向定位处运动。
- 用定时器不断的给萤火虫定位。
创建萤火虫(是N个,不是一个)
这里只是创建一个,new多个实例就会创建多个
addEle() {
var div = document.createElement("div");
var img = document.createElement("img");
img.src = "img/3.jpg";
div.className = "box";
document.body.appendChild(div);
div.appendChild(img);
div.style.left = this.x + "px";
div.style.top = this.y + "px";
this.move(div);
}
用随机数生成萤火虫的随机位置
随机生成的位置就是萤火虫将要到达的位置
pos() {
this.x = ranNum(0, this.clientW - 20);
this.y = ranNum(0, this.clientH - 20);
}
让萤火虫动起来
通过缓冲运动让萤火虫运动到随机数生成的位置上
move(ele) {
this.pos();
move(
ele,
{
left: this.x,
top: this.y,
},
() => {
this.move(ele);
}
);
}
创建N个萤火虫(对应1)
这里就是new多个实例
for (var i = 0; i < 80; i++) {
var a = new Glowworm();
a.pos();
a.addEle();
}
完整代码
<style>
body {
background-image: url(img/bg.jpg);}
.box {
width: 20px;height: 20px;position: absolute; }
.box img {
width: 20px;height: 20px;}
</style>
</head>
<body>
<script>
//构造函数
class Glowworm {
constructor() {
this.oBox = document.getElementsByClassName("box");
this.clientW = document.documentElement.clientWidth;
this.clientH = document.documentElement.clientHeight;
}
//创建萤火虫
addEle() {
var div = document.createElement("div");
var img = document.createElement("img");
img.src = "img/3.jpg";
div.className = "box";
document.body.appendChild(div);
div.appendChild(img);
div.style.left = this.x + "px";
div.style.top = this.y + "px";
this.move(div);
}
//生成随机位置
pos() {
this.x = ranNum(0, this.clientW - 20);
this.y = ranNum(0, this.clientH - 20);
}
//运动到随机位置
move(ele) {
this.pos();
move(
ele,
{
left: this.x,
top: this.y,
},
() => {
this.move(ele);
}
);
}
}
//通过循环new出N个实例
for (var i = 0; i < 80; i++) {
var a = new Glowworm();
a.pos();
a.addEle();
}
//随机数
function ranNum(a, b) {
return Math.round(Math.random() * (a - b) + b);
}
//缓冲运动
// 带有px的css属性和透明度,可以运动
// 背景色不可以
// 参数2被修改成了对象,那么在使用之前需要解析(遍历)
function move(ele,obj,cb){
clearInterval(ele.t);
ele.t = setInterval(() => {
// 假设状态为:可以清除计时器
var i = true;
// 因为在计时器中才开始使用到对象中的信息,所以在计时器中遍历
// 并提前换来的属性和目标变量
for(var attr in obj){
if(attr == "opacity"){
var iNow = getStyle(ele,attr) * 100;
}else{
var iNow = parseInt(getStyle(ele,attr));
}
let speed = (obj[attr] - iNow)/10;
speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);
// 只要有一个属性到目标,就停了,不对
// 必须所有属性到目标,才能停
// 只要有一个属性没到目标,绝对不能停
// 用状态来标记到底要不要停止计时器
// 只要有一个属性没到目标:绝对不能清除计时器
if(iNow !== obj[attr]){
i = false;
}
if(attr == "opacity"){
ele.style.opacity = (iNow + speed)/100;
}else{
ele.style[attr] = iNow + speed + "px";
}
}
// 如果每次计时器执行结束,所有属性都执行了一遍之后,状态还是true,表示,没有被改成false,如果没有被改成false,表示没有属性没到终点,那么状态还是false就不清除
if(i){
clearInterval(ele.t);
// 用户决定在动画结束时要执行的功能,万一用户没传参,做个默认判断
if(cb){
cb();
}
// cb && cb();
}
}, 30);
}
//获取样式
function getStyle(ele,attr){
if(ele.currentStyle){
return ele.currentStyle[attr];
}else{
return getComputedStyle(ele,false)[attr];
}
}
</script>
转载:https://blog.csdn.net/qq_46370188/article/details/115582973
查看评论