ini= res= tot= rot=

KOLORWHEEL.JS

Introduction

What is it?

This small javascript library is designed for developers, who have no talent and time to create professional color palettes. Pick a base color, build a transformation chain, and if you haven't choosen too weird parameters, the result will be satisfactory.

<div id="thanks">
  • Spectrum Colorpicker
  • Open Sans font
  • Droid Sans Mono font
  • Google font hosting
  • HSL cone image
  • Hue order image
  • Caution sign image
  • Web hosting
</div>

Features

• HSL color model, produces HTML hex notation result
• Simple direct access to the object's H, S, L properties
• Relative and absolute gradient generation methods
• Methods are chainable, provides each() callback
• jQuery support, 2 * n lines of code produces gradient for n CSS attribs
• No licence, open source, free (as beer), download or fork it now!

Try live examples!

In the examples below you can change some parameters. As you modify the code, it will be executed immediatelly.

The magic world of colors

The HSL color model

HSL cone (image: Wikipedia)

If you have ever seen a color picker before, you're probably familiar with the HSV or HSL color model. You may try Most Excellent HSL Color Picker, also don't miss the docs.

In the HSL model colors are defined by the following parameters:

• Hue: base color, defined by angle. 0° is red, 180° is cyan.
• Saturation: 0% is gray, 100% is full color.
• Lightness: 0% is black, 100% is white. Use 50% for full saturated colors.

Restrictions

Keep in mind, HSL color space is a cone-shaped coordinate system:

• As far as we go any direction from the lightness value of 50, the other parameters have as less effect. When lightness is 0 or 100, the color will be black or white respectivelly, regardless of the value of hue and saturation.
Hue order (image: Gamasutra)
• As saturation value gets lower, hue will have as less effect. When saturation is 0, the color will be a shade of gray defined by the value of lightness, and hue will have no effect at all.

That's why the most accurate 2D representation of the HSL color space is the triangle color picker (not explained here).

Do you know...

Do you know where does the hue order come from? The answer is pretty obvious, see figure. Or check this.

Defining colors

Constructors

HTML hex notation can be used in constructor, with or without hashmark.

var color = new KolorWheel("#{{336699}}"); paintBox(color.getHex()); var color = new KolorWheel("{{33cc66}}"); paintBox(color.getHex());

When the constructor is an array, it's interpreted as array of H, S, L values.

var color = new KolorWheel([{{ 45}},{{100}},{{ 60}}]); paintBox(color.getHex());

Last, KolorWheel object can be created from another KolorWheel object.

var base = new KolorWheel("#{{cc6666}}"); paintBox(base.getHex(),"base"); var gray = new KolorWheel(base); gray.s = {{ 0}}; paintBox(gray.getHex(),"gray"); var lite = new KolorWheel(base); lite.l += {{ 30}}; paintBox(lite.getHex(),"lite");

Direct H, S, L access

You can access h, s and l properties directly.

var color = new KolorWheel(); color.h = {{ 180}}; color.s = {{100}}; color.l = {{ 70}}; paintBox(color.getHex()); color.l -= {{ 40}}; paintBox(color.getHex());

Overlflow

Hue can't overflow, the wheel has no ends. You may also use negative numbers.

var h = {{ -45}}; for (var n = 0; n < 10; n++) { var color = new KolorWheel([h,100,50]); paintBox(color.getHex(),h + "°"); h += {{ 45}}; } // for hue

When saturation or lightness overflows, the value will be cut back in the 0..100 range.

var s = {{ -25}}; for (var n = 0; n < 7; n++) { color = new KolorWheel([90,s,50]); paintBox(color.getHex(),s + "->" + color.s); s += {{ 25}}; } // for s paintBreak(); var l = {{-25}}; for (var n = 0; n < 7; n++) { color = new KolorWheel([90,70,l]); paintBox(color.getHex(),l + "->" + color.l); l += {{ 25}}; } // for l

Getting color value

In the examples we used getHex() method to get result in HTML notation format. There are also getHsl() and getRgb() methods, they will return array.

When the generated color is used as background, isDark() or isLight() helps to determine whether light or dark foreground color should be used. Note that these methods provide better result which can be achieved by checking value of the l (lightness) property.

Creating gradients

Caution! Less is more!
Don't use too many colors! Don't apply gradient on everything! Don't change H, S, V parameters at the same time! Gray is a beautiful color! Preserve your ink toner, use moderate color scheme!

Basic gradient

The simplest way to create a gradient is to morph one color to another. The target of the morph operation is an absolute color, so we will use abs() method. This method handles the first parameter, which is the target color, as the constructor does: it can be HTML hex value, H, S, L array or another KolorWheel object. Second parameter is the length of the gradient, optional third parameter is the starting index.

var base = new KolorWheel("#{{eeffff}}"); var target = base.abs("#{{330066}}",10); for (var n = 0; n < 10; n++) { paintBox(target.get(n).getHex(),n); } // for gradient

Gradient methods, like abs() produces a series of KolorWheel objects, they can be accessed by calling get() method of the original object with the index of requested step as parameter.

Absolute gradient

When the first parameter of the abs() method is a number, the first three parameters are interpreted as hue, saturation and lightness. Special value of -1, occurs that it won't changed in the gradient items, all the result will have the same H, S or L value.

(new KolorWheel("#{{0000cc}}")).abs({{ 0}},-1,-1,8).each(function() { paintBox(this.getHex(),this.step); });

In this example, only hue is changed to the specified target absolute value, the saturation and lightness are keeping source color's values.

We used each() method there, it sets this to the actual KolorWheel element. The property named this.step holds the step index of the actual gradient.

Relative gradient

The rel() method's parameters are the final distance from the original values, in the usual hue, saturation, lightness order. Special value of 0 occurs that it won't changed, the result will inherit base color's H, S or L value.

(new KolorWheel([{{270}},{{ 20}},10])).rel(0,0,80,7).each(function() { paintBox(this.getHex(),this.step); });

Advanced techniques

Array parameters

As we've seen, the hue, saturation and lightness parameters of abs() and rel() can be numeric, or a special "won't change" value. There is another option: they can be also arrays.

When you define any of H, S, L parameters as array, abs() and rel() will pick next value from the array in each step.

(new KolorWheel("#{{cccccc}}")).rel(-1,-1,[{{ 0}},{{ 10}}],10).each(function() { paintBox(this.getHex()); });

If you don't define length, the gradient length value will be the longest of H, S, L arrays.

(new KolorWheel("#ff0000")) .abs([0,0,{{ 45}}],[100,40,100],{{ 80}},9).each(function() { paintBox(this.getHex(),this.step); });

In this example, we've defined hue and saturation array same length, so the following triad moves together: 0° red with 100% saturation, 0° red with 40% saturation and 45° orange with 100% saturation. Meanwhile, lightness is morphing to 80%, in 9 steps.

Applying colors on elements

Until now, we've used paintBox() function to display results, but in the wild, we have to apply colors on existing DOM elements. Everyone's using jQuery, so KolorWheel.js supports it.

When the length parameter of abs() or rel() is replaced by a jQuery selector function result, the gradient length will be the length of the result it. Then, you will get jQuery items in the parameter of the each() method.

(new KolorWheel([{{ 45}},100,50])) .abs(-1,50,80,$(".abc")).each(function(elm) { elm.css("background",this.getHex()); });

 A    B    C    D    E    F    G    H    I    J    K    L    M    N    O    P    Q    R    S    T    U    V  

When you want to apply two different KolorWheel gradient on the same jQuery result set, you can refer to external KolorWheel result items in the each() callback by using external color's get() method with this.step.

The KolorWheel result lists should be the same length, but that's not a problem, because you can use the same jQuery selector result on the external KolorWheels as the gradient method length parameter.

var baseHue = {{ 12}}; var jqElms = $(".bcd"); var external = new KolorWheel([45 + baseHue,100,60]) .abs(-1,100,60,jqElms); (new KolorWheel([baseHue,100,50])) .abs(-1,50,80,jqElms).each(function(elm) { elm.css("background",this.getHex()); elm.css("color",external.get(this.step).getHex()); });

 B    C    D    E    F    G    H    I    J    K    L    M    N    O    P    Q    R    S    T    U    V    W  

Nesting

There is only one new thing comes into the picture: abs() and rel() have yet another parameter, which describes how many leading items should be omitted. When you use outer loop's result, it's useful to skip inner loop's first result item, because it's the same as the outer item.

(new KolorWheel("#{{cc2200}}")) .rel([0,{{ 180}},30,210,90],0,0).each(function() { paintBreak(); paintBox(this.getHex(),this.step); this.rel({{ 0}},{{-50}},{{ 40}},10, 1 /* skip 0 */ ).each(function() { paintBox(this.getHex()); }); });

Chaining

Gradient methods can be chained. When applying a method on a base result set, it replaces each item with a new result list.

(new KolorWheel("#aa0000")) .abs([0,{{270}}],25,-1,8).rel({{ 0}},{{ 0}},{{ 40}},5).each(function() { paintBox(this.getHex()); });

In this example, the abs() method flip/flops between 0° red and 270° blue meanwhile morphing into 25% saturated grayish, in 8 steps. These colors are the 1st and 6th columns.

The chained rel() method picks this 8 items, and replaces each with 5 items, which gets lighter by 40%.

The result is 8 * 5 = 40 items.

Pointless further examples

Fading out

var a = (new KolorWheel("#{{0000ff}}")).rel({{ 0}},{{ 0}},{{ 30}},5); var b = (new KolorWheel("#{{ff0000}}")).rel({{ 0}},{{-20}},{{ 40}},5) .each(function() { paintBreak(); (new KolorWheel(a.get(this.step))).abs(this,10).each(function() { paintBox(this.getHex()); });; });

Different grays

(new KolorWheel([0,{{ 5}},60])).abs([{{ 0}},{{ 23}},{{ 45}},{{ 90}},{{180}}]) .abs(-1,-1,90,10).each(function() { paintBox(this.getHex()); });

Pepita

(new KolorWheel([{{ 120}},{{ 40}},{{ 40}}])) .rel(360,25,40,30).rel({{ 0}},{{ 0}},[-10,0,+10]).each(function() { paintBox(this.getHex()); });