var width = 500; var height = 400; var frameRate = 1/40; // Seconds var frameDelay = frameRate * 1000; // ms var loopTimer = false; var newObject = function (r, m, px, py, vx, vy, col, s) { staticObj = (typeof s === "undefined") ? false : s; return { colour: col, velocity: {x:0, y:0}, radius: r, mass: m, restitution: -0.7, position: {x: px, y: py}, static: staticObj } } var balls = [ newObject (15, 0.2, 0, 0, 0, 0, 'blue'), newObject (25, 0.3, 120, 120, 0, 0, 'red'), newObject (5, 0.1, 20, 120, 0, 0, 'yellow'), // newObject (30, 0.3, 200, 200, 0, 0, 'orange', true) ]; var G = 1000; var canvas = []; var ctx = []; var setup = function() { for (var i=0, ball = balls[0], arrCount = balls.length; i<arrCount; i++, ball = balls[i]) { var newCanvas = document.createElement('canvas'); newCanvas.setAttribute('id', 'canvas'+i); newCanvas.setAttribute('width', width); newCanvas.setAttribute('height', height); document.getElementsByTagName('body')[0].appendChild(newCanvas); canvas[i] = newCanvas; ctx[i] = canvas[i].getContext("2d"); ctx[i].fillStyle = balls[i].colour; ctx[i].strokeStyle = '#000000'; } loopTimer = setInterval(loop, frameDelay); } var loop = function() { for (var i=0, ball = balls[0], arrCount = balls.length; i<arrCount; i++, ball = balls[i]) { if ( ! ball.static ) { var theta = F = r2 = ry = rx = Dy = Dx = Fx = Fy = 0; for (var j=0; j<arrCount; j++) { if (j==i) continue; Dy = balls[j].position.y - ball.position.y; Dx = balls[j].position.x - ball.position.x; r = Math.sqrt(Math.pow(Dy,2) + Math.pow(Dx,2)); theta = Math.atan2(Dy, Dx); F = (G*ball.mass*balls[j].mass) / (r*r); Fx += F*Math.cos(theta); Fy += F*Math.sin(theta); } Fx = (isNaN(Fx) ? 0 : Fx); Fy = (isNaN(Fy) ? 0 : Fy); var ax = Fx / ball.mass; var ay = Fy / ball.mass; ball.velocity.x += ax*frameRate; ball.velocity.y += ay*frameRate; ball.position.x += ball.velocity.x*frameRate*100; ball.position.y += ball.velocity.y*frameRate*100; } ctx[i].clearRect(0,0,width,height); ctx[i].save(); ctx[i].translate(ball.position.x, ball.position.y); ctx[i].beginPath(); ctx[i].arc(0, 0, ball.radius, 0, Math.PI*2, true); ctx[i].fill(); ctx[i].closePath(); ctx[i].restore(); } } setup();
canvas { position: absolute; top: 0; left: 0; margin:20px auto; border:1px solid #666; height:400px; width:500px; }