PDA

View Full Version : Coloring by daylight



prometheus
6 May 2009, 12:08 PM
Hello, I made a tool to paint daylight in a specified element`s background in real-time (as you can see within your window - if you have one :D). It`s just a funny little hack so use with bless :)

/**
* This is a daylight coloring tool for ExtJS 3 or ExtCore 3.
*
* @author prometheus <fejlesztes@php-sparcle.hu>
*/

Ext.namespace('Color');

/**
* @class Color.HSV
* A Hue-Saturation-Value coloring tool class.
* @constructor
* @param {Number} h Hue 0-255
* @param {Number} s Saturation 0-100
* @param {Number} v Value 0-100
*/
Color.HSV = function(h, s, v)
{
this.h = h;
this.s = s;
this.v = v;
}

/**
* @class Color.RGB
* A Red-Green-Blue coloring tool class.
* @constructor May call without parameters, that`s creating #000000, or only
* one string parameter with an HTML-formed RGB color ('#001122').
* @param {Number} r Red 0-255
* @param {Number} g Green 0-255
* @param {Number} b Blue 0-255
*/
Color.RGB = function(r, g, b)
{
if (r === undefined)
{
this.r = 0;
this.g = 0;
this.b = 0;
}
else if (r instanceof String)
{
this.fromHex(r);
}
else
{
this.r = r;
this.g = g;
this.b = b;
}
}

Color.HSV = Ext.extend(Color.HSV, {
/**
* Returns this color in a new RGB object.
* @return {Color.RGB}
*/
toRgb: function()
{
var r, g, b;
var h = this.h / 360;
var s = this.s / 100;
var v = this.v / 100;
var var_h, var_i, var_1, var_2, var_3, var_r, var_g, var_b;

if (s == 0)
{
r = v * 255;
g = v * 255;
b = v * 255;
}
else
{
var_h = h * 6;
var_i = Math.floor(var_h);
var_1 = v * (1 - s);
var_2 = v * (1 - s * (var_h - var_i));
var_3 = v * (1 - s * (1 - (var_h - var_i)));

if (var_i == 0) {var_r = v; var_g = var_3; var_b = var_1}
else if (var_i == 1) {var_r = var_2; var_g = v; var_b = var_1}
else if (var_i == 2) {var_r = var_1; var_g = v; var_b = var_3}
else if (var_i == 3) {var_r = var_1; var_g = var_2; var_b = v}
else if (var_i == 4) {var_r = var_3; var_g = var_1; var_b = v}
else {var_r = v; var_g = var_1; var_b = var_2};

r = var_r * 255;
g = var_g * 255;
b = var_b * 255;
}

return new Color.RGB(Math.round(r), Math.round(g), Math.round(b));
}
});

Color.RGB = Ext.extend(Color.RGB, {
/**
* Returns this color as HTML formatted RGB String ('#001122').
* @return {String}
*/
toHex: function()
{
return '#' + this.hexify(this.r) + this.hexify(this.g) + this.hexify(this.b);
},
/**
* Setup this color by HTML formatted RGB color.
* @param {String} colorString Color in format '#001122'.
*/
fromHex: function(colorString)
{
this.r = decimalize(colorString.substring(1,3));
this.g = decimalize(colorString.substring(3,5));
this.b = decimalize(colorString.substring(5,7));
},
// private - helper
hexify: function(number)
{
var digits = '0123456789ABCDEF';
var lsd = number % 16;
var msd = (number - lsd) / 16;
var hexified = digits.charAt(msd) + digits.charAt(lsd);
return hexified;
},
// private - helper
decimailze: function(hexNumber)
{
var digits = '0123456789ABCDEF';
return ((digits.indexOf(hexNumber.charAt(0).toUpperCase()) * 16) + digits.indexOf(hexNumber.charAt(1).toUpperCase()));
},
/**
* Helping represent this color as HTML formatted RGB String.
* @return {String}
*/
toString: function()
{
return this.toHex();
}
});

/**
* @class Daylight
* Static manager-class for daylight coloring a specified element. After the
* {@link #Daylight.init initialization}, the manager sets the specified element`s
* backgrund color as the actual time of client browser, and registers a task
* to actualize this color by time to time. Sample init:
* <code><pre>Ext.onReady(
function()
{
Daylight.init(Ext.getBody());
}
);</pre></code>
*/
Daylight =
{
/**
* @property {Color.HSV} HSV
* Before init, you can change this property for your best. Changing the
* Hue-value effects in another color (default 200 is a sky-blue like).
*/
HSV: new Color.HSV(200, 100, 0),
// private
mulS: -1,
// private
mulV: 1,
// private
El: null,
// private
ms: 0,
// private
initTask: null,
// private
initRan: false,
// private - handling a tick of coloring task.
tick: function()
{
this.HSV.s += this.mulS;
this.HSV.v += this.mulV;

if (this.HSV.s < 0)
{
this.HSV.s = 0;
this.mulS = 1;
}
else if (this.HSV.s > 100)
{
this.HSV.s = 100;
this.mulS = -1;
}

if (this.HSV.v < 0)
{
this.HSV.v = 0;
this.mulV = 1;
}
else if (Daylight.HSV.v > 100)
{
this.HSV.v = 100;
this.mulV = -1;
}
},
// private - changes the background color of specified element.
paint: function()
{
this.El.applyStyles({
backgroundColor: Daylight.HSV.toRgb().toString()
});
//console.log('paint! - ' + new Date() + ' - ' + Daylight.HSV.toRgb().toString());
},
/**
* Initialize the class and specifing the element being daylight colored.
* @param {Ext.Element} el
*/
init: function(el)
{
var now = new Date();
var today = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);
var t, tm;

this.El = el;
this.ms = 432000; // = ((24 / 2) * 60 * 60 * 1000ms) / 100 = 7.2 minutes
t = Math.floor(((now.getTime() - today.getTime())) / this.ms);

// Calibrate actual daylight color with playing needed ticks.
for (var i=0; i<t; i++)
{
this.tick();
}

this.paint();

// On first case, we need to wait for next tick-time.
tm = (now.getTime() - today.getTime()) % this.ms;
this.initTask = {
interval: tm,
run: function()
{
if (Daylight.initRan)
{
Ext.TaskMgr.stop(Daylight.initTask);

// Task runs 100 times within 12 hours.
Ext.TaskMgr.start({
interval: Daylight.ms,
run: function()
{
Daylight.tick();
Daylight.paint();
}
});
}
Daylight.initRan = true;
}
}
Ext.TaskMgr.start(this.initTask);
}
};Init code sample:

Ext.onReady(
function()
{
Daylight.init(Ext.getBody());
}
);Any replies/responds would be welcome - thanks for use :) Tested on FF3 ONLY, works properly on it for me.

jay@moduscreate.com
6 May 2009, 12:27 PM
why Color.HSV = Ext.extend(Color.HSV, { ? and not just Color.HSV.prototype = ?

or just extend Object and specify the constructor in extend?

prometheus
6 May 2009, 12:36 PM
I see this pattern in the Ext.data.Store (if I remember that properly) and don`t thinking a lot for any other solution. I know that this code is not my best but it`s works and this motivate me as a newbie in Ext :)

Thanks for your response, I`m learning every time on comments like yours.

Joe
7 May 2009, 6:38 AM
Thanks for the sharing the really slick and useful HSV/RGB conversion code.

Note: I had to make the following change in the daylight example for it to run on Ext JS Core....


paint: function()
{
//added this ... setStyle supported by Ext Core
this.El.setStyle('backgroundColor', Daylight.HSV.toRgb().toString() );
/* REMOVED THIS - applyStyles not available in the Core
this.El.applyStyles({
backgroundColor: Daylight.HSV.toRgb().toString()
});
*/
//console.log('paint! - ' + new Date() + ' - ' + Daylight.HSV.toRgb().toString());
},


You see quite a few ways to create a class out there. The comments in this post prompted me to write up a quick post on the method used by the Ext JS Core examples and why they are like they are .. and how you can make protected variables using that technique ...
http://www.extjs.com/forum/showthread.php?p=326622#post326622

I updated your classes to use this technique last night:



Ext.ns('Color');

/* Color Conversion Classes
* Based on code/classes by: Csaba Dobai (prometheus) <csaba.dobai@php-sparcle.com>
*/

(function() {

Color.HSV = function(h, s, v) {
Ext.apply(this, { h: h, s: s, v: v });
}

Ext.extend(Color.HSV, Object, {
/**
* Returns this color in a new RGB object.
* @return {Color.RGB}
*/
toRgb: function() {
var r, g, b;
var h = this.h / 360;
var s = this.s / 100;
var v = this.v / 100;
var var_h, var_i, var_1, var_2, var_3, var_r, var_g, var_b;

if (s == 0) {
r = v * 255;
g = v * 255;
b = v * 255;
}
else {
var_h = h * 6;
var_i = Math.floor(var_h);
var_1 = v * (1 - s);
var_2 = v * (1 - s * (var_h - var_i));
var_3 = v * (1 - s * (1 - (var_h - var_i)));

if (var_i == 0) { var_r = v; var_g = var_3; var_b = var_1 }
else if (var_i == 1) { var_r = var_2; var_g = v; var_b = var_1 }
else if (var_i == 2) { var_r = var_1; var_g = v; var_b = var_3 }
else if (var_i == 3) { var_r = var_1; var_g = var_2; var_b = v }
else if (var_i == 4) { var_r = var_3; var_g = var_1; var_b = v }
else { var_r = v; var_g = var_1; var_b = var_2 };

r = var_r * 255;
g = var_g * 255;
b = var_b * 255;
}

return new Color.RGB(Math.round(r), Math.round(g), Math.round(b));
}
});


Color.RGB = function(r, g, b) {
if (r === undefined) {
this.r = 0;
this.g = 0;
this.b = 0;
}
else if (r instanceof String) {
this.fromHex(r);
}
else {
this.r = r;
this.g = g;
this.b = b;
}
}

Ext.extend(Color.RGB, Object, {
/**
* Returns this color as HTML formatted RGB String ('#001122').
* @return {String}
*/
toHex: function() {
return '#' + this.hexify(this.r) + this.hexify(this.g) + this.hexify(this.b);
},
/**
* Setup this color by HTML formatted RGB color.
* @param {String} colorString Color in format '#001122'.
*/
fromHex: function(colorString) {
this.r = decimalize(colorString.substring(1, 3));
this.g = decimalize(colorString.substring(3, 5));
this.b = decimalize(colorString.substring(5, 7));
},
// private - helper
hexify: function(number) {
var digits = '0123456789ABCDEF';
var lsd = number % 16;
var msd = (number - lsd) / 16;
var hexified = digits.charAt(msd) + digits.charAt(lsd);
return hexified;
},
// private - helper
decimailze: function(hexNumber) {
var digits = '0123456789ABCDEF';
return ((digits.indexOf(hexNumber.charAt(0).toUpperCase()) * 16) + digits.indexOf(hexNumber.charAt(1).toUpperCase()));
},
/**
* Helping represent this color as HTML formatted RGB String.
* @return {String}
*/
toString: function() {
return this.toHex();
}
});


})();



The Daylight works fine using that update.


Again, thanks for that code. I was able to prototype a really nice web-based color selector last night using this conversion code. I hope to have a demo of that up when my free time permits :)

Happy ExtJSing!

prometheus
7 May 2009, 12:08 PM
Oh, very thank you. About your modification: by a misspelling I`m originally use setStyle but my 3.0RC1.1 throws a tipical 'you are an error on line xxx' to my face :D I really don`t understand that, so I realize that is only my mistake, or browser cache drived me crazy again :)
If I have any free time (or within 2-3 hours) I`m going to build all of your and jgarcia`s suggestions.

Thank you again!

Joe
7 May 2009, 3:27 PM
Check out this prototype for a really nice color control that actually allows you to select any color in the book. This prototype adjusts the background color and some buttons created using css and basic HTML. The demo shows how you can use vertical and/or horizonal graphics / orientation and how you can use the end result for dynamic pursposes.

I am working on some smart skinning options that this will integrate into - why the goofy strung together demo for now.

When I get a nicer control / site / skins process going - I'll make a post with a link to the "final" (haha) version. However I thought you would get a kick out of seeing your code "In Action" another way.

How it works:
It works by using ...
- a 360 pixel wide image for Hue
- a 100 pixel wide image for Sat and Val
- when you mouse over the graphic, a control sends the adjusted [x/y] position based on direction [h(orz)/v(ert)]
- the current color is adjusted based on the control that is changed
- the background is set using that color
- the mocked up buttons are adjusting using hard coded VALs for shading


If you see the source - not much code - the power of the X in action.
A live demo:
http://www.josephfrancisart.com/joe/colordemo.nsf/Color?OpenForm

Joe
8 May 2009, 10:53 AM
Someone created a really killer color control.

http://ux.theba.hu/cp/

I won't spend any time on a color control - this one rocks. Back to skins for me :)