Edit in JSFiddle

var body = document.body; // container
var canvas = document.createElement("canvas");
canvas.width = body.clientWidth;
canvas.height = body.clientHeight;
body.appendChild(canvas);

var ctx = canvas.getContext("2d");
ctx.fillStyle = "#0099CC";
ctx.fillRect(0, 0, canvas.width, canvas.height);

//window.onresize = function(e) {
//    canvas.width = body.clientWidth;
//    canvas.height = body.clientHeight;
//}
//
//window.onresize(); // initial
var spring = 0.99;
var a_x = 0;
var a_y = 1000;
var Ball = function(x, y) {
    this.position_x = x || Math.random() * canvas.width;
    this.position_y = y || Math.random() * canvas.height;
    var dir = Math.random() * Math.PI * 2;
    var vel = Math.random() * 200;
    this.velocity_x = vel * Math.cos(dir);
    this.velocity_y = vel * Math.sin(dir);
    this.size = 10;
    this.collided = false;
    this.update = function(dt) {
        this.velocity_y += a_y * dt;
        this.position_x += this.velocity_x * dt;
        this.position_y += this.velocity_y * dt + 0.5 * a_y * dt * dt;
        

        if (this.position_x < this.size / 2) {
            this.position_x = this.size / 2;
            this.velocity_x *= -1;
        } else if (this.position_x > canvas.width - this.size / 2) {
            this.position_x = canvas.width - this.size / 2;
            this.velocity_x *= -1;
        }
        if (this.position_y < this.size / 2) {
            this.position_y = this.size / 2;
            this.velocity_y *= -1;
        } else if (this.position_y > canvas.height - this.size / 2) {
            this.position_y = canvas.height - this.size / 2;
            this.velocity_y *= -1;
        }
    };
    this.render = function() {
        ctx.beginPath();
        if (this.position_y < -this.size / 2) {
            ctx.moveTo(this.position_x, 0);
            ctx.lineTo(this.position_x + this.size / 2, Math.sqrt(3) * this.size / 2);
            ctx.lineTo(this.position_x - this.size / 2, Math.sqrt(3) * this.size / 2);
            ctx.lineTo(this.position_x, 0);
        } else
            ctx.arc(this.position_x, this.position_y, this.size / 2, 0, Math.PI * 2, false);
        ctx.closePath();
        ctx.fillStyle = this.collided ? "orange" : "white";
        ctx.fill();
    };
    this.collide = function(target) {
        var toTarget_x = target.position_x - this.position_x;
        var toTarget_y = target.position_y - this.position_y;
        var len = Math.sqrt(toTarget_x * toTarget_x + toTarget_y * toTarget_y);
        var rr = (this.size + target.size) / 2;
        // nomalize
        toTarget_x /= len;
        toTarget_y /= len;
        if (len < rr) {
            this.position_x -= (rr - len) * toTarget_x;
            this.position_y -= (rr - len) * toTarget_y;
            target.position_x += (rr - len) * toTarget_x;
            target.position_y += (rr - len) * toTarget_y;
        }
        var projToTarget = this.velocity_x * toTarget_x + this.velocity_y * toTarget_y;
        var projFromTarget = target.velocity_x * toTarget_x + target.velocity_y * toTarget_y;
        this.velocity_x -= (projToTarget - projFromTarget) * toTarget_x * spring;
        this.velocity_y -= (projToTarget - projFromTarget) * toTarget_y * spring;
        target.velocity_x -= (projFromTarget - projToTarget) * toTarget_x * spring;
        target.velocity_y -= (projFromTarget - projToTarget) * toTarget_y * spring;
    }
};

var balls = [];
for (var i = 0; i < 50; i++) {
    balls.push(new Ball());
}

var isMouseDown = false;
canvas.onmousedown = function() {
    isMouseDown = true;
}
canvas.onmousemove = function(event) {
    if (isMouseDown) {
        var x = event.pageX - canvas.offsetLeft;
        var y = event.pageY - canvas.offsetTop;
        balls.push(new Ball(x, y));
    }
};
canvas.onmouseup = function() {
    isMouseDown = false;
}

var checkCollision = function(ball1, ball2) {
    var dx = ball2.position_x - ball1.position_x;
    var dy = ball2.position_y - ball1.position_y;
    var distSq = dx * dx + dy * dy;
    var d = (ball1.size + ball2.size) / 2;
    if (distSq < d * d) {
        ball1.collide(ball2);
        ball1.collided = ball2.collided = true;
    }
};

var checkCollisionInCell = function(cell) {
    for (var i = 0, len = cell.length; i < len; i++) {
        for (var j = i + 1; j < len; j++) {
            checkCollision(cell[i], cell[j]);
        }
    }
}

var checkCollisionInTwoCells = function(cell1, cell2) {
    for (var i = 0, leni = cell1.length, lenj = cell2.length; i < leni; i++) {
        for (var j = 0; j < lenj; j++) {
            checkCollision(cell1[i], cell2[j]);
        }
    }
}

var maxsize = 50;
var columns = Math.floor(canvas.width / maxsize);
var rows = Math.floor(canvas.height / maxsize);
var cell_width = canvas.width / columns;
var cell_height = canvas.height / rows;
var cells;

var handle, last_time = +new Date();
var loop = function() {
    var now = +new Date();
    var dt = Math.min((now - last_time) / 1000, 0.1);
    ctx.fillStyle = "#0099CC";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    // build cells
    cells = []
    for (var r = 0; r < rows; r++) {
        cells[r] = [];
        for (var c = 0; c < columns; c++) {
            cells[r][c] = [];
        }
    }
    // put balls in cells
    for (var i = 0, len = balls.length; i < len; i++) {
        if (balls[i].position_y > 0) {
            var c = Math.floor(balls[i].position_x / cell_width);
            var r = Math.floor(balls[i].position_y / cell_height);
            cells[r][c].push(balls[i]);
        }
        balls[i].collided = false;
    }
    // check collision
    for (var r = 0; r < rows; r++) {
        for (var c = 0; c < columns; c++) {
            checkCollisionInCell(cells[r][c]);
            if (c < columns - 1)
                checkCollisionInTwoCells(cells[r][c], cells[r][c + 1]);
            if (c > 0 && r < rows - 1)
                checkCollisionInTwoCells(cells[r][c], cells[r + 1][c - 1]);
            if (r < rows - 1)
                checkCollisionInTwoCells(cells[r][c], cells[r + 1][c]);
            if (c < columns - 1 && r < rows - 1)
                checkCollisionInTwoCells(cells[r][c], cells[r + 1][c + 1]);
        }
    }
    // update balls
    for (var i = 0, len = balls.length; i < len; i++) {
        balls[i].update(dt);
        balls[i].render();
    }

    last_time = now;
    handle = requestAnimationFrame(loop);
};

loop(); // run