<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>随机生成气泡碰撞</title>
<style>
html {
height: 100%;
}
body {
100%;
margin: 0;
padding: 0;
height: 100%;
}
div.wrap {
height: 100%;
position: relative;
overflow: hidden;
margin: 0;
padding: 0;
}
div:not(.wrap) {
border-radius: 50%;
/*-webkit-animation:tanslateAni 5000ms infinite linear alternate;*/
/*transition: all 10000ms linear;*/
}
div:nth-of-type(2) {
-webkit-animation-delay: 2000ms;
}
div:nth-of-type(3) {
-webkit-animation-delay: 4000ms;
}
div:nth-of-type(4) {
-webkit-animation-delay: -1000ms;
}
@-webkit-keyframes tanslateAni {
0% {
-webkit-transform: rotate(10deg) translate3d(0px, 0px, 0)
}
35% {
-webkit-transform: rotate(0deg) translate3d(20px, 0px, 0)
}
70% {
-webkit-transform: rotate(-10deg) translate3d(0px, 0px, 0)
}
100% {
-webkit-transform: rotate(0deg) translate3d(-20px, 0px, 0)
}
}
span {
display: inline-block;
100px;
height: 100px;
border-radius: 50%;
background-color: red;
background: -webkit-repeating-radial-gradient(red, yellow 10%, green 15%);
/* Safari 5.1 - 6.0 */
background: -o-repeating-radial-gradient(red, yellow 10%, green 15%);
/* Opera 11.6 - 12.0 */
background: -moz-repeating-radial-gradient(red, yellow 10%, green 15%);
/* Firefox 3.6 - 15 */
background: repeating-radial-gradient(red, yellow 10%, green 15%);
/* 标准的语法(必须放在最后) */
</style>
</head>
<body>
<div class="wrap" id='parent'></div>
<span></span>
</body>
<script>
var elWidth = 110;
var containerWidth;
var color = ['-webkit-repeating-radial-gradient(red, yellow 10%, green 15%)', 'green', 'blue', 'black', 'yellow'];
//随机的颜色
var ballNum = 20;
//var pageHeight=window.screen.height;
var pageHeight = document.body.clientHeight;
//var pageWidth=window.screen.width;
var pageWidth = document.body.clientWidth;
containerWidth = pageWidth;
var sizeRange = 60;
var balls = [];
window.onload = function() {
createBalls(elWidth + sizeRange, pageWidth, pageHeight, ballNum);
setInterval(function() { ballHit(balls, pageWidth, pageHeight) }, 30)
}
//生成虚拟网格
function createTable(ballWidth, pageWidth, pageHeight) {
var col = Math.floor(pageWidth / ballWidth);
var marginH = pageWidth % ballWidth;
var marginV = pageHeight % ballWidth;
var row = Math.floor(pageHeight / ballWidth);
var total = col * row;
var ballMap = [];
for(var i = 0; i < total; i++) {
//网格map存入一维数组 //top、left值有较大偏差原因:/、%运算为小数,与Java不同
ballMap[i] = { left: marginH / 2 + Math.floor(i % col) * ballWidth, top: marginV / 2 + Math.floor(i / col) * ballWidth }
}
return ballMap;
}
//生成小球
var spaceIndex = 25;
function createBalls(ballWidth, pageWidth, pageHeight, ballNum) {
var ballMap = createTable(ballWidth, pageWidth, pageHeight);
var range = ballMap.length
if(ballNum >= range - spaceIndex) {
ballNum = range - spaceIndex;
}
var ballsData = [];
var ballIndex;
ballIndex = getRandom(0, range, ballNum);
for(var i = 0; i < ballIndex.length; i++) { ballsData[i] = ballMap[ballIndex[i]]; } renderBalls(ballsData, ballNum);
} //渲染小球
function renderBalls(ballData, ballNum) {
for(var i = 0; i < ballNum; i++) {
var divBall = createEl('div')
//(待改进)
balls.push({
el: divBall,
left: ballData[i].left,
top: ballData[i].top,
vx: Math.random() * 6 - 3,
vy: Math.random() * 6 - 3,
raduis: parseInt(divBall.style.width) / 2
});
}
for(var j = 0; j < ballNum; j++) {
balls[j].el.style.left = balls[j].left + 'px';
balls[j].el.style.top = balls[j].top + 'px';
}
} //随机数去重
function noRepeat(arr, newNum, range) {
var isRepeat = false;
for(var i = 0; i < arr.length; i++) {
if(newNum == arr[i]) {
isRepeat = true;
break;
}
}
if(isRepeat) {
newNum = Math.floor(Math.random() * range);
noRepeat(arr, newNum, range);
} else {
return newNum;
}
} //随机数去重工具函数2
function getRandom(min, max, n) {
if(n > (max - min + 1) || max < min) {
return null;
}
var result = [];
var count = 0;
while(count < n) {
var num = Math.floor(Math.random() * (max - min)) + min;
var flag = true;
for(var j = 0; j < n; j++) {
if(num == result[j]) {
flag = false;
break;
}
}
if(flag) {
result[count] = num;
count++;
}
}
return result;
} //随机生成一个dom元素
function createEl(el, text) {
var elment = document.createElement(el);
document.getElementById('parent').appendChild(elment);
var len = Math.ceil(Math.random() * sizeRange);
elment.style.width = len + elWidth + 'px';
elment.style.height = len + elWidth + 'px';
elment.style.background = color[Math.floor(Math.random() * 5)];
elment.style.position = 'absolute';
elment.innerHTML = text || "";
return elment;
}
function moveBall(balls) {
for(var i = 0; i < balls.length; i++) {
balls[i].left += balls[i].vx;
balls[i].top += balls[i].vy;
balls[i].el.style.left = balls[i].left + 'px';
balls[i].el.style.top = balls[i].top + 'px';
}
}
var spring = 1; //球与球之间弹性系数
var bounce = -1; //球与边缘之间弹性系数
function ballHit(balls, pageWidth, pageHeight) {
//检测边缘
for(var i = 0; i < balls.length; i++) {
if(balls[i].left <= 0 || balls[i].left >= pageWidth - 2 * balls[i].raduis) {
balls[i].vx *= bounce;
}
if(balls[i].top <= 0 || balls[i].top >= pageHeight - 2 * balls[i].raduis) {
balls[i].vy *= bounce;
}
}
//检测小球与小球
for(i = 0; i < balls.length; i++) {
var ball1 = balls[i];
ball1.x = ball1.left + ball1.raduis;
ball1.y = ball1.top + ball1.raduis;
for(j = i + 1; j < balls.length; j++) {
var ball2 = balls[j];
ball2.x = ball2.left + ball2.raduis;
ball2.y = ball2.top + ball2.raduis;
dx = ball2.x - ball1.x;
dy = ball2.y - ball1.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var misDist = ball1.raduis + ball2.raduis;
if(dist < misDist) {
var angle = Math.atan2(dy, dx);
tx = ball1.x + Math.cos(angle) * misDist;
ty = ball1.y + Math.sin(angle) * misDist;
ax = (tx - ball2.x) * spring;
ay = (ty - ball2.y) * spring;
ball1.vx -= ax;
ball1.vy -= ay;
ball2.vx += ax;
ball2.vy += ay;
}
}
}
moveBall(balls);
}
</script>
</html>