Simple Color Scheme Generator

HTML

<canvas id="canvas"></canvas>

CSS

html, body { margin: 0; overflow: hidden; }

JavaScript

// http://printingcode.runemadsen.com/lecture-color/

function isArray( obj ) {

    return /\barray\b/i.test( isArray.test.call( obj ) )
}

isArray.test = ({}).toString

function random( min, max ) {

    if ( isArray( min ) ) return min[ ~~( Math.random() * min.length ) ]

    if ( max == null ) max = min, min = 0
    if ( max == null ) max = 1
    return min + Math.random() * ( max - min )
}

function clamp( n, min, max ) {

    return Math.min( max, Math.max( min, n ) )
}

// Color

function Color( h, s, l ) {

    this.h = ( h || 0 ) % 360
    this.s = clamp( s || 0, 0, 100 )
    this.l = clamp( l || 0, 0, 100 )
}

Color.random = function() {

    return new Color(
        random( 360 ),
        random( 30, 80 ),
        random( 20, 80 )
    )
}

Color.prototype = {

    toString: function() {

        return [
            Math.round( this.h ),
            Math.round( this.s ),
            Math.round( this.l ),
        ].join(',')
    },

    toCSSString: function() {
        
        return 'hsl(' + this.h + ',' + this.s + '%,' + this.l + '%)'
    }
}

// ColorScheme

function ColorScheme( base, size ) {

    this.base = base
    this.generate( size )
}

ColorScheme.prototype = {

    generate: function( size ) {

        this.colors = new Array( size || 10 )
        this.colors.push( this.base )

        var angle = this.base.h
        var theta = random([
            30,  // analogous
            60,  // triadic
            90,  // tetradic
            180, // complimentary
            random( 360 )
        ])

        var h = this.base.h
        var s = this.base.s
        var l = this.base.l

        for ( var i = 1, n = this.colors.length; i < n; i++ ) {

            h += theta * random( 0.9, 1.1 )
            s = clamp( s + random( -1, 1 ) * 25, 10, 90 )
            l = clamp( l + random( -1, 1 ) * 25, 10, 90 )

            this.colors[i] = new Color( h, s, l )
        }

        this.colors = this.colors.sort( function( a, b ) {
            return...