<script src="http://box2dweb.googlecode.com/svn/trunk/Box2D.js"></script>
<script src="http://box2dweb.googlecode.com/svn/trunk/Box2D.js"></script>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script class="text/javascript" src="https://raw.github.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
<link href='http://fonts.googleapis.com/css?family=Archivo+Black' rel='stylesheet' type='text/css'>
<div class="green piece">1<br/></div><div class="blue piece">2<br/></div>
<div class="red piece">3<br/></div><div class="black piece">4<br/></div>
<br>
<div class="rowling piece"></div>
<br>
<div class="black piece">5<br/></div><div class="red piece">6<br/></div>
<div class="blue piece">7<br/></div><div class="black piece">8<br/></div>
<br/>
<div class="rowling piece"></div>
<div class="ground"></div>
<script>
function rewidth(p,w) {
p.animate(
{ background: 'white', width: w },
{
step: function(n,f) { p.data('fixture').GetShape().SetAsBox(p.outerWidth() / 2 / 30, p.outerHeight() / 2 / 30); },
duration: 600
}
);
}
$('.rowling.piece').mouseenter(function() { rewidth($(this), '1px'); });
$('.rowling.piece').mouseleave(function() { rewidth($(this), '10%'); });
</script>
html, body {height:100%;}
html, body {height:100%;}
html {display:table; width:100%;}
body {display:table-cell; text-align:center; vertical-align:bottom;}
* {-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none; -webkit-user-drag:none;-moz-user-drag:none;-ms-user-drag:none;-o-user-drag:none;user-drag:none;}
.ground {box-sizing:border-box;}
.ground {display:inline-block; width:100%; border:.2em solid; color:#8cc924; border-radius:.15em;}
/*PIECES*/
.black { color: black; }
.green { color: green; }
.red { color: red; }
.blue { color: blue; }
.empty { color: rgba(0,0,0,0); }
beige;:
40px;:
26px;:
3px;:
1px;:
2;: +( + )*
2;: +( + )*
.piece {
display: inline-block;
background-color: ;
border-radius: 2px;
height: ;
width: ;
text-align: center;
text-shadow: 1px 1px #FFFFFF;
padding: ;
cursor: pointer;
border-radius: ;
font-size: 1em;
font-family: 'Archivo Black', 'Arial Black';
margin: ;
user-select: none;
user-drag: none;
}
.piece:after { position: relative; text-align: center; top: -10px; content: "●"; }
.empty:after { position: relative; text-align: center; top: -10px; content: "_"; }
.empty { text-shadow: 0px 0px rgba(0,0,0,0); }
.piece {
border-top: 2px solid white;
border-left: 2px solid white;
border-right: 2px solid gray;
border-bottom: 2px solid gray;
}
.piece { border: 1px solid black; }
/**/
.rowling {
width: 10%;
height: 10px;
padding: 0px;
border: 1px solid black;
background-color: brown;
}
.rowling:after { content: "" }
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// vv https://raw.github.com/gist/1579671/rAF.js
////////////////////////////////////////////////////////////////
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller
// fixes from Paul Irish and Tino Zijdel
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|| window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
////////////////////////////////////////////////////////////////
// vv https://raw.github.com/gist/3225993/loop.js
////////////////////////////////////////////////////////////////
// Generated by CoffeeScript 1.3.3
(function() {
var Loop, periodicTimeout,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
periodicTimeout = function(callback, element, interval) {
return setTimeout(function() {
return callback((new Date).getTime() + interval);
}, interval);
};
Loop = (function() {
function Loop(f, interval) {
this.f = f != null ? f : (function() {});
this.interval = interval;
this.stop = __bind(this.stop, this);
this.start = __bind(this.start, this);
}
Loop.prototype.start = function() {
var animLoop, lastCallAt, method,
_this = this;
if (this.id) {
return;
}
method = this.interval != null ? periodicTimeout : window.requestAnimationFrame;
lastCallAt = void 0;
(animLoop = function(time) {
if (time == null) {
time = (new Date).getTime();
}
if (_this.f(time, lastCallAt) === false) {
return _this.stop();
}
lastCallAt = time;
return _this.id = method(animLoop, void 0, _this.interval);
})();
return this;
};
Loop.prototype.stop = function() {
var method;
if (this.id == null) {
return;
}
method = this.interval != null ? clearTimeout : cancelAnimationFrame;
method(this.id);
this.id = void 0;
return this;
};
return Loop;
})();
this.Loop = Loop;
if (typeof module !== "undefined" && module !== null) {
module.exports = this.Loop;
}
}).call(this);
////////////////////////////////////////////////////////////////
// vv http://bl.ocks.org/3411189 (without ball & crates)
////////////////////////////////////////////////////////////////
(function () {
// Flatten Box2d (ugly but handy!)
(function b2(o) {
for (k in o) {
if (o.hasOwnProperty(k)) {
if ($.isPlainObject(o[k])) {
b2(o[k]);
} else if (/^b2/.test(k)) {
window[k] = o[k];
}
}
}
}(Box2D));
var world = new b2World(
new b2Vec2(0, 9.81), // gravity
false // allow sleep
);
var SCALE = 30;
//
// Ground
//
(function ($ground) {
// Fixture
var fixDef = new b2FixtureDef;
fixDef.density = 1;
fixDef.friction = 0.5;
fixDef.restitution = 0.2;
// Shape
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(
$ground.outerWidth() / 2 / SCALE, //half width
$ground.outerHeight() / 2 / SCALE //half height
);
// Body
var bodyDef = new b2BodyDef;
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = ($ground.offset().left + $ground.outerWidth() / 2) / SCALE;
bodyDef.position.y = ($ground.offset().top + $ground.outerHeight() / 2) / SCALE;
var body = world.CreateBody(bodyDef);
body.CreateFixture(fixDef);
$ground.data('body', body);
}($('.ground')));
//
// Pieces
//
$('.piece').each(function (i, el) {
var $crate = $(el);
// Fixture
var fixDef = new b2FixtureDef;
fixDef.density = 1;
fixDef.friction = 0.5;
fixDef.restitution = 0.2;
// Shape
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(
$crate.outerWidth() / 2 / SCALE, //half width
$crate.outerHeight() / 2 / SCALE //half height
);
// Body
var bodyDef = new b2BodyDef;
bodyDef.type = b2Body.b2_dynamicBody;
bodyDef.position.x = ($crate.offset().left + $crate.outerWidth() / 2) / SCALE;
bodyDef.position.y = ($crate.offset().top + $crate.outerHeight() / 2) / SCALE;
var body = world.CreateBody(bodyDef);
var fixture = body.CreateFixture(fixDef);
$crate.data('body', body);
$crate.data('fixture', fixture)
});
//
// MouseJoint
//
var mouse = new b2Vec2();
$(window).mousemove(function (e) {
mouse.Set(e.pageX / SCALE, e.pageY / SCALE);
});
window.mouse = mouse;
(function (mouse) {
var mouseJointDef = new b2MouseJointDef();
mouseJointDef.target = mouse;
mouseJointDef.bodyA = world.GetGroundBody();
mouseJointDef.collideConnected = true;
var mouseJoint;
$('.piece').on({
mousedown: function (e) {
var body = $(this).data('body'); if (!body) return;
mouseJointDef.bodyB = body;
mouseJointDef.maxForce = 300 * body.GetMass();
mouseJoint = world.CreateJoint(mouseJointDef);
mouseJoint.SetTarget(mouse);
function mouseup(e) { world.DestroyJoint(mouseJoint); }
$(window).one('mouseup', mouseup);
}
});
}(mouse));
//
// Loops
//
(function () {
var dt = 60;
new Loop(function () {
world.Step(
1/dt, //frame-rate
10, //velocity iterations
10 //position iterations
);
world.ClearForces();
}, 1000/dt).start();
}());
(function () {
var $entities = $('.piece');
// cache some initial coordinates informations
$entities.each(function (i, el) {
var $el = $(el);
$el.data('origPos', {
left: $el.offset().left,
top: $el.offset().top,
width: $el.outerWidth(),
height: $el.outerHeight()
});
});
new Loop(function (t, t0) {
if (!t0) return;
var dt = t - t0;
if (dt <= 0) return;
var i = $entities.length
while (i--) {(function () {
var entity = $entities[i];
var $entity = $(entity);
var body = $entity.data('body');
var pos = body.GetPosition();
var ang = body.GetAngle() * 180 / Math.PI;
var origPos = $entity.data('origPos')
$entity.css('transform', 'translate3d(' + ~~(pos.x*SCALE - origPos.left - origPos.width / 2) + 'px, ' + ~~(pos.y*SCALE - origPos.top - origPos.height / 2) + 'px, 0) rotate3d(0,0,1,' + ~~ang + 'deg)');
}());}
}).start();
}());
}(jQuery, Box2D));