js实现简单的小球与边框碰撞反弹改变运动方向及颜色,并且继续运动的特效
(代码可以直接复制使用,只需要把body中的div的id换成对应的就行,css中可以设置小球的大小和初始位置,修改小球大小之后需要在js里把现在的80改成小球的大小值)
最终实现效果图:
思路:首先先实现一个小球的运动和撞边框反弹效果,并且改变其颜色,效果如下图:
主要实现方法:
1.小球定位,运动靠改变它的position上下左右值;
2.获取浏览器的宽高,由此设置小球运动的最大范围,大于等于这个范围的时候就改变运动方向;
3.颜色的改变采用rgb方法,rgb的三个数值均用Math.random随机生成;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>运动的小球</title>
<style>
<!--单个小球的样式-->
.ball{
width:80px;
height:80px;
background: red;
border-radius: 50%;
position:absolute;
top:0;
left:0;
}
</style>
</head>
<body>
<div class="ball"></div> <!--单个小球的div-->
<script>
var oBall = document.querySelector('.ball'),
leftNum = 5; //设置小球每次向左运动的像素值
topNum = 5; //设置小球每次向下运动的像素值
leftMax = document.documentElement.clientWidth-oBall.clientWidth; //浏览器窗口宽度减去小球的宽度等于小球能运动到的最大左边位置,下一行代码同理。
topMax = document.documentElement.clientHeight-oBall.clientHeight;
window.onresize = function(){ //当浏览器窗口发生变化时,实时获取浏览器窗口的宽高
leftMax = document.documentElement.clientWidth-oBall.clientWidth;
topMax = document.documentElement.clientHeight-oBall.clientHeight;
}
setInterval(function(){ //为小球的运动新建一个计时器
var Left = oBall.offsetLeft+leftNum, //小球每次运动完之后,距离浏览器左边边框的距离:上一次距离边框的距离加上这次运动的距离,下一行代码同理
Top = oBall.offsetTop+topNum;
//判断当小球向左移动的位置大于之前限定的最大距离或者小于0时,也就是超出浏览器窗口的左右边框时,
//使他运动的方向取反leftNum = -leftNum,下面Top的判断同理。
if(Left>=leftMax){
Left = leftMax;
leftNum = -leftNum;
ballBg(oBall); //传参数到下面的获取随机颜色的function
}else if(Left<=0){
Left = 0;
leftNum = -leftNum;
ballBg(oBall);
};
if(Top>=topMax){
Top = topMax;
topNum = -topNum;
ballBg(oBall);
}else if(Top<=0){
Top = 0;
topNum = -topNum;
ballBg(oBall);
};
oBall.style.left = Left+'px';
oBall.style.top = Top+'px';
},30); //小球每次执行运动的时间
function ballBg(obj){ //随机获取小球颜色
var r = Math.floor(Math.random()*256);
g = Math.floor(Math.random()*256);
b = Math.floor(Math.random()*256);
obj.style.backgroundColor = 'rgb('+r+','+g+','+b+')';
}
</script>
</body>
</html>
一个小球的运动实现之后,当实现多个小球的时候,有两个问题需要考虑:
1.小球数量不能写死,万一数量很多,所以最好不要用div写,而是用appendChild的方法追加,这样,原来<div class="ball"></div>
单个;小球的div需要改成<div id="ball"></div>
一个大的div,然后往这个大的div中追加<div class="ball"></div>
2.小球的运动起点虽然相同,但是运动速度不能相同,不然所有的小球都会重叠在一起运动;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>运动的小球</title>
<style>
.ball{
width:80px;
height:80px;
background: red;
border-radius: 50%;
position:absolute;
top:0;
left:0;
}
</style>
</head>
<body>
<div id="ball"></div>
<script>
var oBall = document.querySelector('#ball'),
leftNum = 0,
topNum = 0,
aBall = null,
length = 0;
reSize();
window.onresize = reSize;
function reSize(){
leftMax = document.documentElement.clientWidth-80;
topMax = document.documentElement.clientHeight-80;
}
creatBall(oBall,10); //传参,往oBall里面追加10个小球
aBall = oBall.children; //获取oBall里面的所有小球
length = aBall.length;
function creatBall(obj,num){ //创建小球的function
for(var i=0;i<num;i++){
var cBall = document.createElement('div');
cBall.className = 'ball';
ballBg(cBall);
cBall.leftNum=cBall.topNum=(i+1)*1; //这里去i+1而不取i的原因是,一个小球的i为0,如果不取i+1,那么第一个小球会永远在左上角不动并且不停地变颜色
obj.appendChild(cBall);
};
};
setInterval(function(){ //这里注意需要将之前所有对oBall设置的都换成aBall[i]
for (var i=0;i<length;i++ ){
var Left = aBall[i].offsetLeft+aBall[i].leftNum,
Top = aBall[i].offsetTop+aBall[i].topNum;
if(Left>=leftMax){
Left = leftMax;
aBall[i].leftNum = -aBall[i].leftNum;
ballBg(aBall[i]);
}else if(Left<=0){
Left = 0;
aBall[i].leftNum = -aBall[i].leftNum;
ballBg(aBall[i]);
};
if(Top>=topMax){
Top = topMax;
aBall[i].topNum = -aBall[i].topNum;
ballBg(aBall[i]);
}else if(Top<=0){
Top = 0;
aBall[i].topNum = -aBall[i].topNum;
ballBg(aBall[i]);
};
aBall[i].style.left = Left+'px';
aBall[i].style.top = Top+'px';
}
},30);
function ballBg(obj){
var r = Math.floor(Math.random()*256);
g = Math.floor(Math.random()*256);
b = Math.floor(Math.random()*256);
obj.style.backgroundColor = 'rgb('+r+','+g+','+b+')';
}
</script>
</body>
</html>
以上,好多小球的碰撞效果就完成了,代码有问题或者还有可以优化的地方,请指教