;(function () { 'use strict'; var canvas = document.getElementById( 'canvas' ); var ctx = canvas.getContext( '2d' ); var balls = []; var numBalls = 5; var spring = 0.03; var friction = 0.9; var gravity = 2; canvas.width = window.innerWidth; canvas.height = window.innerHeight; while(numBalls--) { balls.push(new Ball(20)); } var mouse = { x: 0, y: 0 }; canvas.addEventListener('mousemove', function(evt) { mouse.x = evt.clientX; mouse.y = evt.clientY; }); function Ball(radius, color) { this.x = 0; this.y = 0; this.vx = 0; this.vy = 0; this.radius = radius || 40; this.color = color || 'red'; } Ball.prototype.draw = function () { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false); ctx.fillStyle = this.color; ctx.fill(); }; function move(ball, targetX, targetY) { ball.vx += (targetX - ball.x) * spring; ball.vy += (targetY - ball.y) * spring; ball.vy += gravity; ball.vx *= friction; ball.vy *= friction; ball.x += ball.vx; ball.y += ball.vy; } function draw(ballB, i) { // if first ball, move to mouse if (i === 0) { move(ballB, mouse.x, mouse.y); ctx.moveTo(mouse.x, mouse.y); } else { var ballA = balls[i - 1]; move(ballB, ballA.x, ballA.y); ctx.moveTo(ballA.x, ballA.y); } ctx.lineTo(ballB.x, ballB.y); ctx.strokeStyle = 'purple'; ctx.stroke(); ballB.draw(); } ;(function drawFrame() { requestAnimationFrame( drawFrame ); ctx.clearRect( 0, 0, canvas.width, canvas.height ); // draw balls ctx.beginPath(); balls.forEach(draw); var ball0 = new Ball(); console.log(balls[1].radius); //draw(ball0); })(); })();