<!DOCTYPE html>
<html><head>
<meta charset="UTF-8"> <title>随机生成气泡碰撞</title> <style> html { height: 100%; } body { width: 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; width: 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>