# One-color.js

## JS colors made easy

Peter Müller, Web developer @onecom

# Introduction

- One.com, shared hosting webspaces
- 8 frontend webdevs adding value to product
- Webmail, Abook, Calendar, Filemanager, Blog, Gallery, Webcreator etc...
- All partially or completely JS → Huge toolchain → Modular libs

## Why do we need it?

- Administration for blog, gallery etc
- User choice
- Webpages should look different than the other customers's

## Why do we need it?

- Alternate colors hues
- Color variants based on a user choice
- Text legibility on random background color

## ?

- Custom color picker components
- Automatic colorization of maps etc
- Animation
- Canvas manipulation

# But first...

A little domain knowledge

## Displays

## RGB

## HSV

- Hue: 360 degrees pure color
- Saturation: colorfullness
- Value: amount of light
- More intuitive than RGB

## HSL

- Lightness vs value

- Conversion to RGB looses information
- Uniquely defined in RGB
- White and black ambiguous in HSV, HSL
- Bonusinfo: There are a lot more color spaces

## CSS syntaxes

- `#123456`
- `rgb (100, 100, 100)`
- `rgba(100, 100, 100, 0.5)`
- `hsl (100, 100, 100)`
- `hsla(100, 100, 100, 0.5)`

## Specifications

- RGB, HSL and HSV
- Colorspace conversions
- A 'datatype'
- Pluggable architecture
- Chainable modifiers
- SMALL!

## Options

- Ext JS
- Micro library
- Roll your own

## Ext JS

- Seriously?

- Representation: Hex-string
- Color spaces
- Color conversion

## Micro library

- Lots to choose from
- Lots to choose from!
- Math is well documented
- Architecture is difficult

## Lack of data model

- `"#000000"`
- `[0, 0, 0]`
- `{ R: 0, G: 0, B: 0 }`
- `{ space: 'rgb', R: 0, G: 0, B: 0 }`

## Conversion methods

- `fromHexToRGB()`
- `fromRGBToHex()`

- `fromHexToHSV()`
- `fromRGBToHSV()`
- `fromHSVToHex()`
- `fromHSVToRGB()`

- `fromHexToHSL()`
- `fromRGBToHSL()`
- `fromHSVToHSL()`
- `fromHSLToHex()`
- `fromHSLToRGB()`
- `fromHSLToHSV()`

- RGB and HEX. Simple
- Lets add HSV
- Now HSL... You see where this is going
- Lots of methods, lots of bytes, lots of mental maintenance

## Chained modifiers

- Object with conversion methods
- Object with channel modifier methods

## Color representation

- Red: [0;255]
- Green: [0;255]
- Blue: [0;255]

- Hue: [0;360]
- Saturation: [0;100]
- Value: [0;100]
- Lightness: [0;100]

Color math: [0;1]

- RGB: Integers
- HSL/HSVL: Floating point? Browsers don't get it
- Math: Infinetly precise → Aproximate by using floating point
- Other libs only think one conversion at a time

## And the winner is...

- None :(

... but take a look at https://github.com/harthur/color, lots of good ideas!

# One-color.js

## Specifications

- RGB, HSL and HSV
- Colorspace conversions
- A 'datatype'
- Pluggable architecture
- Chainable modifiers
- SMALL!

- Parse once
- Round once
- Avoid loss of precision

## Base

    one.color = { // General namespace for One.com libs
        color = function( one.color.* | Array | String | Int ), // Parser
    };
    one.color.installColorSpace: function ( str space, [str channelNames], obj methods )
    one.color.installColorSpace("RGB", "Red", "Green", "Blue", "Alpha", {...});

    one.color.RGB  = function ( [0;1], [0;1], [0;1], [0;1] ) // Constructor

And with plugins:

    one.color.HSV  = function ( [0;1], [0;1], [0;1], [0;1] ) // Constructor

    one.color.HSL  = function ( [0;1], [0;1], [0;1], [0;1] ) // Constructor

    one.color.CMYK = function ( [0;1], [0;1], [0;1], [0;1] ) // Constructor

- This is the new API
- Array: toJSON and back!
- String: Hex, RGB, HSL, HSV
- Notice the normalization to [0;1]

## installColorSpace

Metaprogramming FTW!

Methods added to all installed one.color.* prototypes:

- `toString() → "[one.color.RGB: Red=0 Green=0 Blue=0 Alpha=1]"`
- `hex() → "#RRGGBB"`
- `css() → "rgb([0;255], [0;255], [0;255])"`
- `cssa() → "rgb([0;255], [0;255], [0;255], [0;1])"`
- `toJSON() → ["RGB", [0;1], [0;1], [0;1], [0;1]]`
- `equals(otherColor, ε = 10-9) → Boolean`
- `[colorSpace] → one.color[colorSpace]`
- `[channelName] → Number [0;1]`
- `[channelName]([0;1]) → new one.color[colorSpace], channelName = [0;1]`
- `[channelName](±[0;1], true) → new one.color[colorSpace], channelName ±= [0;1]`

## installColorSpace

How to write a colorSpace plugin

    one.color.installColorSpace('HSV', ['Hue', 'Saturation', 'Value', 'Alpha'], {
        fromRgb: function () { // Becomes one.color.RGB.prototype.toHSV
            // SNIP! Colormath is boring, lets go shopping!
            return new one.color.HSV(h, s, v, this.alpha);
        },

        rgb: function () {
            // SNIP! Colormath... Go read wikipedia
            return new one.color.RGB(r, g, b, this.alpha);
        },

        hsl: function () {
            // SNIP! Colormath... Just copy/paste from someone else
            return new one.color.HSL(this.h, s, l, this.alpha);
        }
    });

## API usage

Color space conversions

    one.color("#99FFFF")
        .hsv()
        .hsl()
        .cmyk()
        .hex(); → "#99FFFF"

Conversions are implicit, why bother...

## API usage

Channel manipulation methods

    one.color("#99FFFF")
        .red(0.5)
        .hue(-0.2, true)
        .magenta(0)
        .hex(); → "#99ff80"

## Future possibilities

- More color spaces
- Text contrast method
- Intuitive adjustment methods
- Photoshop blending modes
- To/from canvas array
- Color picker components

## FAQ

Based on the rewritten API version on the 'newapi' branch

- File size: 5.4k minified,
- License: 3 clause BSD
- Works in any browser
- Works in NodeJS
- Github: https://github.com/One-com/one-color

# DEMOTIME!

E
. . .. . . .. . .
RGB

Red

Green

Blue

HSV

Hue

Saturation

Value

CMYK

Cyan

Magenta

Yellow

blacK

Alpha

The CSS NYAN CAT was created by Michal Budzynski for Mozilla Demo Party in Helsinki June 2011

Sound was disabled for the audiences/visitors pleasure...

# Questions?