Cool Blobs

by secretgspot

HTML

<div class="controls">
    <button id="start"><em>go</em></button>
    <div><input type="number" id="count" value="20"></input></div>
</div>
<canvas id="c"></canvas>

CSS

body {
    padding: 0px;
    background: black;   
}
canvas {
    height: 100%; 
    width: 100%;
    display:block;
}
.controls {
    padding: 2px;
    padding-top: 0px;
    border-bottom-left-radius: 7px;
    border-bottom-right-radius: 7px;
    background: white;
    margin: auto;
    margin-bottom: -35px;
    width: 75px;
    position: relative;
}
.controls #count {
    border-bottom-left-radius: 5px;
    margin: 0;
    padding: 5px;
    border: none;
    height: 15px;
    background: #c0c0c0;
    display: block;
    width: auto;
    
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.controls #start{
    border-bottom-right-radius: 5px;
    margin: 0;
    border: none;
    height: 25px;
    background: #c0c0c0;
    display: block;
    float: right;
    width: 25px;
    cursor: pointer;
}
.controls div {
    overflow: hidden;
}
.controls #start em {
    text-indent: -999px;
    display: block;
    border-left:13px solid #e0e0e0;
    border-top:7px solid transparent;
    border-bottom:7px solid transparent;
    height: 1px;
    width: 0px;
}
.controls #start:hover em {
    border-left-color: white;
    
}

JavaScript

(function($) {
    function Vector(x, y) {
        this.x = x;
        this.y = y;
        this.magnitude = function() {
            return Math.sqrt(this.dot(this));
        };
        this.unit = function() {
            return this.scale(1 / this.magnitude());
        };
        this.add = function(that) {
            return new Vector(this.x + that.x, this.y + that.y);
        };
        this.subtract = function(that) {
            return new Vector(this.x - that.x, this.y - that.y);
        };
        this.scale = function(factor) {
            return new Vector(this.x * factor, this.y * factor);
        };
        this.dot = function(that) {
            return this.x * that.x + this.y * that.y;
        };
        this.distanceTo = function(that) {
            return this.subtract(that).magnitude();
        };
        this.toString = function() {
            return '(' + this.x + ',' + this.y + ')';
        };
    }

    var canvas = document.getElementById('c'),
        c = canvas.getContext('2d'),
        w,
        h,
        p,
        clr = ['red', 'green', 'blue', 'yellow', 'purple'];

    var resetSize = function() {
        canvas.height = $(canvas).height();
        canvas.width = $(canvas).width();
        w = canvas.width;
        h = canvas.height;
    };
    $(window).resize(resetSize);
    resetSize();
    
    function init(n) {
        p = [];
        for (var i = 0; i < n; i++) {
            var speed = Math.random() * 12;
            var angle = Math.random() * 2 * Math.PI;
            p.push(new Ball(
                new Vector(w / 2, h / 2),
                new Vector(Math.sin(angle) * speed, Math.cos(angle) * speed),
                Math.floor(Math.random() * 4 + 3),
                clr[Math.floor(Math.random() * clr.length)]
            ));
        }
    }
    init(20);
    var mousePos = null;
    var mouseDown = false;

    function Ball(position, velocity, radius, color) {
        this.position = position || new Vector(0, 0);
       ...