- Author:
- David Nickerson <nickerso@users.sourceforge.net>
- Date:
- 2009-07-07 22:22:32+12:00
- Desc:
- renaming files in order to move to a single reference description for the entire tutorial
- Permanent Source URI:
- https://models.physiomeproject.org/workspace/a1/rawfile/0c824288680f5949ea1972a76176826599ef6d26/dojo-presentation/js/dojo/dojox/color/Palette.js
dojo.provide("dojox.color.Palette");
dojo.require("dojox.color");
(function(){
var dxc = dojox.color;
/***************************************************************
* dojox.color.Palette
*
* The Palette object is loosely based on the color palettes
* at Kuler (http://kuler.adobe.com). They are 5 color palettes
* with the base color considered to be the third color in the
* palette (for generation purposes).
*
* Palettes can be generated from well-known algorithms or they
* can be manually created by passing an array to the constructor.
*
* Palettes can be transformed, using a set of specific params
* similar to the way shapes can be transformed with dojox.gfx.
* However, unlike with transformations in dojox.gfx, transforming
* a palette will return you a new Palette object, in effect
* a clone of the original.
***************************************************************/
// ctor ----------------------------------------------------------------------------
dxc.Palette = function(/* String|Array|dojox.color.Color|dojox.color.Palette */base){
// summary
// An object that represents a palette of colors.
// description
// A Palette is a representation of a set of colors. While the standard
// number of colors contained in a palette is 5, it can really handle any
// number of colors.
//
// A palette is useful for the ability to transform all the colors in it
// using a simple object-based approach. In addition, you can generate
// palettes using dojox.color.Palette.generate; these generated palettes
// are based on the palette generators at http://kuler.adobe.com.
//
// colors: dojox.color.Color[]
// The actual color references in this palette.
this.colors = [];
if(base instanceof dojox.color.Palette){
this.colors = base.colors.slice(0);
}
else if(base instanceof dojox.color.Color){
this.colors = [ null, null, base, null, null ];
}
else if(dojo.isArray(base)){
this.colors = dojo.map(base.slice(0), function(item){
if(dojo.isString(item)){ return new dojox.color.Color(item); }
return item;
});
}
else if (dojo.isString(base)){
this.colors = [ null, null, new dojox.color.Color(base), null, null ];
}
}
// private functions ---------------------------------------------------------------
// transformations
function tRGBA(p, param, val){
var ret = new dojox.color.Palette();
ret.colors = [];
dojo.forEach(p.colors, function(item){
var r=(param=="dr")?item.r+val:item.r,
g=(param=="dg")?item.g+val:item.g,
b=(param=="db")?item.b+val:item.b,
a=(param=="da")?item.a+val:item.a
ret.colors.push(new dojox.color.Color({
r: Math.min(255, Math.max(0, r)),
g: Math.min(255, Math.max(0, g)),
b: Math.min(255, Math.max(0, b)),
a: Math.min(1, Math.max(0, a))
}));
});
console.log("The return colors are ", ret.colors, " from the original colors ", p.colors);
return ret;
}
function tCMY(p, param, val){
var ret = new dojox.color.Palette();
ret.colors = [];
dojo.forEach(p.colors, function(item){
var o=item.toCmy(),
c=(param=="dc")?o.c+val:o.c,
m=(param=="dm")?o.m+val:o.m,
y=(param=="dy")?o.y+val:o.y;
ret.colors.push(dojox.color.fromCmy(
Math.min(100, Math.max(0, c)),
Math.min(100, Math.max(0, m)),
Math.min(100, Math.max(0, y))
));
});
return ret;
}
function tCMYK(p, param, val){
var ret = new dojox.color.Palette();
ret.colors = [];
dojo.forEach(p.colors, function(item){
var o=item.toCmyk(),
c=(param=="dc")?o.c+val:o.c,
m=(param=="dm")?o.m+val:o.m,
y=(param=="dy")?o.y+val:o.y,
k=(param=="dk")?o.b+val:o.b;
ret.colors.push(dojox.color.fromCmyk(
Math.min(100, Math.max(0, c)),
Math.min(100, Math.max(0, m)),
Math.min(100, Math.max(0, y)),
Math.min(100, Math.max(0, k))
));
});
return ret;
}
function tHSL(p, param, val){
var ret = new dojox.color.Palette();
ret.colors = [];
dojo.forEach(p.colors, function(item){
var o=item.toHsl(),
h=(param=="dh")?o.h+val:o.h,
s=(param=="ds")?o.s+val:o.s,
l=(param=="dl")?o.l+val:o.l;
ret.colors.push(dojox.color.fromHsl(h%360, Math.min(100, Math.max(0, s)), Math.min(100, Math.max(0, l))));
});
return ret;
}
function tHSV(p, param, val){
var ret = new dojox.color.Palette();
ret.colors = [];
dojo.forEach(p.colors, function(item){
var o=item.toHsv(),
h=(param=="dh")?o.h+val:o.h,
s=(param=="ds")?o.s+val:o.s,
v=(param=="dv")?o.v+val:o.v;
ret.colors.push(dojox.color.fromHsv(h%360, Math.min(100, Math.max(0, s)), Math.min(100, Math.max(0, v))));
});
return ret;
}
// helper functions
function rangeDiff(val, low, high){
// given the value in a range from 0 to high, find the equiv
// using the range low to high.
return high-((high-val)*((high-low)/high));
}
// object methods ---------------------------------------------------------------
dojo.extend(dxc.Palette, {
transform: function(/* Object */kwArgs){
// summary
// Transform the palette using a specific transformation function
// and a set of transformation parameters.
// description
// {palette}.transform is a simple way to uniformly transform
// all of the colors in a palette using any of 5 formulae:
// RGBA, HSL, HSV, CMYK or CMY.
//
// Once the forumula to be used is determined, you can pass any
// number of parameters based on the formula "d"[param]; for instance,
// { use: "rgba", dr: 20, dg: -50 } will take all of the colors in
// palette, add 20 to the R value and subtract 50 from the G value.
//
// Unlike other types of transformations, transform does *not* alter
// the original palette but will instead return a new one.
var fn=tRGBA; // the default transform function.
if(kwArgs.use){
// we are being specific about the algo we want to use.
var use=kwArgs.use.toLowerCase();
if(use.indexOf("hs")==0){
if(use.charAt(2)=="l"){ fn=tHSL; }
else { fn=tHSV; }
}
else if(use.indexOf("cmy")==0){
if(use.charAt(3)=="k"){ fn=tCMYK; }
else { fn=tCMY; }
}
}
// try to guess the best choice.
else if("dc" in kwArgs || "dm" in kwArgs || "dy" in kwArgs){
if("dk" in kwArgs){ fn = tCMYK; }
else { fn = tCMY; }
}
else if("dh" in kwArgs || "ds" in kwArgs){
if("dv" in kwArgs){ fn = tHSV; }
else { fn = tHSL; }
}
var palette = this;
for(var p in kwArgs){
// ignore use
if(p=="use"){ continue; }
palette = fn(palette, p, kwArgs[p]);
}
return palette; // dojox.color.Palette
},
clone: function(){
// summary
// Clones the current palette.
return new dxc.Palette(this); // dojox.color.Palette
}
});
// static methods ---------------------------------------------------------------
dojo.mixin(dxc.Palette, {
generators: {
analogous:function(/* Object */args){
var high=args.high||60, // delta between base hue and highest hue (subtracted from base)
low=args.low||18, // delta between base hue and lowest hue (added to base)
base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
hsv=base.toHsv();
// generate our hue angle differences
var h=[
(hsv.h+low+360)%360,
(hsv.h+Math.round(low/2)+360)%360,
hsv.h,
(hsv.h-Math.round(high/2)+360)%360,
(hsv.h-high+360)%360
];
var s1=Math.max(10, (hsv.s<=95)?hsv.s+5:(100-(hsv.s-95))),
s2=(hsv.s>1)?hsv.s-1:21-hsv.s,
v1=(hsv.v>=92)?hsv.v-9:Math.max(hsv.v+9, 20),
v2=(hsv.v<=90)?Math.max(hsv.v+5, 20):(95+Math.ceil((hsv.v-90)/2)),
s=[ s1, s2, hsv.s, s1, s1 ],
v=[ v1, v2, hsv.v, v1, v2 ]
return new dxc.Palette(dojo.map(h, function(hue, i){
return dojox.color.fromHsv(hue, s[i], v[i]);
})); // dojox.color.Palette
},
monochromatic: function(/* Object */args){
var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
hsv = base.toHsv();
// figure out the saturation and value
var s1 = (hsv.s-30>9)?hsv.s-30:hsv.s+30,
s2 = hsv.s,
v1 = rangeDiff(hsv.v, 20, 100),
v2 = (hsv.v-20>20)?hsv.v-20:hsv.v+60,
v3 = (hsv.v-50>20)?hsv.v-50:hsv.v+30;
return new dxc.Palette([
dojox.color.fromHsv(hsv.h, s1, v1),
dojox.color.fromHsv(hsv.h, s2, v3),
base,
dojox.color.fromHsv(hsv.h, s1, v3),
dojox.color.fromHsv(hsv.h, s2, v2)
]); // dojox.color.Palette
},
triadic: function(/* Object */args){
var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
hsv = base.toHsv();
var h1 = (hsv.h+57+360)%360,
h2 = (hsv.h-157+360)%360,
s1 = (hsv.s>20)?hsv.s-10:hsv.s+10,
s2 = (hsv.s>90)?hsv.s-10:hsv.s+10,
s3 = (hsv.s>95)?hsv.s-5:hsv.s+5,
v1 = (hsv.v-20>20)?hsv.v-20:hsv.v+20,
v2 = (hsv.v-30>20)?hsv.v-30:hsv.v+30,
v3 = (hsv.v-30>70)?hsv.v-30:hsv.v+30;
return new dxc.Palette([
dojox.color.fromHsv(h1, s1, hsv.v),
dojox.color.fromHsv(hsv.h, s2, v2),
base,
dojox.color.fromHsv(h2, s2, v1),
dojox.color.fromHsv(h2, s3, v3)
]); // dojox.color.Palette
},
complementary: function(/* Object */args){
var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
hsv = base.toHsv();
var h1 = ((hsv.h*2)+137<360)?(hsv.h*2)+137:Math.floor(hsv.h/2)-137,
s1 = Math.max(hsv.s-10, 0),
s2 = rangeDiff(hsv.s, 10, 100),
s3 = Math.min(100, hsv.s+20),
v1 = Math.min(100, hsv.v+30),
v2 = (hsv.v>20)?hsv.v-30:hsv.v+30;
return new dxc.Palette([
dojox.color.fromHsv(hsv.h, s1, v1),
dojox.color.fromHsv(hsv.h, s2, v2),
base,
dojox.color.fromHsv(h1, s3, v2),
dojox.color.fromHsv(h1, hsv.s, hsv.v)
]); // dojox.color.Palette
},
splitComplementary: function(/* Object */args){
var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
dangle = args.da || 30,
hsv = base.toHsv();
var baseh = ((hsv.h*2)+137<360)?(hsv.h*2)+137:Math.floor(hsv.h/2)-137,
h1 = (baseh-dangle+360)%360,
h2 = (baseh+dangle)%360,
s1 = Math.max(hsv.s-10, 0),
s2 = rangeDiff(hsv.s, 10, 100),
s3 = Math.min(100, hsv.s+20),
v1 = Math.min(100, hsv.v+30),
v2 = (hsv.v>20)?hsv.v-30:hsv.v+30;
return new dxc.Palette([
dojox.color.fromHsv(h1, s1, v1),
dojox.color.fromHsv(h1, s2, v2),
base,
dojox.color.fromHsv(h2, s3, v2),
dojox.color.fromHsv(h2, hsv.s, hsv.v)
]); // dojox.color.Palette
},
compound: function(/* Object */args){
var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
hsv = base.toHsv();
var h1 = ((hsv.h*2)+18<360)?(hsv.h*2)+18:Math.floor(hsv.h/2)-18,
h2 = ((hsv.h*2)+120<360)?(hsv.h*2)+120:Math.floor(hsv.h/2)-120,
h3 = ((hsv.h*2)+99<360)?(hsv.h*2)+99:Math.floor(hsv.h/2)-99,
s1 = (hsv.s-40>10)?hsv.s-40:hsv.s+40,
s2 = (hsv.s-10>80)?hsv.s-10:hsv.s+10,
s3 = (hsv.s-25>10)?hsv.s-25:hsv.s+25,
v1 = (hsv.v-40>10)?hsv.v-40:hsv.v+40,
v2 = (hsv.v-20>80)?hsv.v-20:hsv.v+20,
v3 = Math.max(hsv.v, 20);
return new dxc.Palette([
dojox.color.fromHsv(h1, s1, v1),
dojox.color.fromHsv(h1, s2, v2),
base,
dojox.color.fromHsv(h2, s3, v3),
dojox.color.fromHsv(h3, s2, v2)
]); // dojox.color.Palette
},
shades: function(/* Object */args){
var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
hsv = base.toHsv();
var s = (hsv.s==100 && hsv.v==0)?0:hsv.s,
v1 = (hsv.v-50>20)?hsv.v-50:hsv.v+30,
v2 = (hsv.v-25>=20)?hsv.v-25:hsv.v+55,
v3 = (hsv.v-75>=20)?hsv.v-75:hsv.v+5,
v4 = Math.max(hsv.v-10, 20);
return new dxc.Palette([
new dojox.color.fromHsv(hsv.h, s, v1),
new dojox.color.fromHsv(hsv.h, s, v2),
base,
new dojox.color.fromHsv(hsv.h, s, v3),
new dojox.color.fromHsv(hsv.h, s, v4)
]); // dojox.color.Palette
}
},
generate: function(/* String|dojox.color.Color */base, /* Function|String */type){
// summary
// Generate a new Palette using any of the named functions in
// dojox.color.Palette.generators or an optional function definition.
if(dojo.isFunction(type)){
return type({ base: base }); // dojox.color.Palette
}
else if(dxc.Palette.generators[type]){
return dxc.Palette.generators[type]({ base: base }); // dojox.color.Palette
}
throw new Error("dojox.color.Palette.generate: the specified generator ('" + type + "') does not exist.");
}
});
})();