123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 |
- /*
- Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
- Available via Academic Free License >= 2.1 OR the modified BSD license.
- see: http://dojotoolkit.org/license for details
- */
- if(!dojo._hasResource["dojox.color.Palette"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
- dojo._hasResource["dojox.color.Palette"] = true;
- 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))
- }));
- });
- 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(/* dojox.color.Palette.__transformArgs */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
- }
- });
- /*=====
- dojox.color.Palette.__transformArgs = function(use, dr, dg, db, da, dc, dm, dy, dk, dh, ds, dv, dl){
- // summary:
- // The keywords argument to be passed to the dojox.color.Palette.transform function. Note that
- // while all arguments are optional, *some* arguments must be passed. The basic concept is that
- // you pass a delta value for a specific aspect of a color model (or multiple aspects of the same
- // color model); for instance, if you wish to transform a palette based on the HSV color model,
- // you would pass one of "dh", "ds", or "dv" as a value.
- //
- // use: String?
- // Specify the color model to use for the transformation. Can be "rgb", "rgba", "hsv", "hsl", "cmy", "cmyk".
- // dr: Number?
- // The delta to be applied to the red aspect of the RGB/RGBA color model.
- // dg: Number?
- // The delta to be applied to the green aspect of the RGB/RGBA color model.
- // db: Number?
- // The delta to be applied to the blue aspect of the RGB/RGBA color model.
- // da: Number?
- // The delta to be applied to the alpha aspect of the RGBA color model.
- // dc: Number?
- // The delta to be applied to the cyan aspect of the CMY/CMYK color model.
- // dm: Number?
- // The delta to be applied to the magenta aspect of the CMY/CMYK color model.
- // dy: Number?
- // The delta to be applied to the yellow aspect of the CMY/CMYK color model.
- // dk: Number?
- // The delta to be applied to the black aspect of the CMYK color model.
- // dh: Number?
- // The delta to be applied to the hue aspect of the HSL/HSV color model.
- // ds: Number?
- // The delta to be applied to the saturation aspect of the HSL/HSV color model.
- // dl: Number?
- // The delta to be applied to the luminosity aspect of the HSL color model.
- // dv: Number?
- // The delta to be applied to the value aspect of the HSV color model.
- this.use = use;
- this.dr = dr;
- this.dg = dg;
- this.db = db;
- this.da = da;
- this.dc = dc;
- this.dm = dm;
- this.dy = dy;
- this.dk = dk;
- this.dh = dh;
- this.ds = ds;
- this.dl = dl;
- this.dv = dv;
- }
- dojox.color.Palette.__generatorArgs = function(base){
- // summary:
- // The keyword arguments object used to create a palette based on a base color.
- //
- // base: dojo.Color
- // The base color to be used to generate the palette.
- this.base = base;
- }
- dojox.color.Palette.__analogousArgs = function(base, high, low){
- // summary:
- // The keyword arguments object that is used to create a 5 color palette based on the
- // analogous rules as implemented at http://kuler.adobe.com, using the HSV color model.
- //
- // base: dojo.Color
- // The base color to be used to generate the palette.
- // high: Number?
- // The difference between the hue of the base color and the highest hue. In degrees, default is 60.
- // low: Number?
- // The difference between the hue of the base color and the lowest hue. In degrees, default is 18.
- this.base = base;
- this.high = high;
- this.low = low;
- }
- dojox.color.Palette.__splitComplementaryArgs = function(base, da){
- // summary:
- // The keyword arguments object used to create a palette based on the split complementary rules
- // as implemented at http://kuler.adobe.com.
- //
- // base: dojo.Color
- // The base color to be used to generate the palette.
- // da: Number?
- // The delta angle to be used to determine where the split for the complementary rules happen.
- // In degrees, the default is 30.
- this.base = base;
- this.da = da;
- }
- =====*/
- dojo.mixin(dxc.Palette, {
- generators: {
- analogous:function(/* dojox.color.Palette.__analogousArgs */args){
- // summary:
- // Create a 5 color palette based on the analogous rules as implemented at
- // http://kuler.adobe.com.
- 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(/* dojox.color.Palette.__generatorArgs */args){
- // summary:
- // Create a 5 color palette based on the monochromatic rules as implemented at
- // http://kuler.adobe.com.
- 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(/* dojox.color.Palette.__generatorArgs */args){
- // summary:
- // Create a 5 color palette based on the triadic rules as implemented at
- // http://kuler.adobe.com.
- 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(/* dojox.color.Palette.__generatorArgs */args){
- // summary:
- // Create a 5 color palette based on the complementary rules as implemented at
- // http://kuler.adobe.com.
- 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(/* dojox.color.Palette.__splitComplementaryArgs */args){
- // summary:
- // Create a 5 color palette based on the split complementary rules as implemented at
- // http://kuler.adobe.com.
- 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(/* dojox.color.Palette.__generatorArgs */args){
- // summary:
- // Create a 5 color palette based on the compound rules as implemented at
- // http://kuler.adobe.com.
- 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(/* dojox.color.Palette.__generatorArgs */args){
- // summary:
- // Create a 5 color palette based on the shades rules as implemented at
- // http://kuler.adobe.com.
- 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. Current
- // generators include "analogous", "monochromatic", "triadic", "complementary",
- // "splitComplementary", and "shades".
- 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.");
- }
- });
- })();
- }
|