web 

Color extensions


part of wslib


Methods for Color processing, conversion and naming.

Used by SVG



Color name libraries


*web ( name, alpha )

the web method creates a table with 151 standard web color names, as found at

http://www.w3schools.com/html/html_colornames.asp


This method can be used in various ways:


Color.web;   // returns the table (an Event)

Color.web( \maroon );   // returns a color named "maroon"

Color.web[ \maroon ]; // also returns a color named "maroon"

Color.web.maroon; // and again returns a color named "maroon"


Color.web.keys.asArray.sort.dopostln; // post all names



*web16 ( name, alpha )

the web method creates a table with the 16 most common web color names, supported by the W3C HTML 4.0 standard. Works the same way as *web.


Color.web16.keys.asArray.sort.dopostln; // post all names



*xwindows ( name, alpha, includeGrayShades )

the web method creates a table with the X-windows colors as found in the Color code file in the ClassLibrary. Works the same way as *web. It is advisable to get the table into a variable once when using more then once for saving speed. The full table when includeGrayShades is true (default : false ) has 650 entries.


Color.xwindows( includeGrayShades: true ).keys.asArray.sort.dopostln; // post all names


(

var table, window, button, text, key;

table = Color.xwindows;

window = GUI.window.new( "colors" ).front;

text = GUI.staticText.new( window, Rect( 120, 10, 150, 20 ) );

button = GUI.button.new( window, Rect( 10, 10, 100, 20 ) )

.states_( [[ "new color" ]] )

.action_( {

key = table.keys.choose;

window.view.background = table[ key ];

text.string = key.asString;

} );

button.doAction;

)



Creation methods


*newHex ( hexName, alpha )

Creates a color from a web standard hex String or  Symbol ( like "#FFAA00" ). The hexName can also be a decimal number, for example produced using 16xFFAA00.


Color.newHex( "FFAA00" );

Color.newHex( "#FFAA00" );

Color.newHex( 16xFFAA00 );



*newName ( name, table, includeXWindows )

Creates a color from a web name. If the name is a number or a hex String / Symbol, it works as *newHex. If the name is a color name which is in the *web color table, the associated color will be returned. You can also provide your own color table with the table argument. By default the web table is used, but if includeXWindows is true (default : false ) the web and xwindows tables are combined, including the grayshades. There is also name conversion going on, providing compatibility with various naming conventions:


Color.newName( "EEE8AA" );

Color.newName( "PaleGoldenrod" );

Color.newName( "pale_goldenrod" ); 

Color.newName( 16xEEE8AA );

Color.newName( "none" );    // same as Color.clear




Accessing and conversion methods


*web related


hex

convert the color to a hex string


Color.newName( "EEE8AA" ).hex;  // proof of concept


webHex

convert the color to a hex string with a "#" char at the start


hexValue

convert the color to a decimal value derrived from the hex string


Color.newName( "EEE8AA" ).hexValue;


asWebColorString

convert the color to webcolor name if found or else a webHex string


Color.newName( "EEE8AA" ).asWebColorString;  // pale_golenrod

Color.newName( "FFAA00" ).asWebColorString;  // #FFAA00


asWebColorString can also be called on other objects:

Nil:asWebColorString ( default )  : returns default

String:asWebColorString ( default )  : returns default if not compatible

Symbol:asWebColorString ( default ) 

Number:asWebColorString ( default ) 


asColor

returns itself when called upon a Color, but returns a color when called upon a:

Number, String, Symbol or nil

asColor uses Color.newName internally



roundHex

returns a color rounded to the 24bit web color standard


Color(0.12345, 0.23456, 0.34567 ).asArray * 255;

Color(0.12345, 0.23456, 0.34567 ).roundHex.asArray * 255;


findWebColor ( table )

returns an alphabetically sorted array of web color names found with this color


Color.newName( "FF00FF" ).findWebColor;  // returns 2 web color names with identical hex values


findSameHueNames ( table )

returns an alphabetically sorted array of web color names with the same hue as this color


(

var window, table;

table = Color.web; // make table once for optimized speed

window = GUI.window.new( "purple shades" ).front;

window.view.decorator = FlowLayout( window.view.bounds );

Color.newName( "purple", table ).findSameHueNames( table )

.sort({ |a,b| Color.newName( a, table).lightness <= Color.newName( b, table ).lightness }) 

.do({ |name|

GUI.compositeView.new( window, 50@380 )

.background_( Color.newName( name, table ) );

});

)



processing methods


hue, sat, val

gets and sets HSV values for colors as if they were instance variables


lightness

returns the mean of red, green and blue


desaturate

desaturates the color in place


clip ( min, max )

clips the red, green and blue values in place


round ( quant )

rounds the red, green and blue values in place


saturate ( amount )

returns a saturated or desaturated version of the color ( amount : -1 to 1 )


hueAdd ( amount )

returns a hue-shifted version of the color ( amount : -1 to 1 )


blendVal ( amount, toVal )

returns a val-changed version of the color ( amount : -1 to 1, toVal : 0 to 1, default 0.5 )

This changes the lightness to an average value, thus decreases/increases lightness differences between  colors. Similar to contrast, but inversed and keeps color (doesn't fade to gray)


contrast ( amount )

returns a contrast changed version of the color ( amount : -1 to 1 )


brightness ( amount )

returns a brightness changed version of the color ( amount : -1 to 1 )


(

var window, button, comps, comps2, process, sliders;

window = GUI.window.new( "color processing", Rect(300, 100, 400, 282) ).front;

window.view.background_( Color.black );

window.view.decorator = FlowLayout( window.view.bounds );

comps = { GUI.compositeView.new( window, 40@25 ) } ! 9;

comps2 = { GUI.compositeView.new( window, 40@100 ) } ! 9;


process = { comps2.do({ |comp, i|

var newColor;

newColor = comps[i].background ?? { Color.clear };

sliders.do({ |sl, ii| 

newColor = newColor.perform( sl[0], sl[1].value.linlin(0,1,-1,1) );

});

comp.background = newColor;

});

};


sliders = [ \saturate, \hueAdd, \blendVal, \contrast, \brightness ].collect({ |item, i|

[ item,

GUI.slider.new( window, 280@20 )

.value_( 0.5 )

.background_( Color.gray(0.5) )

.action_({ process.value }),

GUI.staticText.new( window, 100@20 )

.string_( item.asString )

.stringColor_( Color.gray(0.5) )

] });

button = GUI.button.new( window, 80@20 ).states_( [[ "new colors" ]] )

.action_({ 

({ |i| Color.rand(0.0,1.0); } ! 9)

.sort({ |a,b| a.hue <= b.hue })

.do({ |color, i| comps[i].background_( color ) });

process.value;

});

button.doAction;


GUI.button.new( window, 80@20 ).states_( [[ "reset sliders" ]] )

.action_({ sliders.do({ |sl| sl[1].value = 0.5; }); process.value });

)