以下是 HTML5小球碰撞叠加特效代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>HTML5小球碰撞叠加</title>
<link href="style.css" type="text/css" rel="stylesheet" media="screen" />
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script src="script/qiu.js" type="text/javascript"></script>
<script type="text/javascript">try{ clicky.init(66439025); }catch(e){}</script>
</head>
<body>
<div id="canvas">
<script type="text/javascript" src="script/protoclass.js"></script>
<script type="text/javascript" src="script/box2d.js"></script>
<script type="text/javascript" src="script/main.js"></script>
</div>
</body>
</html>
JS代码(main.js):
//code sourced from http://mrdoob.com/var canvas;
var delta = [ 0,0 ];
var stage = [ window.screenX,window.screenY,window.innerWidth,window.innerHeight ];
getBrowserDimensions();
var themes = [[ "#FFF","#135487","#D5D8DD","#5CA2BE","#2A4353","#989DA4" ] ];
var theme;
var worldAABB,world,iterations = 1,timeStep = 1 / 20;
var walls = [];
var wall_thickness = 200;
var wallsSetted = false;
var bodies,elements,text;
var createMode = false;
var destroyMode = false;
var isMouseDown = false;
var mouseJoint;
var mouseX = 0;
var mouseY = 0;
var orientation ={
x:0,y:1}
;
var PI2 = Math.PI * 2;
var timeOfLastTouch = 0;
init();
play();
function init(){
canvas = document.getElementById( 'canvas' );
document.onmousedown = onDocumentMouseDown;
document.onmouseup = onDocumentMouseUp;
document.onmousemove = onDocumentMouseMove;
document.ondblclick = onDocumentDoubleClick;
document.addEventListener( 'touchstart',onDocumentTouchStart,false );
document.addEventListener( 'touchmove',onDocumentTouchMove,false );
document.addEventListener( 'touchend',onDocumentTouchEnd,false );
window.addEventListener( 'deviceorientation',onWindowDeviceOrientation,false );
// init box2d worldAABB = new b2AABB();
worldAABB.minVertex.Set( -200,-200 );
worldAABB.maxVertex.Set( screen.width + 200,screen.height + 200 );
world = new b2World( worldAABB,new b2Vec2( 0,0 ),true );
setWalls();
reset();
}
function play(){
setInterval( loop,1000 / 40 );
}
function reset(){
var i;
if ( bodies ){
for ( i = 0;
i < bodies.length;
i++ ){
var body = bodies[ i ] canvas.removeChild( body.GetUserData().element );
world.DestroyBody( body );
body = null;
}
}
// color theme theme = themes[ Math.random() * themes.length >> 0 ];
document.body.style[ 'backgroundColor' ] = theme[ 0 ];
bodies = [];
elements = [];
createInstructions();
//amount of balls for( i = 0;
i < 8;
i++ ){
createBall();
}
}
//function onDocumentMouseDown(){
isMouseDown = true;
return false;
}
function onDocumentMouseUp(){
isMouseDown = false;
return false;
}
function onDocumentMouseMove( event ){
mouseX = event.clientX;
mouseY = event.clientY;
}
function onDocumentDoubleClick(){
reset();
}
function onDocumentTouchStart( event ){
if( event.touches.length == 1 ){
event.preventDefault();
// Faking double click for touch devices var now = new Date().getTime();
if ( now - timeOfLastTouch < 250 ){
reset();
return;
}
timeOfLastTouch = now;
mouseX = event.touches[ 0 ].pageX;
mouseY = event.touches[ 0 ].pageY;
isMouseDown = true;
}
}
function onDocumentTouchMove( event ){
if ( event.touches.length == 1 ){
event.preventDefault();
mouseX = event.touches[ 0 ].pageX;
mouseY = event.touches[ 0 ].pageY;
}
}
function onDocumentTouchEnd( event ){
if ( event.touches.length == 0 ){
event.preventDefault();
isMouseDown = false;
}
}
function onWindowDeviceOrientation( event ){
if ( event.beta ){
orientation.x = Math.sin( event.gamma * Math.PI / 180 );
orientation.y = Math.sin( ( Math.PI / 4 ) + event.beta * Math.PI / 180 );
}
}
//function createInstructions(){
var size = 90;
var element = document.createElement( 'div' );
element.width = size;
element.height = size;
element.style.position = 'absolute';
element.style.left = -200 + 'px';
element.style.top = -200 + 'px';
element.style.cursor = "default";
canvas.appendChild(element);
elements.push( element );
var circle = document.createElement( 'canvas' );
circle.width = size;
circle.height = size;
var graphics = circle.getContext( '2d' );
graphics.fillStyle = theme[ 3 ];
graphics.beginPath();
graphics.arc( size * .5,size * .5,size * .5,0,PI2,true );
graphics.closePath();
graphics.fill();
element.appendChild( circle );
text = document.createElement( 'div' );
text.onSelectStart = null;
text.style.left = ((250 - text.clientWidth) / 2) +'px';
text.style.top = ((250 - text.clientHeight) / 2) +'px';
var b2body = new b2BodyDef();
var circle = new b2CircleDef();
circle.radius = size / 2;
circle.density = 1;
circle.friction = 0.3;
circle.restitution = 0.3;
b2body.AddShape(circle);
b2body.userData ={
element:element}
;
b2body.position.Set( Math.random() * stage[2],Math.random() * -200 );
b2body.linearVelocity.Set( Math.random() * 400 - 200,Math.random() * 400 - 200 );
bodies.push( world.CreateBody(b2body) );
}
function createBall( x,y ){
var x = x || Math.random() * stage[2];
var y = y || Math.random() * -200;
//sb var size = (Math.random() * 75 >> 0) + 20;
var element = document.createElement("canvas");
element.width = size;
element.height = size;
element.style['position'] = 'absolute';
element.style['left'] = -200 + 'px';
element.style['top'] = -200 + 'px';
var graphics = element.getContext("2d");
var num_circles = Math.random() * 10 >> 0;
for (var i = size;
i > 0;
i-= (size/num_circles)){
graphics.fillStyle = theme[ (Math.random() * 4 >> 0) + 1];
graphics.beginPath();
graphics.arc(size * .5,size * .5,i * .5,0,PI2,true);
graphics.closePath();
graphics.fill();
}
canvas.appendChild(element);
elements.push( element );
var b2body = new b2BodyDef();
var circle = new b2CircleDef();
circle.radius = size >> 1;
circle.density = 1;
circle.friction = 0.3;
circle.restitution = 0.3;
b2body.AddShape(circle);
b2body.userData ={
element:element}
;
b2body.position.Set( x,y );
b2body.linearVelocity.Set( Math.random() * 400 - 200,Math.random() * 400 - 200 );
bodies.push( world.CreateBody(b2body) );
}
//function loop(){
if (getBrowserDimensions()){
setWalls();
}
delta[0] += (0 - delta[0]) * .5;
delta[1] += (0 - delta[1]) * .5;
world.m_gravity.x = orientation.x * 350 + delta[0];
world.m_gravity.y = orientation.y * 350 + delta[1];
mouseDrag();
world.Step(timeStep,iterations);
for (i = 0;
i < bodies.length;
i++){
var body = bodies[i];
var element = elements[i];
element.style.left = (body.m_position0.x - (element.width >> 1)) + 'px';
element.style.top = (body.m_position0.y - (element.height >> 1)) + 'px';
if (element.tagName == 'DIV'){
var rotationStyle = 'rotate(' + (body.m_rotation0 * 57.2957795) + 'deg)';
text.style.WebkitTransform = rotationStyle;
text.style.MozTransform = rotationStyle;
text.style.OTransform = rotationStyle;
// text.style.MsTransform = rotationStyle;
}
}
}
// .. BOX2D UTILSfunction createBox(world,x,y,width,height,fixed){
if (typeof(fixed) == 'undefined'){
fixed = true;
}
var boxSd = new b2BoxDef();
if (!fixed){
boxSd.density = 1.0;
}
boxSd.extents.Set(width,height);
var boxBd = new b2BodyDef();
boxBd.AddShape(boxSd);
boxBd.position.Set(x,y);
return world.CreateBody(boxBd);
}
function mouseDrag(){
// mouse press if (createMode){
createBall( mouseX,mouseY );
}
else if (isMouseDown && !mouseJoint){
var body = getBodyAtMouse();
if (body){
var md = new b2MouseJointDef();
md.body1 = world.m_groundBody;
md.body2 = body;
md.target.Set(mouseX,mouseY);
md.maxForce = 30000 * body.m_mass;
md.timeStep = timeStep;
mouseJoint = world.CreateJoint(md);
body.WakeUp();
}
else{
createMode = true;
}
}
// mouse release if (!isMouseDown){
createMode = false;
destroyMode = false;
if (mouseJoint){
world.DestroyJoint(mouseJoint);
mouseJoint = null;
}
}
// mouse move if (mouseJoint){
var p2 = new b2Vec2(mouseX,mouseY);
mouseJoint.SetTarget(p2);
}
}
function getBodyAtMouse(){
// Make a small box. var mousePVec = new b2Vec2();
mousePVec.Set(mouseX,mouseY);
var aabb = new b2AABB();
aabb.minVertex.Set(mouseX - 1,mouseY - 1);
aabb.maxVertex.Set(mouseX + 1,mouseY + 1);
// Query the world for overlapping shapes. var k_maxCount = 10;
var shapes = new Array();
var count = world.Query(aabb,shapes,k_maxCount);
var body = null;
for (var i = 0;
i < count;
++i){
if (shapes[i].m_body.IsStatic() == false){
if ( shapes[i].TestPoint(mousePVec) ){
body = shapes[i].m_body;
break;
}
}
}
return body;
}
function setWalls(){
if (wallsSetted){
world.DestroyBody(walls[0]);
world.DestroyBody(walls[1]);
world.DestroyBody(walls[2]);
world.DestroyBody(walls[3]);
walls[0] = null;
walls[1] = null;
walls[2] = null;
walls[3] = null;
}
walls[0] = createBox(world,stage[2] / 2,- wall_thickness,stage[2],wall_thickness);
walls[1] = createBox(world,stage[2] / 2,stage[3] + wall_thickness,stage[2],wall_thickness);
walls[2] = createBox(world,- wall_thickness,stage[3] / 2,wall_thickness,stage[3]);
walls[3] = createBox(world,stage[2] + wall_thickness,stage[3] / 2,wall_thickness,stage[3]);
wallsSetted = true;
}
// BROWSER DIMENSIONSfunction getBrowserDimensions(){
var changed = false;
if (stage[0] != window.screenX){
delta[0] = (window.screenX - stage[0]) * 50;
stage[0] = window.screenX;
changed = true;
}
if (stage[1] != window.screenY){
delta[1] = (window.screenY - stage[1]) * 50;
stage[1] = window.screenY;
changed = true;
}
if (stage[2] != window.innerWidth){
stage[2] = window.innerWidth;
changed = true;
}
if (stage[3] != window.innerHeight){
stage[3] = window.innerHeight;
changed = true;
}
return changed;
}
CSS代码(style.css):
@charset "UTF-8";/* CSS Document */
html{overflow-x:hidden}
p{font-family:"Helvetica",Arial,sans-serif;}
h1{font-family:"Helvetica",Arial,sans-serif;padding:0px;margin:0px;}
h2{margin:0px;padding:0px;font-family:"Helvetica",Arial,sans-serif;}
li{list-style-type:none;}
ul{margin:0px;padding:0px;}
a{text-decoration:none;font-family:"Helvetica",Arial,sans-serif;margin:0px;padding:0px;}
img{border:none;}
body{margin:0 auto;padding:0px;}
outline{none;}
#wrap{min-width:100%;min-height:100%;padding:0px;margin:0 auto;}
#header{width:100%;height:153px;z-index:9999998;}
/*Turn off button*/
#turnoff{position:absolute;top:7px;height:11px;width:108px;right:34px;}
#turnoff a{font-size:13px;color:#A7A9AC;-webkit-transition:color 200ms ease-in 100ms;-moz-transition:color 200ms ease-in 100ms;-o-transition:color 200ms ease-in 100ms;transition:color 200ms ease-in 100ms;}
#turnoff a:hover{color:#06A2C6;}
/************************************************NAVIGATION STARTS HERE************************************************/
#navigation{height:119px;width:293px;float:right;margin-right:51px;margin-top:27px;z-index:99999999;}
#navigation ul{height:119px;width:293px;padding-left:7.5px;}
#navigation ul li{height:71px;width:70px;float:left;margin-left:-5px;}
#navigation ul li.bottom{margin-top:42px;}
#navigation ul li.top{margin-top:7px;}
#navigation ul li a{display:block;width:75px;height:71px;-webkit-transform:scale(1);-webkit-transition-timing-function:ease-in-out;-webkit-transition-duration:100ms;-webkit-backface-visibility:visible;-webkit-perspective:0;-webkit-border-radius:2px;-moz-transition-timing-function:ease-in-out;-moz-transition-duration:100ms;-moz-border-radius:2px;z-index:1000000;}
/********CLASSES AND HOVER FOR NAVIGATION**************/
#navigation ul li a.home{background:url(images/navigation/home.png) no-repeat 0 0;}
#navigation ul li a.homecurrent{background:url(images/navigation/home_current.png) no-repeat 0 0;}
#navigation ul li a.work{background:url(images/navigation/work.png) no-repeat 0 0;}
#navigation ul li a.workcurrent{background:url(images/navigation/work_current.png) no-repeat 0 0;}
#navigation ul li a.about{background:url(images/navigation/about.png) no-repeat 0 0;}
#navigation ul li a.aboutcurrent{background:url(images/navigation/about_current.png) no-repeat 0 0;}
#navigation ul li a.contact{background:url(images/navigation/contact.png) no-repeat 0 0;}
#navigation ul li a.contactcurrent{background:url(images/navigation/contact_current.png) no-repeat 0 0;}
#navigation ul li a:hover{-webkit-transform:scale(1.1) rotate(-15deg);-moz-transform:scale(1) rotate(-15deg);}
/*************************************************SIDEBAR STARTS HERE*******************************************/
#sidebar{display:block;width:363px;height:417px;margin-left:51px;float:left;margin-top:0px;z-index:9999997;}
#friends{width:363px;height:75px;border-top:1.5px dashed #D5D8DD;padding-top:0px;margin-top:-31px;display:block;}
#friends_list{width:363px;height:32px;display:block;padding-top:0px;margin-top:15px;}
/***********************************************SOCIAL NETWORKS START HERE*****************************************************/
#social{width:363px;height:32px;display:block;padding-top:0px;}
#social.normal{width:363px;height:32px;display:block;padding-top:0px;margin-top:15px;}
#social.home_social{width:363px;height:32px;display:block;border-top:1.5px dashed #D5D8DD;padding-top:8px;}
#social ul.gallery{width:148px;height:32px;}
#social ul.gallery li{width:31px;height:32px;float:left;padding-right:6px;display:inline;}
#social ul.gallery li a.thumb{width:31px;height:32px;display:block;background-position:-34px 0;}
ul.gallery li span{/*--Used to crop image--*/
width:31px;height:32px;overflow:hidden;display:block;}
#about_social{width:230px;height:74px;display:block;margin-top:15px;}
li.con{width:75px;height:75px;float:left;}
#about_social #social{width:150px;margin-left:80px;position:relative;top:38px;}
a.contactme{width:75px;height:75px;margin-left:0px;background:url(images/navigation/contact.png) no-repeat;display:block;opacity:1;-webkit-transition:opacity;-webkit-transition-timing-function:ease-out;-webkit-transition-duration:500ms;-moz-transition:opacity;-moz-transition-timing-function:ease-out;-moz-transition-duration:500ms;}
a.contactme:hover{opacity:.6;}
#followme{position:absolute;width:153px;height:96px;background:url(images/follow_me.png);display:block;left:270px;margin-top:15px;}
/*********************************************NEW ZEALAND HERE****************************************************/
#newzealand{width:218px;height:317px;float:left;margin-top:42px;margin-left:-33px;background:url(images/new_zealand.png) no-repeat;padding-top:25px;}
@-webkit-keyframes pin{0%{margin-top:0;}
50%{margin-top:-10px;}
100%{margin-top:0;}
}
@-moz-keyframes pin{0%{margin-top:0;}
50%{margin-top:-10px;}
100%{margin-top:0;}
}
#pinpoint{z-index:2;width:43px;height:65px;margin-left:150px;-webkit-animation:'pin' 3s infinite;-moz-animation:'pin' 3s infinite;}
@-webkit-keyframes resize{0%{padding:0 0;opacity:1;}
50%{padding:0 10px 0 10px;opacity:0.6;}
100%{padding:0 0;opacity:1;}
}
@-moz-keyframes resize{0%{padding:0 0;opacity:1;}
50%{padding:0 10px 0 10px;opacity:0.6;}
100%{padding:0 0;opacity:1;}
}
#resize{margin-left:159px;width:24px;}
.shadow{margin:0 auto;width:2px;height:2px;-webkit-animation:resize 3s infinite;-webkit-box-shadow:0 4px 4px #357080;-moz-animation:resize 3s infinite;-moz-box-shadow:0 4px 4px #357080;}
/*******************************************FOOTER STARTS HERE*******************************************/
#footer{width:197px;height:121px;left:51px;bottom:0px;position:absolute;}
#click{width:149px;height:85px;margin-left:35px;}
#like{width:197px;height:32px;margin-bottom:0px;}
/*********************************************SLIDE OUT TAB*************************************************/
.slide-out-div{width:365px;height:421px;display:block;}
#instruction{width:400px;height:421px;background:url(images/instructions_two.gif) no-repeat;/*background-position:0 -24px;*/
margin-top:-24px;}
h1{font-size:18px;color:#6D6E70;top:395px;left:92px;position:absolute;}
a.slide{font-family:"Helvetica",Arial,sans-serif;font-size:18px;color:#2A4353;text-decoration:underline;position:absolute;top:395px;left:198px;font-weight:bold;}
/**********************************************WORK PAGE SIDE BAR*********************************************/
h1.sub{width:290px;height:auto;margin-top:12px;float:left;position:relative;top:0px;left:5px;font-size:31px;color:#989DA4;font-weight:normal;line-height:32px;display:block;}
#dashed{width:290px;height:168px;border-top:1.5px dashed #D5D8DD;margin-top:126px;margin-left:5px;}
h2.bottom{width:186px;height:auto;color:#939598;font-size:16px;font-weight:normal;margin-top:18px;}
/*********************************************INFORMATION FOR ABOUT STARTS HERE**************************************************/
#contain{width:626px;height:490px;display:block;margin-right:72px;float:right;margin-top:10px;}
#myself{width:611px;height:200px;margin-left:8px;margin-top:5px;border-bottom:1.5px dashed #D5D8DD;}
.uppercase{font-size:48px;color:#5CA2BE;font-weight:normal;position:absolute;font-family:Arial,"Helvetica",sans-serif;margin-top:-31px;}
p.content{color:#939598;font-size:12px;font-weight:100;text-indent:50px;line-height:17px;}
#haveyou{background:url(images/speech_about.gif) no-repeat;width:176px;height:79px;float:left;margin-left:-177px;margin-top:150px;}
/***************************************************SLIDESHOW STARTS BELOW************************************************/
#slideshow{margin:0 auto;width:640px;height:205px;position:relative;top:18px;}
#slideshow #slidesContainer{margin:0 auto;width:563px;height:205px;overflow:auto;/* allow scrollbar */
position:relative;}
#slideshow #slidesContainer .slide{margin:0 auto;width:525px;/* reduce by 20 pixels of #slidesContainer to avoid horizontal scroll */
height:205px;}
/** * Slideshow controls style rules. */
.control{display:block;width:39px;height:263px;text-indent:-10000px;position:absolute;cursor:pointer;}
#leftControl{top:55px;left:0;height:35px;background:transparent url(images/prev.gif) no-repeat 0 0;opacity:1;-webkit-transition:opacity;-webkit-transition-timing-function:ease-out;-webkit-transition-duration:500ms;-moz-transition:opacity;-moz-transition-timing-function:ease-out;-moz-transition-duration:500ms;}
#leftControl:hover{opacity:.6;-webkit-transition:opacity;-webkit-transition-timing-function:ease-out;-webkit-transition-duration:500ms;-moz-transition:opacity;-moz-transition-timing-function:ease-out;-moz-transition-duration:500ms;}
#rightControl{top:0;right:0;height:35px;top:55px;background:transparent url(images/next.gif) no-repeat 0 0;opacity:1;-webkit-transition:opacity;-webkit-transition-timing-function:ease-out;-webkit-transition-duration:500ms;-moz-transition:opacity;-moz-transition-timing-function:ease-out;-moz-transition-duration:500ms;}
#rightControl:hover{opacity:.6;-webkit-transition:opacity;-webkit-transition-timing-function:ease-out;-webkit-transition-duration:500ms;-moz-transition:opacity;-moz-transition-timing-function:ease-out;-moz-transition-duration:500ms;}
/****************************CONTACT BELOW************************************/
h1{left:50%;height:50%;color:#999;font-size:24px;top:200px;}
#form-container{padding:15px;-moz-border-radius:12px;-khtml-border-radius:12px;-webkit-border-radius:12px;border-radius:12px;float:left;margin-left:132px;width:500px;}
td{white-space:nowrap;}
a,a:visited{color:#00BBFF;text-decoration:none;outline:none;}
label{font-size:10px;font-family:"Helvetica",Arial,Sans-serif;color:#6D6F71;}
textarea{color:#333;font-family:Arial,"Helvetica",sans-serif;font-size:12px;}
td > button{text-indent:8px;}
.error{background-color:#06A2C6;color:white;font-size:10px;font-weight:bold;margin-top:10px;padding:10px;width:240px;font-family:"Helvetica",Arial,sans-serif}
#loading{position:relative;bottom:9px;visibility:hidden;}
.tutorial-info{color:white;text-align:center;padding:10px;margin-top:10px;}
#award{position:absolute;top:0px;left:51px;width:164px;height:69px;}
#award a{background:url(images/css-design-award-nominee.png) no-repeat;width:164px;height:69px;display:block;opacity:1;-webkit-transition:opacity;-webkit-transition-timing-function:ease-out;-webkit-transition-duration:500ms;-moz-transition:opacity;-moz-transition-timing-function:ease-out;-moz-transition-duration:500ms;}
#award a:hover{opacity:0.8;}
#NavSubhead{position:relative;top:0px;left:0px;font-family:Arial,"Helvetica",sans-serif;font-size:12px;color:#5ca2be;width:117px;height:42px;text-align:left;}
#NavSubhead.nina{}
#NavSubhead.raewyn{}
#NavSubhead.estiana{}
#copyright{position:absolute;right:34px;bottom:8px;height:auto !important;width:auto !important;}
#copyright p{font-size:9px;font-family:Arial,"Helvetica",sans-serif;color:#999;}