commit 08725127a0dfd79b24b01c2f8dbbd20af0b7277e Author: peterd Date: Mon Aug 4 15:14:27 2014 +0200 New (quite) stable version Initial version (tested on IE7, IE6 possible with new CSS) diff --git a/_bgs.png b/_bgs.png new file mode 100644 index 0000000..d830a9a Binary files /dev/null and b/_bgs.png differ diff --git a/_blank.cur b/_blank.cur new file mode 100644 index 0000000..bbe2bce Binary files /dev/null and b/_blank.cur differ diff --git a/_blank.png b/_blank.png new file mode 100644 index 0000000..b34b413 Binary files /dev/null and b/_blank.png differ diff --git a/_icons.png b/_icons.png new file mode 100644 index 0000000..ad5212b Binary files /dev/null and b/_icons.png differ diff --git a/color.all.min.js b/color.all.min.js new file mode 100644 index 0000000..aef3783 --- /dev/null +++ b/color.all.min.js @@ -0,0 +1,6 @@ +// color.min.js +(function(i,g){var m={rgb:{r:[0,255],g:[0,255],b:[0,255]},hsv:{h:[0,360],s:[0,100],v:[0,100]},hsl:{h:[0,360],s:[0,100],l:[0,100]},cmy:{c:[0,100],m:[0,100],y:[0,100]},cmyk:{c:[0,100],m:[0,100],y:[0,100],k:[0,100]},XYZ:{X:[0,100],Y:[0,100],Z:[0,100]},Lab:{L:[0,100],a:[-128,127],b:[-128,127]},alpha:{alpha:[0,1]},HEX:{HEX:[0,16777215]}},a={},p={},n={X:[0.4124564,0.3575761,0.1804375],Y:[0.2126729,0.7151522,0.072175],Z:[0.0193339,0.119192,0.9503041],R:[3.2404542,-1.5371385,-0.4985314],G:[-0.969266,1.8760108,0.041556],B:[0.0556434,-0.2040259,1.0572252]},e={r:0.298954,g:0.586434,b:0.114612},t={r:0.2126,g:0.7152,b:0.0722},r=i.Colors=function(v){this.colors={RND:{}};this.options={color:"rgba(204, 82, 37, 0.8)",XYZMatrix:n,grey:e,luminance:t,valueRanges:m};o(this,v||{})},o=function(A,y){var w,B,v=A.options,x;q(A);for(var z in y){if(y[z]!==g){v[z]=y[z]}}w=v.XYZMatrix;if(!y.XYZReference){v.XYZReference={X:w.X[0]+w.X[1]+w.X[2],Y:w.Y[0]+w.Y[1]+w.Y[2],Z:w.Z[0]+w.Z[1]+w.Z[2]}}x=v.customBG;v.customBG=(typeof x==="string")?f.txt2color(x).rgb:x;p=d(A.colors,v.color,g,true)},q=function(v){if(a!==v){a=v;p=v.colors}};r.prototype.setColor=function(x,v,w){q(this);if(x){return d(this.colors,x,v,g,w)}else{if(w!==g){this.colors.alpha=w}return s(v)}};r.prototype.getColor=function(w){var v=this.colors,x=0;if(w){w=w.split(".");while(v[w[x]]){v=v[w[x++]]}if(w.length!==x){v=g}}return v};r.prototype.setCustomBackground=function(v){q(this);this.options.customBG=(typeof v==="string")?f.txt2color(v).rgb:v;return d(this.colors,g,"rgb")};r.prototype.saveAsBackground=function(){q(this);return d(this.colors,g,"rgb",true)};r.prototype.convertColor=function(A,F){var E=f,v=m,C=F.split("2"),x=C[0],G=C[1],D=/(?:RG|HS|CM|LA)/,z=D.test(x),w=D.test(G),y={LAB:"Lab"},B=function(J,L,K){var I={},H=L==="Lab"?1:0;for(var M in J){I[M]=K?Math.round(J[M]*(H||v[L][M][1])):J[M]/(H||v[L][M][1])}return I};x=v[x]?x:y[x]||x.toLowerCase();G=v[G]?G:y[G]||G.toLowerCase();if(z&&F!=="RGB2HEX"){A=B(A,x)}A=x===G?A:(E[x+"2"+G]?E[x+"2"+G](A,true):G==="HEX"?E.RGB2HEX(F==="RGB2HEX"?A:B(x==="rgb"?A:E[x+"2rgb"](A,true),"rgb",true)):E["rgb2"+G](E[x+"2rgb"](A,true),true));if(w){A=B(A,G,true)}return A};function d(v,w,x,y,z){if(typeof w==="string"){var w=f.txt2color(w);x=w.type;p[x]=w[x];z=z!==g?z:w.alpha}else{if(w){for(var A in w){v[x][A]=k(w[A]/m[x][A][1],0,1)}}}if(z!==g){v.alpha=+z}return s(x,y?v:g)}function b(v,x,z){var y=a.options.grey,w={};w.RGB={r:v.r,g:v.g,b:v.b};w.rgb={r:x.r,g:x.g,b:x.b};w.alpha=z;w.equivalentGrey=Math.round(y.r*v.r+y.g*v.g+y.b*v.b);w.rgbaMixBlack=u(x,{r:0,g:0,b:0},z,1);w.rgbaMixWhite=u(x,{r:1,g:1,b:1},z,1);w.rgbaMixBlack.luminance=c(w.rgbaMixBlack,true);w.rgbaMixWhite.luminance=c(w.rgbaMixWhite,true);if(a.options.customBG){w.rgbaMixCustom=u(x,a.options.customBG,z,1);w.rgbaMixCustom.luminance=c(w.rgbaMixCustom,true);a.options.customBG.luminance=c(a.options.customBG,true)}return w}function s(C,G){var I=G||p,H=f,B=a.options,A=m,K=I.RND,w,L="",N="",R={hsl:"hsv",cmyk:"cmy",rgb:C},y=K.rgb,x,P;if(C!=="alpha"){for(var U in A){if(!A[U][U]){if(C!==U&&U!=="XYZ"){N=R[U]||"rgb";I[U]=H[N+"2"+U](I[N])}if(!K[U]){K[U]={}}w=I[U];for(L in w){K[U][L]=Math.round(w[L]*(U==="Lab"?1:A[U][L][1]))}}}if(C!=="Lab"){delete I._rgb}y=K.rgb;I.HEX=H.RGB2HEX(y);I.equivalentGrey=B.grey.r*I.rgb.r+B.grey.g*I.rgb.g+B.grey.b*I.rgb.b;I.webSave=x=j(y,51);I.webSmart=P=j(y,17);I.saveColor=y.r===x.r&&y.g===x.g&&y.b===x.b?"web save":y.r===P.r&&y.g===P.g&&y.b===P.b?"web smart":"";I.hueRGB=f.hue2RGB(I.hsv.h);if(G){I.background=b(y,I.rgb,I.alpha)}}var v=I.rgb,E=I.alpha,T="luminance",Q=I.background,J,z,F,O,S,M,D;J=u(v,{r:0,g:0,b:0},E,1);J[T]=c(J,true);I.rgbaMixBlack=J;z=u(v,{r:1,g:1,b:1},E,1);z[T]=c(z,true);I.rgbaMixWhite=z;if(B.allMixDetails){J.WCAG2Ratio=l(J[T],0);z.WCAG2Ratio=l(z[T],1);if(B.customBG){F=u(v,B.customBG,E,1);F[T]=c(F,true);F.WCAG2Ratio=l(F[T],B.customBG[T]);I.rgbaMixCustom=F}O=u(v,Q.rgb,E,Q.alpha);O[T]=c(O,true);I.rgbaMixBG=O;S=u(v,Q.rgbaMixBlack,E,1);S[T]=c(S,true);S.WCAG2Ratio=l(S[T],Q.rgbaMixBlack[T]);S.luminanceDelta=Math.abs(S[T]-I.background.rgbaMixBlack[T]);S.hueDelta=h(Q.rgbaMixBlack,S,true);I.rgbaMixBGMixBlack=S;M=u(v,Q.rgbaMixWhite,E,1);M[T]=c(M,true);M.WCAG2Ratio=l(M[T],Q.rgbaMixWhite[T]);M.luminanceDelta=Math.abs(M[T]-I.background.rgbaMixWhite[T]);M.hueDelta=h(Q.rgbaMixWhite,M,true);I.rgbaMixBGMixWhite=M}if(B.customBG){D=u(v,Q.rgbaMixCustom,E,1);D[T]=c(D,true);D.WCAG2Ratio=l(D[T],Q.rgbaMixCustom[T]);I.rgbaMixBGMixCustom=D;D.luminanceDelta=Math.abs(D[T]-I.background.rgbaMixCustom[T]);D.hueDelta=h(Q.rgbaMixCustom,D,true)}I.RGBLuminance=c(y);I.HUELuminance=c(I.hueRGB);if(B.convertCallback){B.convertCallback(I,C)}return I}var f={txt2color:function(v){var x={},z=v.replace(/(?:#|\))/,"").split("("),w=(z[1]||"").split(/,\s*/),y=z[1]?z[0].substr(0,3):"rgb";x.type=y;x[y]={};if(z[1]){for(var A=3;A--;){x[y][y[A]]=+w[A]/m[y][y[A]][1]}}else{x.rgb=f.HEX2rgb(z[0])}x.alpha=w[3]?+w[3]:1;return x},RGB2HEX:function(v){return((v.r<16?"0":"")+v.r.toString(16)+(v.g<16?"0":"")+v.g.toString(16)+(v.b<16?"0":"")+v.b.toString(16)).toUpperCase()},HEX2rgb:function(v){return{r:parseInt(v[0]+v[v[3]?1:0],16)/255,g:parseInt(v[v[3]?2:1]+(v[3]||v[1]),16)/255,b:parseInt((v[4]||v[2])+(v[5]||v[2]),16)/255}},hue2RGB:function(v){var y=v*6,x=~~y%6,w=y===6?0:(y-x);return{r:Math.round([1,1-w,0,0,w,1][x]*255),g:Math.round([w,1,1,1-w,0,0][x]*255),b:Math.round([0,0,w,1,1,1-w][x]*255)}},rgb2hsv:function(x){var C=x.r,B=x.g,v=x.b,w=0,z,y,A;if(BC?1.055*Math.pow(v,B)-0.055:12.92*v);A=(A>C?1.055*Math.pow(A,B)-0.055:12.92*A);D=(D>C?1.055*Math.pow(D,B)-0.055:12.92*D);if(!E){p._rgb={r:v,g:A,b:D}}return{r:k(v,0,1),g:k(A,0,1),b:k(D,0,1)}},rgb2XYZ:function(w){var A=a.options.XYZMatrix,y=w.r,x=w.g,v=w.b,z=0.04045;y=(y>z?Math.pow((y+0.055)/1.055,2.4):y/12.92);x=(x>z?Math.pow((x+0.055)/1.055,2.4):x/12.92);v=(v>z?Math.pow((v+0.055)/1.055,2.4):v/12.92);return{X:y*A.X[0]+x*A.X[1]+v*A.X[2],Y:y*A.Y[0]+x*A.Y[1]+v*A.Y[2],Z:y*A.Z[0]+x*A.Z[1]+v*A.Z[2]}},XYZ2Lab:function(y){var z=a.options.XYZReference,x=y.X/z.X,w=y.Y/z.Y,v=y.Z/z.Z,A=16/116,B=1/3,D=0.008856,C=7.787037;x=x>D?Math.pow(x,B):(C*x)+A;w=w>D?Math.pow(w,B):(C*w)+A;v=v>D?Math.pow(v,B):(C*v)+A;return{L:(116*w)-16,a:500*(x-w),b:200*(w-v)}},Lab2XYZ:function(B){var z=a.options.XYZReference,w=(B.L+16)/116,x=B.a/500+w,v=w-B.b/200,y=Math.pow(x,3),F=Math.pow(w,3),A=Math.pow(v,3),C=16/116,E=0.008856,D=7.787037;return{X:(y>E?y:(x-C)/D)*z.X,Y:(F>E?F:(w-C)/D)*z.Y,Z:(A>E?A:(v-C)/D)*z.Z}},rgb2Lab:function(v,w){var x=f.rgb2XYZ(v);return f.XYZ2Lab(w?x:(p.XYZ=x))},Lab2rgb:function(v,w){var x=f.Lab2XYZ(v);return f.XYZ2rgb(w?x:(p.XYZ=x),w)}};function j(v,z){var w={},x=0,y=z/2;for(var A in v){x=v[A]%z;w[A]=v[A]+(x>y?z-x:-x)}return w}function h(w,v,x){return(Math.max(w.r-v.r,v.r-w.r)+Math.max(w.g-v.g,v.g-w.g)+Math.max(w.b-v.b,v.b-w.b))*(x?255:1)/765}function c(x,z){var A=z?1:255,v=[x.r/A,x.g/A,x.b/A],w=a.options.luminance;for(var y=v.length;y--;){v[y]=v[y]<=0.03928?v[y]/12.92:Math.pow(((v[y]+0.055)/1.055),2.4)}return((w.r*v[0])+(w.g*v[1])+(w.b*v[2]))}function u(C,w,B,v){var A={},D=(B!==g?B:1),z=(v!==g?v:1),y=D+z*(1-D);for(var x in C){A[x]=(C[x]*D+w[x]*z*(1-D))/y}A.a=y;return A}function l(w,v){var x=1;if(w>=v){x=(w+0.05)/(v+0.05)}else{x=(v+0.05)/(w+0.05)}return Math.round(x*100)/100}function k(x,w,v){return(x>v?v:x^§slds">^§sldl-1">$^§sldl-2">$^§sldl-3">$^§curm">$^§sldr-1">$^§sldr-2">$^§sldr-4">$^§curl">$^§curr">$$^§opacity">|^§opacity-slider">$$$^§memo">^§raster">$^§raster-bg">$|$|$|$|$|$|$|$|$^§memo-store">$^§memo-cursor">$$^§panel">^§hsv">^hsl-mode §ß">$^hsv-h-ß §ß">H$^hsv-h-~ §~">-^§nsarrow">$$^hsl-h-@ §@">H$^hsv-s-ß §ß">S$^hsv-s-~ §~">-$^hsl-s-@ §@">S$^hsv-v-ß §ß">B$^hsv-v-~ §~">-$^hsl-l-@ §@">L$$^§hsl §hide">^hsv-mode §ß">$^hsl-h-ß §ß">H$^hsl-h-~ §~">-$^hsv-h-@ §@">H$^hsl-s-ß §ß">S$^hsl-s-~ §~">-$^hsv-s-@ §@">S$^hsl-l-ß §ß">L$^hsl-l-~ §~">-$^hsv-v-@ §@">B$$^§rgb">^rgb-r-ß §ß">R$^rgb-r-~ §~">-$^rgb-r-@ §ß"> $^rgb-g-ß §ß">G$^rgb-g-~ §~">-$^rgb-g-@ §ß"> $^rgb-b-ß §ß">B$^rgb-b-~ §~">-$^rgb-b-@ §ß"> $$^§cmyk">^Lab-mode §ß">$^cmyk-c-ß §@">C$^cmyk-c-~ §~">-$^Lab-L-@ §@">L$^cmyk-m-ß §@">M$^cmyk-m-~ §~">-$^Lab-a-@ §@">a$^cmyk-y-ß §@">Y$^cmyk-y-~ §~">-$^Lab-b-@ §@">b$^cmyk-k-ß §@">K$^cmyk-k-~ §~">-$^Lab-x-@ §ß"> $$^§Lab §hide">^cmyk-mode §ß">$^Lab-L-ß §@">L$^Lab-L-~ §~">-$^cmyk-c-@ §@">C$^Lab-a-ß §@">a$^Lab-a-~ §~">-$^cmyk-m-@ §@">M$^Lab-b-ß §@">b$^Lab-b-~ §~">-$^cmyk-y-@ §@">Y$^Lab-x-ß §@"> $^Lab-x-~ §~">-$^cmyk-k-@ §@">K$$^§alpha">^alpha-ß §ß">A$^alpha-~ §~">-$^alpha-@ §ß">W$$^§HEX">^HEX-ß §ß">#$^HEX-~ §~">-$^HEX-@ §ß">M$$^§ctrl">^§raster">$^§cont">$^§cold">$^§col1">| $$^§col2">| $$^§bres">RESET$^§bsav">SAVE$$$^§exit">$^§resize">$^§resizer">|$$$').replace(/\^/g,'
").replace(/~/g,"disp").replace(/ß/g,"butt").replace(/@/g,"labl").replace(/\|/g,"
"),f=("är^1,äg^1,äb^1,öh^1,öh?1,öh?2,ös?1,öv?1,üh^1,üh?1,üh?2,üs?1,ül?1,.no-rgb-r är?2,.no-rgb-r är?3,.no-rgb-r är?4,.no-rgb-g äg?2,.no-rgb-g äg?3,.no-rgb-g äg?4,.no-rgb-b äb?2,.no-rgb-b äb?3,.no-rgb-b äb?4{visibility:hidden}är^2,är^3,äg^2,äg^3,äb^2,äb^3{@-image:url(_patches.png)}.§slds div{@-image:url(_vertical.png)}öh^2,ös^1,öv^1,üh^2,üs^1,ül^1{@-image:url(_horizontal.png)}ös?4,öv^3,üs?4,ül^3{@:#000}üs?3,ül^4{@:#fff}är?1{@-color:#f00}äg?1{@-color:#0f0}äb?1{@-color:#00f}är^2{@|-1664px 0}är^3{@|-896px 0}är?1,äg?1,äb?1,öh^3,ös^2,öv?2Ü-2432Öär?2Ü-2944Öär?3Ü-4480Öär?4Ü-3202Öäg^2Äöh^2{@|-640px 0}äg^3{@|-384px 0}äg?2Ü-4736Öäg?3Ü-3968Öäg?4Ü-3712Öäb^2{@|-1152px 0}äb^3{@|-1408px 0}äb?2Ü-3456Öäb?3Ü-4224Öäb?4Ü-2688Ööh^2Äär^3Ääb?4Ü0}öh?4,üh?4Ü-1664Öös^1,öv^1,üs^1,ül^1Ääg^3{@|-256px 0}ös^3,öv?4,üs^3,ül?4Ü-2176Öös?2,öv^2Ü-1920Öüh^2{@|-768px 0}üh^3,üs^2,ül?2Ü-5184Öüs?2,ül^2Ü-5824Ö.S är^2{@|-128px -128Ö.S är?1Ääg?1Ääb?1Äöh^3Äös^2Äöv?2Ü-1408Ö.S är?2Ääb^3Ü-128Ö.S är?3Ü-896Ö.S är?4Ü-256Ö.S äg^2{@|-256px -128Ö.S äg?2Ü-1024Ö.S äg?3Ü-640Ö.S äg?4Ü-512Ö.S äb^2{@|-128px 0}.S äb?2Ü-384Ö.S äb?3Ü-768Ö.S öh?4Äüh?4Ü-1536Ö.S ös^1Äöv^1Äüs^1Äül^1{@|-512px 0}.S ös^3Äöv?4Äüs^3Äül?4Ü-1280Ö.S ös?2Äöv^2Ü-1152Ö.S üh^2{@|-1024px 0}.S üh^3Äüs^2Äül?2Ü-5440Ö.S üs?2Äül^2Ü-5696Ö.XXS ös^2,.XXS öv?2Ü-5120Ö.XXS ös^3,.XXS öv?4,.XXS üs^3,.XXS ül^3,.XXS ül?4Ü-5056Ö.XXS ös?2,.XXS öv^2Ü-4992Ö.XXS üs^2,.XXS ül?2Ü-5568Ö.XXS üs?2,.XXS ül^2Ü-5632Ö").replace(/Ü/g,"{@|0 ").replace(/Ö/g,"px}").replace(/Ä/g,",.S ").replace(/\|/g,"-position:").replace(/@/g,"background").replace(/ü/g,".hsl-").replace(/ö/g,".hsv-").replace(/ä/g,".rgb-").replace(/~/g," .no-rgb-}").replace(/\?/g," .§sldr-").replace(/\^/g," .§sldl-"),i=("∑{@#bbb;font-family:Courier, mono;font-size:12¥line-ä15¥font-weight:bold;cursor:default;~412¥ä323¥?top-left-radius:7¥?top-Ü-radius:7¥?bottom-Ü-radius:7¥?bottom-left-radius:7¥ö@#444}.S{~266¥ä177px}.XS{~158¥ä173px}.XXS{ä105¥~154px}∑,∑ div{border:none;padding:0¥float:none;margin:0¥outline:none;box-sizing:?box}∑ div{|absolute}^s .§curm,«§disp,«§nsarrow,∑ .§exit,∑ ø-cursor,∑ .§resize{öimage:url(_icons.png)}∑ .do-drag div{cursor:url(_blank.png), auto}∑ .§opacity,ø .§raster-bg,∑ .§raster{öimage:url(_bgs.png)}∑ ^s{~287¥ä256¥top:10¥left:10¥overflow:hidden;cursor:crosshair}.S ^s{~143¥ä128¥left:9¥top:9px}.XS ^s{left:7¥top:7px}.XXS ^s{left:5¥top:5px}^s div{~256¥ä256¥left:0px}.S ^l-1,.S ^l-2,.S ^l-3,.S ^l-4{~128¥ä128px}.XXS ^s,.XXS ^s ^l-1,.XXS ^s ^l-2,.XXS ^s ^l-3,.XXS ^s ^l-4{ä64px}^s ^r-1,^s ^r-2,^s ^r-3,^s ^r-4{~31¥left:256¥cursor:default}.S ^r-1,.S ^r-2,.S ^r-3,.S ^r-4{~15¥ä128¥left:128px}^s .§curm{margin:-5¥~11¥ä11¥ö|-36px -30px}.light .§curm{ö|-7px -30px}^s .§curl,^s .§curr{~0¥ä0¥margin:-3px -4¥border:4px solid;cursor:default;left:auto;öimage:none}^s .§curl,∑ ^s .§curl-dark,.hue-dark div.§curl{Ü:27¥?@† † † #fff}.light .§curl,∑ ^s .§curl-light,.hue-light .§curl{?@† † † #000}.S ^s .§curl,.S ^s .§curr{?~3px}.S ^s .§curl-light,.S ^s .§curl{Ü:13px}^s .§curr,∑ ^s .§curr-dark{Ü:4¥?@† #fff † †}.light .§curr,∑ ^s .§curr-light{?@† #000 † †}∑ .§opacity{bottom:44¥left:10¥ä10¥~287¥ö|0 -87px}.S .§opacity{bottom:27¥left:9¥~143¥ö|0 -100px}.XS .§opacity{left:7¥bottom:25px}.XXS .§opacity{left:5¥bottom:23px}.§opacity div{~100%;ä16¥margin-top:-3¥overflow:hidden}.§opacity .§opacity-slider{margin:0 -5¥~0¥?~4¥?style:solid;?@#eee †}∑ ø{bottom:10¥left:10¥~288¥ä31¥ö@#fff}.S ø{ä15¥~144¥left:9¥bottom:9px}.XS ø{left:7¥bottom:7px}.XXS ø{left:5¥bottom:5px}ø div{|relative;float:left;~31¥ä31¥margin-Ü:1px}.S ø div{~15¥ä15px}∑ .§raster,ø .§raster-bg,.S ø .§raster,.S ø .§raster-bg{|absolute;top:0¥Ü:0¥bottom:0¥left:0¥~100%}.S ø .§raster-bg{ö|0 -31px}∑ .§raster{opacity:0.2;ö|0 -49px}.alpha-bg-b ø{ö@#333}.alpha-bg-b .§raster{opacity:1}ø ø-cursor{|absolute;Ü:0¥ö|-26px -87px}∑ .light ø-cursor{ö|3px -87px}.S ø-cursor{ö|-34px -95px}.S .light ø-cursor{ö|-5px -95px}∑ .§panel{|absolute;top:10¥Ü:10¥bottom:10¥~96¥?~1¥?style:solid;?@#222 #555 #555 #222;overflow:hidden;ö@#333}.S .§panel{top:9¥Ü:9¥bottom:9px}.XS .§panel{display:none}.§panel div{|relative}«§hsv,«§hsl,«§rgb,«§cmyk,«§Lab,«§alpha,«§HEX{~86¥margin:-1px 0px 1px 4¥padding:1px 0px 3¥?top-~1¥?top-style:solid;?top-@#444;?bottom-~1¥?bottom-style:solid;?bottom-@#222;float:Ö«§hsv,«§hsl{padding-top:2px}.S .§hsv,.S .§hsl{padding-top:1px}«§HEX{?bottom-style:none;?top-~0¥margin-top:-4¥padding-top:0px}«§alpha{?bottom-style:none}.S .rgb-r .§hsv,.S .rgb-g .§hsv,.S .rgb-b .§hsv,.S .rgb-r .§hsl,.S .rgb-g .§hsl,.S .rgb-b .§hsl,.S .hsv-h .§rgb,.S .hsv-s .§rgb,.S .hsv-v .§rgb,.S .hsl-h .§rgb,.S .hsl-s .§rgb,.S .hsl-l .§rgb,.S .§cmyk,.S .§Lab{display:none}«§butt,«§labl{float:left;~16¥ä16¥margin-top:2¥text-align:center;border:1px solid}«§butt{?@#555 #222 #222 #555}«§butt:active{ö@#444}«§labl{?@†}«Lab-mode,«cmyk-mode,«hsv-mode,«hsl-mode{|absolute;Ü:0¥ä52px}«cmyk-mode{ä70px}.hsl-h .hsl-h-labl,.hsl-s .hsl-s-labl,.hsl-l .hsl-l-labl,.hsv-h .hsv-h-labl,.hsv-s .hsv-s-labl,.hsv-v .hsv-v-labl{@#f90}«cmyk-mode,«hsv-mode,.rgb-r .rgb-r-butt,.rgb-g .rgb-g-butt,.rgb-b .rgb-b-butt,.hsv-h .hsv-h-butt,.hsv-s .hsv-s-butt,.hsv-v .hsv-v-butt,.hsl-h .hsl-h-butt,.hsl-s .hsl-s-butt,.hsl-l .hsl-l-butt,«rgb-r-labl,«rgb-g-labl,«rgb-b-labl,«alpha-butt,«HEX-butt,«Lab-x-labl{?@#222 #555 #555 #222;ö@#444}.no-rgb-r .rgb-r-labl,.no-rgb-g .rgb-g-labl,.no-rgb-b .rgb-b-labl,.no-alpha .alpha-butt,.no-HEX .HEX-butt,.cmy-only .Lab-x-labl{?@#555 #222 #222 #555;ö@#333}.Lab-x-disp,.cmy-only .cmyk-k-disp,.cmy-only .cmyk-k-butt{visibility:hidden}«HEX-disp{öimage:none}«§disp{float:left;~50¥ä16¥margin:2px 2px 0¥cursor:text;text-align:left;text-indent:3¥?~1¥?style:solid;?@#222 #555 #555 #222}∑ .§nsarrow{|absolute;top:0¥left:-13¥~8¥ä16¥visibility:hidden;ö|-87px -23px}∑ .start-change .§nsarrow{visibility:visible}∑ .do-change .§nsarrow{visibility:visible;ö|-87px -36px}.do-change .§disp{cursor:default}«§hide{display:none}«§cont,«§cold{|absolute;top:-5¥ä5¥border:1px solid #333}«§cold{z-index:1;ö@#c00}«§cont{margin-Ü:-1¥z-index:2}«contrast .§cont{z-index:1;ö@#ccc}«orange .§cold{ö@#f90}«green .§cold{ö@#4d0}«§ctrl{|absolute;bottom:0¥ö@#fff}.alpha-bg-b .§ctrl,«§bres,«§bsav{ö@#333}«§col1,«§col2,«§bres,«§bsav{?~1¥?style:solid;?@#555 #222 #222 #555;float:left;~47¥line-ä28¥text-align:center}.S .§ctrl div{line-ä25px}.S «§bres,.S «§bsav{line-ä26px}∑ .§exit,∑ .§resize{Ü:3¥top:3¥~15¥ä15¥ö|0 -52px}∑ .§resize{top:auto;bottom:3¥cursor:nwse-resize;ö|-15px -52px}.S .§exit{ö|1px -52px}.XS .§resize,.XS .§exit{~10¥ä10¥Ü:0¥öimage:none}.XS .§exit{top:0px}.XS .§resize{bottom:0px}∑ .§resizer,∑ .§resizer div{|absolute;border:1px solid #888;top:-1¥Ü:-1¥bottom:-1¥left:-1¥z-index:2;display:none;cursor:nwse-resize}∑ .§resizer div{border:1px dashed #333;opacity:0.3;display:block;ö@#bbb}").replace(/Ü/g,"right").replace(/Ö/g,"left}").replace(/∑/g,".§app").replace(/«/g,".§panel .").replace(/¥/g,"px;").replace(/\|/g,"position:").replace(/@/g,"color:").replace(/ö/g,"background-").replace(/ä/g,"height:").replace(/ø/g,".§memo").replace(/†/g,"transparent").replace(/\~/g,"width:").replace(/\?/g,"border-").replace(/\^/g,".§sld"),e="iVBORw0KGgoAAAANSUhEUgAABIAAAAABCAYAAACmC9U0AAABT0lEQVR4Xu2S3Y6CMBCFhyqIsjGBO1/B9/F5DC/pK3DHhVkUgc7Zqus2DVlGU/cnQZKTjznttNPJBABA149HyRf1iN//4mIBCg0jV4In+j9xJiuihly1V/Z9X88v//kNeDXVvyO/lK+IPR76B019+1Riab3H1zkmeqerKnL+Bzwxx6PAgZxaSQU8vB62T28pxcQeRQ2sHw6GxCOWHvP78zwHAARBABOfdYtd30rwxXOEPDF+dj2+91r6vV/id3k+/brrXmaGUkqKhX3i+ffSt16HQ/dorTGZTHrs7ev7Tl7XdZhOpzc651nfsm1bRFF0YRiGaJoGs9nsQuN/xafTCXEco65rzOdzHI9HJEmCqqqwXC6x3++RZRnKssRqtUJRFFiv19jtdthutyAi5Hl+Jo9VZg7+7f3yXuvZf5c3KaXYzByb+WIzO5ymKW82G/0BNcFhO/tOuuMAAAAASUVORK5CYII=",g="iVBORw0KGgoAAAANSUhEUgAAAAEAABfACAYAAABn2KvYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABHtJREFUeNrtnN9SqzAQxpOF1to6zuiVvoI+j6/gva/lA/kKeqUzjtX+QTi7SzSYBg49xdIzfL34+e1usoQQklCnmLwoCjImNwDQA2xRGMqNAYB+gPEH9IdCgIUA6Aem0P1fLoMQAPYNHYDoCKAv8OMHFgKgX2AjDPQDXn4t1l+gt/1fId//yWgE/hUJ+mAn8EyY5wCwXxhrbaHzn8E9iPlv79DdHxXTqciZ4KROnXRVZMF/6U2OPhcEavtAbZH1SM7wRDD7VoHZItCiyEQf4t6+MW9UOxaZybmdCGKqNrB9Eb5SfMg3wTyiagMtigTmWofiSDCOYNTSNz6sLDIoaCU9GWDd0tdhoMMsRm+r8U/EfB0GfjmLXiqzimDd0tdhoLMsI7la45+I+ToM/HIW0kfGVQTrlr7tA91kaUr//fxrKo8jUFB7VAn6AKpHJf+EKwAAAIYD/f7F7/8MVgMo7P+gBqDKr57Lf72V8x8AAMDgYIuvH4EAAAAMDQX6AACAQcI9GGMjDADA4MA/P2KlP8IEAAAYFCz6AACAgaLA8y8AAIN+CMYXoQAADA7u/UPYCAMAMDjI7z9S+SdwDFQX2C9Gh9GMEOWriz8/Pw1lWQZsi/L3R4czzP678Ve+P8f9nCv/C7hwLq99ah8NfKrU15zPB5pVcwtiJt9qGy0IfEE+jQa+Fn0VtI/fkxUPqBlEfRENeF+tqUpbGpi1iu8epwJzvV5XA4GpWC6XGz7F+/u766EgwJ+ckiTJKU3TnI6OjnI6OzvLZf6zMggt3dzckPhIoiTlSGpQ+eEsVegdz0fbCCi4fRs+Po+4yWdeDXiT+6pBSTeHple1pkz3FZ+avpyavoiPxgLN0B7yprY08PlyQTTm0+PWmkH7ynedNKraar4F/lRj1WpTtYh+ozL/cY2sAvZl0gcbZm0gSLBLvkxGoaogiy/HDXemQk2t5pUm8OAhH8/HH6e0mkJ9q9XKKQXfb07xfZnJbZrRxcVFVt6/t7e3Kc1ms5RGo1Eq5VIZuyl9fHw4k/M5xYeoKj64A7eqCt1ZeqWFVSl8NV9OTV3fmvP5qE9VmzSoEcsXpArK1UHen/hZbgL53BZSdyEXalGau/hU8TEW0u3VcoFPy3EDFrTgT+njydeZ0+l0UV7fu7u7iVzziQQmUm4iqRw4n/NxMxw4s/Mp1NSALxf4NEtQ10cjMDwSl+b+/j6hp6enVGb+jUvrn05iKobm6PboOt8vPISY5Pr6OqGXlxe3fOokoGtAbMUJZmqvYmaLQDP+sdrecOjtO/SXeH69P8Imutm5urqy9PDwYOny8tLS4+OjpfPzc0vPz8+WTk9PLb2+vlpZbCzN53NLx8fHVtYZS5PJxMoEZWWqsjKULY3HYytTi1Pex5OMldXKRVXxuLcy/20onmms3BBOxcr5qCrZtsrd45SPel8sGlOxGoGy0neynQ6VL9fsa1YtWlCrtj9G83G7PjdVush5n5q1iJWLZW6u21a1bUvbVnVzlru0pe3RdmlV1/23fZtbZv4Dx+7FBypx77kAAAAASUVORK5CYII=",j=("iVBORw0KGgo^NSUhEUgAAB4^EACAI#DdoPxz#L0UlEQVR4Xu3cQWrDQBREwR7FF8/BPR3wXktnQL+KvxfypuEhvLJXcp06d/bXd71OPt+trIw95zr33Z1bk1/fudEv79wa++7OfayZ59wrO2PBzklcGQmAZggAAOBYgAYBmpWRAGg^BGgRofAENgAAN#I0CBA6w8AG^ECABgEa/QH§AI0CNDoDwAY^QIAGAVp/AM§AjQI0OgPAAY^QoEGARn8Aw§CNAjQ+gMABg#BCgQYCmGQmABgAAEKBBgEZ/AM§AjQI0PoDAAY^QoEGARn8AM^IAADQI0+gMABg#BCgQYDWHwAw^gAANAjT6A4AB^BGgQoNEfAD^C#0CtP4AgAE^EaBCgaUYCoAE#RoEKDRHwAw^gAANArT+AIAB^BGgQoNEfAAw^gQIMAjf4AgAE^EaBCg9QcAD^CBAgwCN/gBg§EaBGj0BwAM^IECDAK0/AG§ARoEaJqRAGg^BGgRo9AcAD^CBAgwCtPwBg§EaBGj0BwAD^CNAgQKM/AG§ARoEaP0BAAM^I0CBAoz8AG^ECABgEa/QEAAw^jQIEDrDwAY^QIAGAZpmJACaBw^RoEKD1BwAM^IECDAK0/AG§ARoEaPQHAAw^gQIMArT8AY§BGgRo/QEAAw^jQIECjPwBg§EaBGj9AQAD^CNAgQOsPABg#BAgAYBGv0BAANwCwAAGB6gYeckmpEAa^AEaBGj0BwAM^IECDAK0/AG§ARoEaPQHAAM^I0CBAoz8AY§BGgRo/QEAAw^jQIECjPwAY^QIAGARr9AQAD^CNAgQOsPABg#BAgAYBmmYkABoAAECABgEa/QEAAw^jQIEDrDwAY^QIAGARr9Ac§AjQI0OgPABg#BAgAYBWn8Aw§CNAjQ6A8ABg#BCgQYBGfwD§AI0CND6AwAG^EKBBgKYZCYAG#QoEGARn8Aw§CNAjQ+gMABg#BCgQYBGfwAw^gAANAjT6AwAG^EKBBgNYfAD^C#0CNPoDgAE^EaBCg0R8AM^IAADQK0/gCAAQ^RoEKBpRgKgAQAABGgQoNEfAD^C#0CtP4AgAE^EaBCg0R8AD^CBAgwCN/gCAAQ^RoEKD1BwAM^IECDAI3+AG§ARoEaPQHAAw^gQIMArT8AY§BGgRomsMAM^IAADQK0/gCAAQ^RoEKDRHwAw^gAANO7fQHwAw^gAANArT+AIAB^BGgQoNEfAGg^BGgRo9AcAD^CBAgwCtPwBg§EaBGj0BwAD^RIB+Ntg5iea5AD^DAIwI0CND6AwAG^EKBBgEZ/AKAB#EaBCg0R8AM^IAADQK0/gCAAQ^RoEKDRHwAM^IECDAI3+AIAB^BGgQoPUHAAw^gQIMAjf4AY§BGgRo9AcAD^CBAgwCtPwBg§EaBGiakQBo^ARoEaPQHAAw^gQIMArT8AY§BGgRo9AcAAw^jQIECjPwBg§EaBGj9AQAD^CNAgQKM/ABg#BAgAYBGv0BAAM^I0CBA6w8AG^ECABgGaZiQAGgAAQIAGARr9AQAD^CNAgQOsPABg#BAgAYBGv0Bw§CNAjQ6A8AG^ECABgFafwD§AI0CNDoDwAG^EKBBgEZ/AM§AjQI0PoDAAY^QoEGApjkMAAM^I0CBA6w8AG^ECABgEa/QEAAw^jQsIP+AIAB^BGgQoPUHAAw^gQIMAjf4AgAE#Bea/fK+3P5/3PJOvh8t1cO4nflmQAQoAEAAF9Aw/7JHfQHAAw^gQIMArT8AY§BGvwHNPoDAA0AACBAgwCN/gCAAQ^RoEKD1BwAM^IECDAI3+AG§ARoEaPQHAAw^gQIMArT8AY§BGgRo9AcAAw^jQIECjPwBg§EaBGj9AQAD^CNAgQNOMBEAD#I0CBAoz8AY§BGgRo/QEAAw^jQIECjPwAY^QIAGARr9AQAD^CNAgQOsPABg#BAgAYBGv0Bw§CNAjQ6A8AG^ECABgFafwD§AI0CNA0IwHQ^AjQI0OgPABg#BAgAYBWn8Aw§CNAjQ6A8ABg#BCgQYBGfwD§AI0CND6AwAG^EKBBgEZ/AD^C#0CNPoDAAY^QoEGA1h8AM^IAADQI0DQAG^EKBBgEZ/AM§AjQI0PoDAAY^QoEGA1h8AM^IAADQI0+gMABg#BCgQYDWHwAw^gAANArT+AIAB^BGgQoNEfAD^C#0CtP4AgAE^EaBCg9QcAD^CBAgwCN/gCAAQ^RoEKD1BwAM^IECDAK0/AG§ARoEaPQHAAw^gQIMArT8AY§BGgRo/QEAAw^jQIECjPwBgACDhFgC#07t9AfAD^C#0CtP4AgAE^EaBCg0R8Aa^AEaBGj0BwAM^IECDAK0/AG§ARoEaPQHAAM^I0CBAoz8AY§BGgRo/QEAAw^jQIECjPwAY^QIAGARr9AQAD^CNAgQOsPABg#BAgAYBmmYkABoAAECABgEa/QEAAw^jQIEDrDwAY^QIAGARr9Ac§AjQI0OgPABg#BAgAYBWn8Aw§CNAjQ6A8ABg#BCgQYBGfwD§AI0CND6AwAG^EKBBgKYZCYAG#QoEGARn8Aw§CNAjQ+gMABg#BCgQYBGfwAw^gAANAjT6AwAG^EKBBgNYfAD^C#0CNPoDgAE^EaBCg0R8AM^IAADQK0/gCAAQ^RoEKBpRgKgAQAABGgQoNEfAD^C#0CtP4AgAE^EaBCg0R8AD^CBAgwCN/gCAAQ^RoEKD1BwAM^IECDAI3+AG§ARoEaPQHAAw^gQIMArT8AY§BGgRommEAM^CBAgwCN/gCAAQ^RoEKD1BwAM^IECDAI3+AIAB^ARoEaPQHAAw^gQIMArT8AY§BGgRo9AcAGgAAQICGCNBfRfNcABg#BgeICGnVvoDwAY^QIAGAVp/AM§AjQI0OgPADQAAIAADQI0+gMABg#BCgQYDWHwAw^gAANAjT6A4AB^BGgQoNEfAD^C#0CtP4AgAE^EaBCg0R8AD^CBAgwCN/gCAAQ^RoEKD1BwAM^IECDAE0zEgAN#gQIMAjf4AgAE^EaBCg9QcAD^CBAgwCN/gBg§EaBGj0BwAM^IECDAK0/AG§ARoEaPQHAAM^I0CBAoz8AY§BGgRo/QEAAw^jQIEDTjARAAwAACNAgQKM/AG§ARoEaP0BAAM^I0CBAoz8AG^ECABgEa/QEAAw^jQIEDrDwAY^QIAGARr9Ac§AjQI0OgPABg#BAgAYBWn8Aw§CNAjQNIcBY§BGgRo/QEAAw^jQIECjPwBg§EadtAfAD^C#0CtP4AgAE^EaBCgAQABGgAA+AO2TAbHupOgH^ABJRU5ErkJggg==").replace(/§/g,"AAAAAA").replace(/\^/g,"AAAA").replace(/#/g,"AAA"),a="iVBORw0KGgoAAAANSUhEUgAAAGEAAABDCAMAAAC7vJusAAAAkFBMVEUAAAAvLy9ERERubm7///8AAAD///9EREREREREREREREQAAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8cHBwkJCQnJycoKCgpKSkqKiouLi4vLy8/Pz9AQEBCQkJDQ0NdXV1ubm58fHykpKRERERVVVUzMzPx7Ab+AAAAHXRSTlMAAAAAAAQEBQ4QGR4eIyMtLUVFVVVqapKSnJy7u9JKTggAAAFUSURBVHja7dXbUoMwEAbgSICqLYeW88F6KIogqe//dpoYZ0W4AXbv8g9TwkxmvtndZMrEwlw/F8YIRjCCEYxgBCOsFmzqGMEI28J5zzmt0Pc9rdDL0NYgMxIYC5KiKpKAzZphWtZlGm4SjlnkOV6UHeeEUx77rh/npw1dCrI9k9lnwUwF+UG9D3m4ftJJxH4SJdPtaawXcbr+tBaeFrxiur309cIv19+4ytGCU0031a5euPVigLYGqjlAqM4ShOQ+QAYQUO80AMMAAkUGGfMfR9Ul+kmvPq2QGxXKOQBAKdjUgk0t2NiCGEVP+rHT3/iCUMBT90YrPMsKsIWP3x/VolaonJEETchHCS8AYAmaUICQQwaAQnjoXgHAES7jLkEFaHO4bdq/k25HAIpgWY34FwAE5xjCffM+D2DV8B0gRsAZT7hr5gE8wdrJcU+CJqhcqQD7Cx5L7Ph4WnrKAAAAAElFTkSuQmCC",c="iVBORw0KGgoAAAANSUhEUgAAASAAAABvCAYAAABM+h2NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABORJREFUeNrs3VtTW1UYBuCEcxAI4YydWqTWdqr1V7T/2QsvvPDCCy9qjxZbamsrhZIQUHsCEtfafpmJe8qFjpUxfZ4Zuvt2feydJvAOARZUut1u5bRerl692nV913f99/f6QxWAU6KAAAUEKCAABQQoIAAFBCggAAUEKCAABQQoIAAFBCggAAUEKCAABQQoIEABASggQAEBKCBAAQEoIEABASggQAEBKCBAAQEoIGBQC+jatWvd07zxrv9+Xx8fAQEoIEABASggQAEBKCBAAQEoIEABAQoIQAEBCghAAQEKCEABAQOk2u36kS6AAgLetwJKL29toFRM1be+QrVq3rx58//KvM8BAadGAQEKCFBAAAoIGHwnfhneZ+/Nmzf/LufzrI+AAE/BAAUEoIAABQTwztgLZt68eXvBAE/BABQQoIAAFBAweOwFM2/evL1ggKdgAAoIUEAACggYPPaCmTdv3l4wwFMwAAUEKCAABQQMHnvBzJs3by8Y4CkYgAICFBCAAgIGz4lfBQNQQMDgFlCtVisaaHV1tThubW1VInciD0U+ysdnz54N5+PKysphOnRTHsvHlN9EHo/1l5FrkV9Enoz8W87b29tTOS8vLx9EnoncjlyPvBe5EbkZeT4fU96NvBDr2znv7Ows57y0tLQVeSXy08gf5mNfPhPrjyOfrVarlcXFxZ9yfv78+bl8TPlh5LU8n/KDyOuxfj/y+VjfyHl3d/dCKv28fi/yp/m4sLDwQ+SLke9GvhT5Tinfjnw5f4/F/Pz8rZybzeZn+ZjyzVK+EfnzUr4S+Xopf9/L+fxzc3M5d1qt1hf531Mu5k/IxzGf85VYL+fefHH+RqNRrO/t7RW3L+UbkS9Hvhk5/386Kd/qW8/5duRLMV/OdyJfzNebnZ0t7t92u53v/07K9yJfiLwROT9+ef7HyOux/iDyWuSHkT+K+eLtZX9//2xer9frjyOfyY9/Wn8S86v59qT1p7Ge315zLt4RU16K19+O9YXIu5HnYn435hux3opcj9yOPB3z+5E/iPXf43y1yMX778HBQS3f3pTz+28l5bHIr2N+LN3+zszMzGHkoh/S+mHMF98XlNaP8zHd/0W/pMe943NAwKlSQIACAhQQgAICFBCAAgIUEIACAhQQgAIC/n9GqtXqYbfbHa38+RtSu32llPdqdNL6aOSj+LfxyMVekLTem39Ryr/mPDQ0NBznzXtROikPRW6W8k7k3m9rzXthOsPDw73bUuylGRkZ6cR63nvTSfko8oPIr+Pnz96P/DLW816ezujoaN6DdtyX9+P8eS9QZ2xs7Hxf7qa8Xlr/JO6Ljcjrcf6cj1P+OO+N6V1/fHz8XLz+/Tjfubh+sZcorZ+N9Ycxfybyo8ircf6fc56YmFiJ1/8l8mLk7cjzkfP92U15Ns63G+u9nPcKdWq12lQ8Xu3Ixd6f9Pd8P3UmJycnUszzL2N9LM7/anNzs9V7Q2q32395w/q7ubdH6L/KrVbrpPxlKX9Vyl+X8jel/G0pf5f/aDabvXy9tH6ztH63lDdKebOUH5Xyk1LeKuWd/ry2tlap9P125Onp6Zf9eWpq6lW3b8f6zMzM6/71er3+ppSP+u/XNN/pz41Go+sjIMBTMEABASggQAEBKCBAAQEoIEABASggQAEB/CN/CDAAw78uW9AVDw4AAAAASUVORK5CYII=",k="iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQI12P4//8/MwAI/wMBbrqo4gAAAABJRU5ErkJggg==";h.ColorPicker={_html:b,_cssFunc:f,_cssMain:i,_horizontalPng:e,_verticalPng:g,_patchesPng:j,_iconsPng:a,_bgsPng:c,_blankPng:k}})(window); +// colorPicker.min.js +(function(aa,B){var ai=aa.ColorPicker,L=!ai,z=false,r={},C,G,H,t=1,W={},K={},f,j=true,v={selection:aa.getSelection(),range:document.createRange?document.createRange():document.body.createTextRange()},R={},h={},m,A,N={},a={},ah={},X={},Q="AnimationFrame",D="request"+Q,M="cancel"+Q,o=["ms","moz","webkit","o"],aj=function(n){this.options={color:"rgba(204, 82, 37, 0.8)",mode:"rgb-b",fps:60,delayOffset:8,CSSPrefix:"cp-",scale:1,allMixDetails:true,alphaBG:"w"};s(this,n||{})};aa.ColorPicker=aj;aj.addEvent=w;aj.removeEvent=d;aj.getOrigin=F;aj.limitValue=E;aj.changeClass=u;aj.prototype.setColor=function(al,n,ak,am){q(this);H=true;i(N.setColor.apply(N,arguments));if(am){this.startRender(true)}};aj.prototype.saveAsBackground=function(){q(this);return c()};Colors.prototype.setCustomBackground=function(n){q(this);return N.setCustomBackground(n)};aj.prototype.startRender=function(n){q(this);if(n){C=false;O();this.stopRender()}else{C=1;f=aa[D](O)}};aj.prototype.stopRender=function(){q(this);aa[M](f);if(H){C=1;ab(B,"external")}};aj.prototype.setMode=function(n){q(this);V(n);T();O()};aj.prototype.destroyAll=function(){var n=this.nodes.colorPicker,ak=function(al){for(var am in al){if(al[am]&&al[am].toString()==="[object Object]"||al[am] instanceof Array){ak(al[am])}al[am]=null;delete al[am]}};this.stopRender();Z(this,true);ak(this);n.parentNode.removeChild(n);n=null};function s(aq,at){var ak,am,ao="",ar="";for(var an in at){aq.options[an]=at[an]}N=new Colors(aq.options);delete aq.options;ah=N.options;ar=ah.CSSPrefix;aq.color=N;r=ah.valueRanges;aq.nodes=X=af(J(aq),aq);V(ah.mode);q(aq);c();ao=" "+ah.mode.type+"-"+ah.mode.z;X.slds.className+=ao;X.panel.className+=ao;if(ah.noHexButton){u(X.HEX_butt,ar+"butt",ar+"labl")}if(ah.size!==B){Y(B,ah.size)}var ap={alphaBG:X.alpha_labl,cmyOnly:X.HEX_labl};for(var al in ap){if(ah[al]!==B){e({target:ap[al],data:ah[al]})}}am=ah.memoryColors;for(var al=X.memos.length;al--;){X.memos[al].style.cssText="background-color: "+(am&&am[al]!==B?ae(am[al])+";"+P(am[al]["a"]||1):"rgb(0,0,0);")}Z(aq);C=true;ab(B,"init");if(A){q(A);O()}}function q(n){j=true;if(m!==n){m=n;a=n.color.colors;ah=n.color.options;X=n.nodes;N=n.color;h={};i(a)}}function I(){var ak=["L","S","XS","XXS"];ah.sizes={};X.testNode.style.cssText="position:absolute;left:-1000px;top:-1000px;";document.body.appendChild(X.testNode);for(var al=ak.length;al--;){X.testNode.className=ah.CSSPrefix+"app "+ak[al];ah.sizes[ak[al]]=[X.testNode.offsetWidth,X.testNode.offsetHeight]}if(X.testNode.removeNode){X.testNode.removeNode(true)}else{document.body.removeChild(X.testNode)}}function J(am){var ao=document.createElement("div"),al,an=ah.CSSPrefix,ak="data:image/png;base64,";if(L){return am.color.options.devPicker}if(A=m){T()}ao.innerHTML=m?m.nodes.colorPicker.outerHTML:ai._html.replace(/§/g,an);if(!document.getElementById("colorPickerCSS")){al=document.createElement("style");al.setAttribute("type","text/css");al.setAttribute("id","colorPickerCSS");al.innerHTML=ai._cssFunc.replace(/§/g,an).replace("_patches.png",!z?ak+ai._patchesPng:"_patches.png").replace("_vertical.png",!z?ak+ai._verticalPng:"_vertical.png").replace("_horizontal.png",!z?ak+ai._horizontalPng:"_horizontal.png");document.getElementsByTagName("head")[0].appendChild(al);if(!ah.customCSS){al=document.createElement("style");al.setAttribute("type","text/css");al.innerHTML=ai._cssMain.replace(/§/g,an).replace("_bgs.png",!z?ak+ai._bgsPng:"_bgs.png").replace("_icons.png",!z?ak+ai._iconsPng:"_icons.png").replace("_blank.png",!z?ak+ai._blankPng:"_blank.png");document.getElementsByTagName("head")[0].appendChild(al)}for(var ap in ai){ai[ap]=null}}return(ah.appenTo||document.body).appendChild(ao.children[0])}function af(al,ar){var at=al.getElementsByTagName("*"),ak={colorPicker:al},ao,aq,au=0,ap=new RegExp(ah.CSSPrefix);ak.styles={};ak.textNodes={};ak.memos=[];ak.testNode=document.createElement("div");for(var am=0,an=at.length;am=al){if(!t){t=(ap>0?-al:al)+(+G.firstChild.data)*(ao?100:1);W.pageY+=t;ap+=t;t=1;u(X.panel,"start-change","do-change");aa.getSelection?aa.getSelection().removeAllRanges():document.selection.empty();document.activeElement.blur();f=aa[D](O)}if(ak==="cmyk"&&ah.cmyOnly){ak="cmy"}if(ao){j=true;a.alpha=E(ap/100,0,1)}else{n=r[ak][H.z];a[ak][H.z]=ak==="Lab"?E(ap,n[0],n[1]):E(ap/n[1],0,1)}y(ao?"alpha":ak);am.returnValue=false}}function p(az){var ax=az||aa.event,ap=ax.which||ax.keyCode,aB=String.fromCharCode(ap),an=document.activeElement,am=an.className.replace(ah.CSSPrefix,"").split("-"),al=am[0],ar=am[1],ao=al==="alpha",at=al==="HEX",ak={k40:-1,k38:1,k34:-10,k33:10}["k"+ap]/(ao?100:1),n={HEX:/[0-9a-fA-F]/,Lab:/[\-0-9]/,alpha:/[\.0-9]/}[al]||/[0-9]/,aq=r[al][al]||r[al][ar],av=an.firstChild,ay=b(an),au=av.data,aw,aA=au==="0"&&!at?[]:au.split("");if(/^(?:27|13)$/.test(ap)){an.blur()}else{if(ax.type==="keydown"){if(ak){aw=E(Math.round((+au+ak)*1000000)/1000000,aq[0],aq[1])}else{if(/^(?:8|46)$/.test(ap)){if(!ay.range){ay.range++;ay.start-=ap===8?1:0}aA.splice(ay.start,ay.range);aw=aA.join("")||"0"}}if(aw!==B){S(ax)}}else{if(ax.type==="keypress"){if(!/^(?:37|39|8|46|9)$/.test(ap)){S(ax)}if(n.test(aB)){aA.splice(ay.start,ay.range,aB);aw=aA.join("")}ay.start++}}}if(ap===13&&at){if(av.data.length%3===0||av.data==="0"){return m.setColor(av.data==="0"?"000":av.data,"rgb",a.alpha,true)}else{S(ax);return an.focus()}}if(at&&aw!==B){aw=/^0+/.test(aw)?aw:parseInt(""+aw,16)||0}if(aw!==B&&aw!==""&&+aw>=aq[0]&&+aw<=aq[1]){if(at){aw=aw.toString(16).toUpperCase()||"0"}if(ao){a[al]=+aw}else{if(!at){a[al][ar]=+aw/(al==="Lab"?1:aq[1])}}y(ao?"alpha":al);i(a);C=true;ab(az,ax.type);av.data=aw;x(ay,av)}}function e(aD){var aB=aD||aa.event,aF=aB.target||aB.srcElement,an=aF.className,at=aF.parentNode,ao=ah,am=a.RND.rgb,aq,ap,av=ah.mode,aE="",aA=ao.CSSPrefix,aC=/(?:hs|rgb)/.test(at.className)&&/^[HSBLRG]$/.test(aF.firstChild?aF.firstChild.data:""),ak=/dblc/.test(aB.type),au="";if(ak&&!aC){return}else{if(an.indexOf("-labl "+aA+"labl")!==-1){u(X[an.split("-")[0]],aA+"hide","");u(X[at.className.split("-")[1]],aA+"hide")}else{if(an.indexOf(aA+"butt")!==-1){if(aC){if(ak&&ah.scale===2){aE=/hs/.test(av.type)?"rgb":/hide/.test(X.hsl.className)?"hsv":"hsl";aE=aE+"-"+aE[av.type.indexOf(av.z)]}m.setMode(aE?aE:an.replace("-butt","").split(" ")[0]);au="modeChange"}else{if(/^[rgb]/.test(an)){aE=an.split("-")[1];u(X.colorPicker,"no-rgb-"+aE,(ao["noRGB"+aE]=!ao["noRGB"+aE])?B:"");au="noRGB"+aE}else{if(aF===X.alpha_labl){aq=ao.customBG;ap=ao.alphaBG;u(X.colorPicker,"alpha-bg-"+ap,"alpha-bg-"+(ap=ao.alphaBG=aD.data||(ap==="w"?(aq?"c":"b"):ap==="c"?"b":"w")));aF.firstChild.data=ap.toUpperCase();X.ctrl.style.backgroundColor=X.memo.style.backgroundColor=ap!=="c"?"":"rgb("+Math.round(aq.r*255)+", "+Math.round(aq.g*255)+", "+Math.round(aq.b*255)+")";X.raster.style.cssText=X.raster_bg.previousSibling.style.cssText=ap!=="c"?"":P(aq.luminance<0.22?0.6:0.4);au="alphaBackground"}else{if(aF===X.alpha_butt){u(X.colorPicker,"no-alpha",(ao.noAalpha=!ao.noAalpha)?B:"");au="alphaState"}else{if(aF===X.HEX_butt){u(X.colorPicker,"no-HEX",(ao.HEXState=!ao.HEXState)?B:"");au="HEXState"}else{if(aF===X.HEX_labl){var ay=a.saveColor==="web save";if(a.saveColor!=="web smart"&&!ay){ao.webUnsave=ag(am);m.setColor(a.webSmart,"rgb")}else{if(!ay){if(!ao.webUnsave){ao.webUnsave=ag(am)}m.setColor(a.webSave,"rgb")}else{m.setColor(ao.webUnsave,"rgb")}}au="webColorState"}else{if(/Lab-x-labl/.test(an)){u(X.colorPicker,"cmy-only",(ao.cmyOnly=!ao.cmyOnly)?B:"");au="cmykState"}}}}}}}}else{if(aF===X.bsav){c();au="saveAsBackground"}else{if(aF===X.bres){var al=ag(am),aw=a.alpha;m.setColor(ao.color);c();m.setColor(al,"rgb",aw);au="resetColor"}else{if(at===X.col1){a.hsv.h-=(a.hsv.h>0.5?0.5:-0.5);y("hsv");au="shiftColor"}else{if(at===X.col2){m.setColor(aF.style.backgroundColor,"rgb",a.background.alpha);au="setSavedColor"}else{if(at===X.memo){var ar=function(){if(X.memos.blinker){X.memos.blinker.style.cssText=X.memos.cssText}},az=function(n){X.memos.blinker=n;n.style.cssText="background-color:"+(a.RGBLuminance>0.22?"#333":"#DDD");aa.setTimeout(ar,200)};if(aF===X.memo_cursor){ar();X.memos.blinker=B;X.testNode.style.cssText=X.memo_store.style.cssText;X.memos.cssText=X.testNode.style.cssText;for(var ax=X.memos.length-1;ax--;){if(X.memos.cssText===X.memos[ax].style.cssText){az(X.memos[ax]);break}}if(!X.memos.blinker){for(var ax=X.memos.length-1;ax--;){X.memos[ax+1].style.cssText=X.memos[ax].style.cssText}X.memos[0].style.cssText=X.memo_store.style.cssText}au="toMemery"}else{ar();m.setColor(aF.style.backgroundColor,av.type,aF.style.opacity);X.memos.cssText=aF.style.cssText;az(aF);C=1;au="fromMemory"}}}}}}}}}if(au){i(a);C=C||true;ab(aD,au)}}function Y(an,av){var n=an||aa.event,am=av!==B,aq=am?av:n.pageX-K.left+8,ao=am?av:n.pageY-K.top+8,at=[" S XS XXS"," S XS"," S",""],au=ah.sizes,ar=am?at[av]:ao10?aq:10)+"px;height: "+(ao>10?ao:10)+"px;"}function V(am){var ak={rgb_r:{x:"b",y:"g"},rgb_g:{x:"b",y:"r"},rgb_b:{x:"r",y:"g"},hsv_h:{x:"s",y:"v"},hsv_s:{x:"h",y:"v"},hsv_v:{x:"h",y:"s"},hsl_h:{x:"s",y:"l"},hsl_s:{x:"h",y:"l"},hsl_l:{x:"h",y:"s"}},n=am.replace("-","_"),al="\\b(?:rg|hs)\\w\\-\\w\\b";u(X.panel,al,am);u(X.slds,al,am);am=am.split("-");return ah.mode={type:am[0],x:ak[n].x,y:ak[n].y,z:am[1]}}function T(){var ak=/\s+(?:hue-)*(?:dark|light)/g;X.curl.className=X.curl.className.replace(ak,"");X.curr.className=X.curr.className.replace(ak,"");X.slds.className=X.slds.className.replace(ak,"");X.sldr_2.className=ah.CSSPrefix+"sldr-2";X.sldr_4.className=ah.CSSPrefix+"sldr-4";X.sldl_3.className=ah.CSSPrefix+"sldl-3";for(var n in X.styles){if(!n.indexOf("sld")){X.styles[n].cssText=""}}h={}}function ac(){X.styles.curr.cssText=X.styles.curl.cssText;X.curl.className=ah.CSSPrefix+"curl"+(R.noRGBZ?" "+ah.CSSPrefix+"curl-"+R.noRGBZ:"");X.curr.className=ah.CSSPrefix+"curr "+ah.CSSPrefix+"curr-"+(ah.mode.z==="h"?R.HUEContrast:R.noRGBZ?R.noRGBZ:R.RGBLuminance)}function y(n){i(N.setColor(B,n||ah.mode.type));j=true}function c(){N.saveAsBackground();X.styles.col2.cssText="background-color: "+ae(a.background.RGB)+";"+P(a.background.alpha);return(a)}function i(n){var al=R,ak={w:"White",b:"Black",c:"Custom"}[ah.alphaBG];al.hueDelta=Math.round(n["rgbaMixBGMix"+ak].hueDelta*100);al.luminanceDelta=Math.round(n["rgbaMixBGMix"+ak].luminanceDelta*100);al.RGBLuminance=n.RGBLuminance>0.22?"light":"dark";al.HUEContrast=n.HUELuminance>0.22?"light":"dark";al.contrast=al.luminanceDelta>al.hueDelta?"contrast":"";al.readabiltiy=n["rgbaMixBGMix"+ak].WCAG2Ratio>=7?"green":n["rgbaMixBGMix"+ak].WCAG2Ratio>=4.5?"orange":"";al.noRGBZ=ah["no"+ah.mode.type.toUpperCase()+ah.mode.z]?(ah.mode.z==="g"&&n.rgb.g<0.59||ah.mode.z==="b"||ah.mode.z==="r"?"dark":"light"):B}function O(){if(C){if(!j){return(f=aa[D](O))}j=false}var ap=ah,ay=a,aq=R,aH=h,aB=ap.mode,aD=X,aJ=ap.CSSPrefix,aG=r,aL=H,aC=aD.styles,an=aD.textNodes,aP=ah.scale,az=ay[aB.type][aB.x],am=Math.round(az*255/(aP===4?2:aP)),ao=ay[aB.type][aB.y],ax=1-ao,al=Math.round(ax*255/aP),av=1-ay[aB.type][aB.z],ak=Math.round(av*255/aP),aK=(1===1)?[az,ao]:[0,0],aO=0,aN=0,n=aB.type==="rgb",aw=aB.z==="h",au=aB.type==="hsl",ar=au&&aB.z==="s",aI,aM,aF,aE,at=C===l,aA=C===k;if(n){if(aK[0]>=aK[1]){aN=1}else{aO=1}if(aH.sliderSwap!==aO){aD.sldr_2.className=ap.CSSPrefix+"sldr-"+(3-aO);aH.sliderSwap=aO}}if((n&&!aA)||(aw&&!at)||(!aw&&!aA)){aC[aw?"sldl_2":"sldr_2"][n?"cssText":"backgroundColor"]=n?P((aK[aO]-aK[aN])/(1-(aK[aN])||0)):ae(ay.hueRGB)}if(!aw){if(!aA){aC.sldr_4.cssText=P(n?aK[aN]:ar?Math.abs(1-ax*2):ax)}if(!at){aC.sldl_3.cssText=P(au&&aB.z==="l"?Math.abs(1-av*2):av)}if(au){aE=ar?"sldr_4":"sldl_3";aM=ar?"r-":"l-";aF=ar?(ax>0.5?4:3):(av>0.5?3:4);if(aH[aE]!==aF){aD[aE].className=ap.CSSPrefix+"sld"+aM+aF;aH[aE]=aF}}}if(!aA){aC.curm.cssText="left: "+am+"px; top: "+al+"px;"}if(!at){aC.curl.top=ak+"px"}if(aL){aC.curr.top=ak+"px"}if((aL&&aL.type==="alpha")||G===aD.opacity){aC.opacity_slider.left=ap.opacityPositionRelative?(ay.alpha*((K.width||aD.opacity.offsetWidth)-(K.childWidth||aD.opacity_slider.offsetWidth)))+"px":(ay.alpha*100)+"%"}aC.col1.cssText="background-color: "+ae(ay.RND.rgb)+"; "+(ap.noAalpha?"":P(ay.alpha));aC.opacity.backgroundColor=ae(ay.RND.rgb);aC.cold.width=aq.hueDelta+"%";aC.cont.width=aq.luminanceDelta+"%";for(aI in an){aM=aI.split("_");if(ap.cmyOnly){aM[0]=aM[0].replace("k","")}aF=aM[1]?ay.RND[aM[0]][aM[1]]:ay.RND[aM[0]]||ay[aM[0]];if(aH[aI]!==aF){aH[aI]=aF;an[aI].data=aF>359.5&&aI!=="HEX"?0:aF;if(aI!=="HEX"&&!ap.noRangeBackground){aF=ay[aM[0]][aM[1]]!==B?ay[aM[0]][aM[1]]:ay[aM[0]];if(aM[0]==="Lab"){aF=(aF-aG[aM[0]][aM[1]][0])/(aG[aM[0]][aM[1]][1]-aG[aM[0]][aM[1]][0])}aC[aI]["backgroundPosition"]=Math.round((1-aF)*100)+"% 0"}}}aM=ay._rgb?[ay._rgb.r!==ay.rgb.r,ay._rgb.g!==ay.rgb.g,ay._rgb.b!==ay.rgb.b]:[];if(aM.join("")!==aH.outOfGammut){aD.rgb_r_labl.firstChild.data=aM[0]?"!":" ";aD.rgb_g_labl.firstChild.data=aM[1]?"!":" ";aD.rgb_b_labl.firstChild.data=aM[2]?"!":" ";aH.outOfGammut=aM.join("")}if(aq.noRGBZ){if(aH.noRGBZ!==aq.noRGBZ){aD.curl.className=aJ+"curl "+aJ+"curl-"+aq.noRGBZ;if(!aA){aD.curr.className=aJ+"curr "+aJ+"curr-"+aq.noRGBZ}aH.noRGBZ=aq.noRGBZ}}if(aH.HUEContrast!==aq.HUEContrast&&aB.z==="h"){aD.slds.className=aD.slds.className.replace(/\s+hue-(?:dark|light)/,"")+" hue-"+aq.HUEContrast;if(!aA){aD.curr.className=aJ+"curr "+aJ+"curr-"+aq.HUEContrast}aH.HUEContrast=aq.HUEContrast}else{if(aH.RGBLuminance!==aq.RGBLuminance){aD.colorPicker.className=aD.colorPicker.className.replace(/\s+(?:dark|light)/,"")+" "+aq.RGBLuminance;if(!aA&&aB.z!=="h"&&!aq.noRGBZ){aD.curr.className=aJ+"curr "+aJ+"curr-"+aq.RGBLuminance}aH.RGBLuminance=aq.RGBLuminance}}if(aH.contrast!==aq.contrast||aH.readabiltiy!==aq.readabiltiy){aD.ctrl.className=aD.ctrl.className.replace(" contrast","").replace(/\s*(?:orange|green)/,"")+(aq.contrast?" "+aq.contrast:"")+(aq.readabiltiy?" "+aq.readabiltiy:"");aH.contrast=aq.contrast;aH.readabiltiy=aq.readabiltiy}if(aH.saveColor!==ay.saveColor){aD.HEX_labl.firstChild.data=!ay.saveColor?"!":ay.saveColor==="web save"?"W":"M";aH.saveColor=ay.saveColor}if(ap.renderCallback){ap.renderCallback(ay,aB)}if(C){f=aa[D](O)}}function ag(ak){var al={};for(var am in ak){al[am]=ak[am]}return al}function ae(ak,am){var al=[],an=0;am=am||"rgb";while(am[an]){al.push(ak[am[an++]])}return am+"("+al.join(", ")+")"}function E(al,ak,n){return(al>n?n:al + + + + + color_new + + + + +
+ +
+ +
+
+
+
+ +
+
+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + diff --git a/color.js b/color.js new file mode 100644 index 0000000..bb0108c --- /dev/null +++ b/color.js @@ -0,0 +1,713 @@ +;(function(window, undefined){ + "use strict" + + var _valueRanges = { + rgb: {r: [0, 255], g: [0, 255], b: [0, 255]}, + hsv: {h: [0, 360], s: [0, 100], v: [0, 100]}, + hsl: {h: [0, 360], s: [0, 100], l: [0, 100]}, + cmy: {c: [0, 100], m: [0, 100], y: [0, 100]}, + cmyk: {c: [0, 100], m: [0, 100], y: [0, 100], k: [0, 100]}, + XYZ: {X: [0, 100], Y: [0, 100], Z: [0, 100]}, + Lab: {L: [0, 100], a: [-128, 127], b: [-128, 127]}, + alpha: {alpha: [0, 1]}, + HEX: {HEX: [0, 16777215]} // maybe we don't need this + }, + + _instance = {}, + _colors = {}, + + // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html for more + XYZMatrix = { // Observer = 2° (CIE 1931), Illuminant = D65 + X: [ 0.4124564, 0.3575761, 0.1804375], + Y: [ 0.2126729, 0.7151522, 0.0721750], + Z: [ 0.0193339, 0.1191920, 0.9503041], + R: [ 3.2404542, -1.5371385, -0.4985314], + G: [-0.9692660, 1.8760108, 0.0415560], + B: [ 0.0556434, -0.2040259, 1.0572252] + }, + grey = {r: 0.298954, g: 0.586434, b: 0.114612}, // CIE-XYZ 1931 + luminance = {r: 0.2126, g: 0.7152, b: 0.0722}, // W3C 2.0 + + Colors = window.Colors = function(options) { + this.colors = {RND: {}}; + this.options = { + color: 'rgba(204, 82, 37, 0.8)', // init value(s)... + XYZMatrix: XYZMatrix, + // XYZReference: {}, + grey: grey, + luminance: luminance, + valueRanges: _valueRanges + // customBG: '#808080' + // convertCallback: undefined, + // allMixDetails: false + }; + initInstance(this, options || {}); + }, + initInstance = function(THIS, options) { + var matrix, + importColor, + _options = THIS.options, + customBG; + + focusInstance(THIS); + for (var option in options) { + if (options[option] !== undefined) _options[option] = options[option]; + } + matrix = _options.XYZMatrix; + if (!options.XYZReference) _options.XYZReference = { + X: matrix.X[0] + matrix.X[1] + matrix.X[2], + Y: matrix.Y[0] + matrix.Y[1] + matrix.Y[2], + Z: matrix.Z[0] + matrix.Z[1] + matrix.Z[2] + }; + customBG = _options.customBG; + _options.customBG = (typeof customBG === 'string') ? ColorConverter.txt2color(customBG).rgb : customBG; + _colors = setColor(THIS.colors, _options.color, undefined, true); // THIS.colors = _colors = + }, + focusInstance = function(THIS) { + if (_instance !== THIS) { + _instance = THIS; + _colors = THIS.colors; + } + }; + + Colors.prototype.setColor = function(newCol, type, alpha) { + focusInstance(this); + if (newCol) { + return setColor(this.colors, newCol, type, undefined, alpha); + } else { + if (alpha !== undefined) { + this.colors.alpha = alpha; + } + return convertColors(type); + } + }; + + Colors.prototype.getColor = function(type) { + var result = this.colors, n = 0; + + if (type) { + type = type.split('.'); + while (result[type[n]]) { + result = result[type[n++]]; + } + if (type.length !== n) { + result = undefined; + } + } + return result; + }; + + Colors.prototype.setCustomBackground = function(col) { // wild gues,... check again... + focusInstance(this); // needed??? + this.options.customBG = (typeof col === 'string') ? ColorConverter.txt2color(col).rgb : col; + // return setColor(this.colors, this.options.customBG, 'rgb', true); // !!!!RGB + return setColor(this.colors, undefined, 'rgb'); // just recalculate existing + }; + + Colors.prototype.saveAsBackground = function() { // alpha + focusInstance(this); // needed??? + // return setColor(this.colors, this.colors.RND.rgb, 'rgb', true); + return setColor(this.colors, undefined, 'rgb', true); + }; + + Colors.prototype.convertColor = function(color, type) { + var convert = ColorConverter, + ranges = _valueRanges, + types = type.split('2'), + fromType = types[0], + toType = types[1], + test = /(?:RG|HS|CM|LA)/, + normalizeFrom = test.test(fromType), + normalizeTo = test.test(toType), + exceptions = {LAB: 'Lab'}, + normalize = function(color, type, reverse) { + var result = {}, + Lab = type === 'Lab' ? 1 : 0; + + for (var n in color) { // faster (but bigger) way: if/else outside 2 for loops + result[n] = reverse ? + Math.round(color[n] * (Lab || ranges[type][n][1])) : + color[n] / (Lab || ranges[type][n][1]); + } + + return result; + }; + + fromType = ranges[fromType] ? fromType : exceptions[fromType] || fromType.toLowerCase(); + toType = ranges[toType] ? toType : exceptions[toType] || toType.toLowerCase(); + + if (normalizeFrom && type !== 'RGB2HEX') { // from ABC to abc + color = normalize(color, fromType); + } + color = fromType === toType ? color : ( // same type; returns same/normalized version + convert[fromType + '2' + toType] ? convert[fromType + '2' + toType](color, true) : // existing converter + toType === 'HEX' ? convert.RGB2HEX(type === 'RGB2HEX' ? color : normalize(fromType === 'rgb' ? color : + convert[fromType + '2rgb'](color, true), 'rgb', true)) : + convert['rgb2' + toType](convert[fromType + '2rgb'](color, true), true) // not in ColorConverter + ); + if (normalizeTo) { // from abc to ABC + color = normalize(color, toType, true); + } + + return color; + }; + + // ------------------------------------------------------ // + // ---------- Color calculation related stuff ---------- // + // -------------------------------------------------------// + + function setColor(colors, color, type, save, alpha) { // color only full range + if (typeof color === 'string') { + var color = ColorConverter.txt2color(color); // new object + type = color.type; + _colors[type] = color[type]; + alpha = alpha !== undefined ? alpha : color.alpha; + } else if (color) { + for (var n in color) { + colors[type][n] = limitValue(color[n] / _valueRanges[type][n][1], 0 , 1); + } + } + if (alpha !== undefined) { + colors.alpha = +alpha; + } + return convertColors(type, save ? colors : undefined); + } + + function saveAsBackground(RGB, rgb, alpha) { + var grey = _instance.options.grey, + color = {}; + + color.RGB = {r: RGB.r, g: RGB.g, b: RGB.b}; + color.rgb = {r: rgb.r, g: rgb.g, b: rgb.b}; + color.alpha = alpha; + // color.RGBLuminance = getLuminance(RGB); + color.equivalentGrey = Math.round(grey.r * RGB.r + grey.g * RGB.g + grey.b * RGB.b); + + color.rgbaMixBlack = mixColors(rgb, {r: 0, g: 0, b: 0}, alpha, 1); + color.rgbaMixWhite = mixColors(rgb, {r: 1, g: 1, b: 1}, alpha, 1); + color.rgbaMixBlack.luminance = getLuminance(color.rgbaMixBlack, true); + color.rgbaMixWhite.luminance = getLuminance(color.rgbaMixWhite, true); + + if (_instance.options.customBG) { + color.rgbaMixCustom = mixColors(rgb, _instance.options.customBG, alpha, 1); + color.rgbaMixCustom.luminance = getLuminance(color.rgbaMixCustom, true); + _instance.options.customBG.luminance = getLuminance(_instance.options.customBG, true); + } + + return color; + } + + function convertColors(type, colorObj) { + // console.time('convertColors'); + var colors = colorObj || _colors, + convert = ColorConverter, + options = _instance.options, + ranges = _valueRanges, + RND = colors.RND, + // type = colorType, // || _mode.type, + modes, mode = '', from = '', // value = '', + exceptions = {hsl: 'hsv', cmyk: 'cmy', rgb: type}, + RGB = RND.rgb, SAVE, SMART; + + if (type !== 'alpha') { +/* if (type !== 'rgb') colors.rgb = convert[type + '2rgb'](colors[type]); + if (type !== 'hsv') colors.hsv = convert.rgb2hsv(colors.rgb); + if (type !== 'hsl') colors.hsl = convert.hsv2hsl(colors.hsv); + if (type !== 'cmy' && type !== 'cmyk') colors.cmy = convert.rgb2cmy(colors.rgb); + if (type !== 'cmyk') colors.cmyk = convert.cmy2cmyk(colors.cmy); + if (type !== 'Lab') { + colors.Lab = convert.rgb2Lab(colors.rgb); + delete colors._rgb; + } +*/ + for (var typ in ranges) { + if (!ranges[typ][typ]) { // no alpha|HEX + if (type !== typ && typ !== 'XYZ') { + from = exceptions[typ] || 'rgb'; + colors[typ] = convert[from + '2' + typ](colors[from]); + } + + if (!RND[typ]) RND[typ] = {}; + modes = colors[typ]; + for(mode in modes) { + RND[typ][mode] = Math.round(modes[mode] * (typ === 'Lab' ? 1 : ranges[typ][mode][1])); + } + } + } + if (type !== 'Lab') { + delete colors._rgb; + } + + RGB = RND.rgb; + colors.HEX = convert.RGB2HEX(RGB); + colors.equivalentGrey = + options.grey.r * colors.rgb.r + + options.grey.g * colors.rgb.g + + options.grey.b * colors.rgb.b; + colors.webSave = SAVE = getClosestWebColor(RGB, 51); + // colors.webSave.HEX = convert.RGB2HEX(colors.webSave); + colors.webSmart = SMART = getClosestWebColor(RGB, 17); + // colors.webSmart.HEX = convert.RGB2HEX(colors.webSmart); + colors.saveColor = + RGB.r === SAVE.r && RGB.g === SAVE.g && RGB.b === SAVE.b ? 'web save' : + RGB.r === SMART.r && RGB.g === SMART.g && RGB.b === SMART.b ? 'web smart' : ''; + colors.hueRGB = ColorConverter.hue2RGB(colors.hsv.h); + + if (colorObj) { + colors.background = saveAsBackground(RGB, colors.rgb, colors.alpha); + } + } // else RGB = RND.rgb; + + var rgb = colors.rgb, // for better minification... + alpha = colors.alpha, + luminance = 'luminance', + background = colors.background, + rgbaMixBlack, rgbaMixWhite, rgbaMixCustom, + rgbaMixBG, rgbaMixBGMixBlack, rgbaMixBGMixWhite, rgbaMixBGMixCustom; + + rgbaMixBlack = mixColors(rgb, {r: 0, g: 0, b: 0}, alpha, 1); + rgbaMixBlack[luminance] = getLuminance(rgbaMixBlack, true); + colors.rgbaMixBlack = rgbaMixBlack; + + rgbaMixWhite = mixColors(rgb, {r: 1, g: 1, b: 1}, alpha, 1); + rgbaMixWhite[luminance] = getLuminance(rgbaMixWhite, true); + colors.rgbaMixWhite = rgbaMixWhite; + + if (options.allMixDetails) { + rgbaMixBlack.WCAG2Ratio = getWCAG2Ratio(rgbaMixBlack[luminance], 0); + rgbaMixWhite.WCAG2Ratio = getWCAG2Ratio(rgbaMixWhite[luminance], 1); + + if (options.customBG) { + rgbaMixCustom = mixColors(rgb, options.customBG, alpha, 1); + rgbaMixCustom[luminance] = getLuminance(rgbaMixCustom, true); + rgbaMixCustom.WCAG2Ratio = getWCAG2Ratio(rgbaMixCustom[luminance], options.customBG[luminance]); + colors.rgbaMixCustom = rgbaMixCustom; + } + + rgbaMixBG = mixColors(rgb, background.rgb, alpha, background.alpha); + rgbaMixBG[luminance] = getLuminance(rgbaMixBG, true); // ?? do we need this? + colors.rgbaMixBG = rgbaMixBG; + + rgbaMixBGMixBlack = mixColors(rgb, background.rgbaMixBlack, alpha, 1); + rgbaMixBGMixBlack[luminance] = getLuminance(rgbaMixBGMixBlack, true); + rgbaMixBGMixBlack.WCAG2Ratio = getWCAG2Ratio(rgbaMixBGMixBlack[luminance], + background.rgbaMixBlack[luminance]); + /* ------ */ + rgbaMixBGMixBlack.luminanceDelta = Math.abs( + rgbaMixBGMixBlack[luminance] - colors.background.rgbaMixBlack[luminance]); + rgbaMixBGMixBlack.hueDelta = getHueDelta(background.rgbaMixBlack, rgbaMixBGMixBlack, true); + /* ------ */ + colors.rgbaMixBGMixBlack = rgbaMixBGMixBlack; + + rgbaMixBGMixWhite = mixColors(rgb, background.rgbaMixWhite, alpha, 1); + rgbaMixBGMixWhite[luminance] = getLuminance(rgbaMixBGMixWhite, true); + rgbaMixBGMixWhite.WCAG2Ratio = getWCAG2Ratio(rgbaMixBGMixWhite[luminance], + background.rgbaMixWhite[luminance]); + /* ------ */ + rgbaMixBGMixWhite.luminanceDelta = Math.abs( + rgbaMixBGMixWhite[luminance] - colors.background.rgbaMixWhite[luminance]); + rgbaMixBGMixWhite.hueDelta = getHueDelta(background.rgbaMixWhite, rgbaMixBGMixWhite, true); + /* ------ */ + colors.rgbaMixBGMixWhite = rgbaMixBGMixWhite; + } + + if (options.customBG) { + rgbaMixBGMixCustom = mixColors(rgb, background.rgbaMixCustom, alpha, 1); + rgbaMixBGMixCustom[luminance] = getLuminance(rgbaMixBGMixCustom, true); + rgbaMixBGMixCustom.WCAG2Ratio = getWCAG2Ratio(rgbaMixBGMixCustom[luminance], + background.rgbaMixCustom[luminance]); + colors.rgbaMixBGMixCustom = rgbaMixBGMixCustom; + /* ------ */ + rgbaMixBGMixCustom.luminanceDelta = Math.abs( + rgbaMixBGMixCustom[luminance] - colors.background.rgbaMixCustom[luminance]); + rgbaMixBGMixCustom.hueDelta = getHueDelta(background.rgbaMixCustom, rgbaMixBGMixCustom, true); + /* ------ */ + } + + colors.RGBLuminance = getLuminance(RGB); + colors.HUELuminance = getLuminance(colors.hueRGB); + + // renderVars.readyToRender = true; + if (options.convertCallback) { + options.convertCallback(colors, type); //, convert); //, _mode); + } + + // console.timeEnd('convertColors') + // if (colorObj) + return colors; + } + + + // ------------------------------------------------------ // + // ------------------ color conversion ------------------ // + // -------------------------------------------------------// + + var ColorConverter = { + txt2color: function(txt) { + var color = {}, + parts = txt.replace(/(?:#|\))/, '').split('('), + values = (parts[1] || '').split(/,\s*/), + type = parts[1] ? parts[0].substr(0, 3) : 'rgb', + m = ''; + + color.type = type; + color[type] = {}; + if (parts[1]) { + for (var n = 3; n--; ) { + m = type[n] || type.charAt(n); // IE7 + color[type][m] = +values[n] / _valueRanges[type][m][1]; + } + } else { + color.rgb = ColorConverter.HEX2rgb(parts[0]); + } + // color.color = color[type]; + color.alpha = values[3] ? +values[3] : 1; + + return color; + }, + + RGB2HEX: function(RGB) { + return ( + (RGB.r < 16 ? '0' : '') + RGB.r.toString(16) + + (RGB.g < 16 ? '0' : '') + RGB.g.toString(16) + + (RGB.b < 16 ? '0' : '') + RGB.b.toString(16) + ).toUpperCase(); + }, + + HEX2rgb: function(HEX) { + HEX = HEX.split(''); // IE7 + return { + r: parseInt(HEX[0] + HEX[HEX[3] ? 1 : 0], 16) / 255, + g: parseInt(HEX[HEX[3] ? 2 : 1] + (HEX[3] || HEX[1]), 16) / 255, + b: parseInt((HEX[4] || HEX[2]) + (HEX[5] || HEX[2]), 16) / 255 + }; + }, + + hue2RGB: function(hue) { + var h = hue * 6, + mod = ~~h % 6, // Math.floor(h) -> faster in most browsers + i = h === 6 ? 0 : (h - mod); + + return { + r: Math.round([1, 1 - i, 0, 0, i, 1][mod] * 255), + g: Math.round([i, 1, 1, 1 - i, 0, 0][mod] * 255), + b: Math.round([0, 0, i, 1, 1, 1 - i][mod] * 255) + } + }, + + // ------------------------ HSV ------------------------ // + + rgb2hsv: function(rgb) { // faster + var r = rgb.r, + g = rgb.g, + b = rgb.b, + k = 0, chroma, min, s; + + if (g < b) { + g = b + (b = g, 0); + k = -1; + } + min = b; + if (r < g) { + r = g + (g = r, 0); + k = -2 / 6 - k; + min = Math.min(g, b); // g < b ? g : b; ??? + } + chroma = r - min; + s = r ? (chroma / r) : 0; + return { + h: s < 1e-15 ? ((_colors && _colors.hsl.h) || 0) : chroma ? Math.abs(k + (g - b) / (6 * chroma)) : 0, + s: r ? (chroma / r) : ((_colors && _colors.hsv.s) || 0), // ??_colors.hsv.s || 0 + v: r + }; + }, + + hsv2rgb: function(hsv) { + var h = hsv.h * 6, + s = hsv.s, + v = hsv.v, + i = ~~h, // Math.floor(h) -> faster in most browsers + f = h - i, + p = v * (1 - s), + q = v * (1 - f * s), + t = v * (1 - (1 - f) * s), + mod = i % 6; + + return { + r: [v, q, p, p, t, v][mod], + g: [t, v, v, q, p, p][mod], + b: [p, p, t, v, v, q][mod] + }; + }, + + // ------------------------ HSL ------------------------ // + + hsv2hsl: function(hsv) { + var l = (2 - hsv.s) * hsv.v, + s = hsv.s * hsv.v; + + s = !hsv.s ? 0 : l < 1 ? (l ? s / l : 0) : s / (2 - l); + + return { + h: hsv.h, + s: !hsv.v && !s ? ((_colors && _colors.hsl.s) || 0) : s, // ??? + l: l / 2 + } + }, + + rgb2hsl: function(rgb, dependent) { // not used in Color + var hsv = ColorConverter.rgb2hsv(rgb); + + return ColorConverter.hsv2hsl(dependent ? hsv : (_colors.hsv = hsv)); + }, + + hsl2rgb: function(hsl) { + var h = hsl.h * 6, + s = hsl.s, + l = hsl.l, + v = l < 0.5 ? l * (1 + s) : (l + s) - (s * l), + m = l + l - v, + sv = v ? ((v - m) / v) : 0, + sextant = ~~h, // Math.floor(h) -> faster in most browsers + fract = h - sextant, + vsf = v * sv * fract, + t = m + vsf, + q = v - vsf, + mod = sextant % 6; + + return { + r: [v, q, m, m, t, v][mod], + g: [t, v, v, q, m, m][mod], + b: [m, m, t, v, v, q][mod] + }; + }, + + // ------------------------ CMYK ------------------------ // + // Quote from Wikipedia: + // "Since RGB and CMYK spaces are both device-dependent spaces, there is no + // simple or general conversion formula that converts between them. + // Conversions are generally done through color management systems, using + // color profiles that describe the spaces being converted. Nevertheless, the + // conversions cannot be exact, since these spaces have very different gamuts." + // Translation: the following are just simple RGB to CMY(K) and visa versa conversion functions. + + rgb2cmy: function(rgb) { + return { + c: 1 - rgb.r, + m: 1 - rgb.g, + y: 1 - rgb.b + }; + }, + + cmy2cmyk: function(cmy) { + var k = Math.min(Math.min(cmy.c, cmy.m), cmy.y), + t = 1 - k || 1e-20; + + return { // regular + c: (cmy.c - k) / t, + m: (cmy.m - k) / t, + y: (cmy.y - k) / t, + k: k + }; + }, + + cmyk2cmy: function(cmyk) { + var k = cmyk.k; + + return { // regular + c: cmyk.c * (1 - k) + k, + m: cmyk.m * (1 - k) + k, + y: cmyk.y * (1 - k) + k + }; + }, + + cmy2rgb: function(cmy) { + return { + r: 1 - cmy.c, + g: 1 - cmy.m, + b: 1 - cmy.y + }; + }, + + rgb2cmyk: function(rgb, dependent) { + var cmy = ColorConverter.rgb2cmy(rgb); // doppelt?? + + return ColorConverter.cmy2cmyk(dependent ? cmy : (_colors.cmy = cmy)); + }, + + cmyk2rgb: function(cmyk, dependent) { + var cmy = ColorConverter.cmyk2cmy(cmyk); // doppelt?? + + return ColorConverter.cmy2rgb(dependent ? cmy : (_colors.cmy = cmy)); + }, + + // ------------------------ LAB ------------------------ // + + XYZ2rgb: function(XYZ, skip) { + var M = _instance.options.XYZMatrix, + X = XYZ.X, + Y = XYZ.Y, + Z = XYZ.Z, + r = X * M.R[0] + Y * M.R[1] + Z * M.R[2], + g = X * M.G[0] + Y * M.G[1] + Z * M.G[2], + b = X * M.B[0] + Y * M.B[1] + Z * M.B[2], + N = 1 / 2.4, M = 0.0031308; + + r = (r > M ? 1.055 * Math.pow(r, N) - 0.055 : 12.92 * r); + g = (g > M ? 1.055 * Math.pow(g, N) - 0.055 : 12.92 * g); + b = (b > M ? 1.055 * Math.pow(b, N) - 0.055 : 12.92 * b); + + if (!skip) { // out of gammut + _colors._rgb = {r: r, g: g, b: b}; + } + + return { + r: limitValue(r, 0, 1), + g: limitValue(g, 0, 1), + b: limitValue(b, 0, 1) + }; + }, + + rgb2XYZ: function(rgb) { + var M = _instance.options.XYZMatrix, + r = rgb.r, + g = rgb.g, + b = rgb.b, + N = 0.04045; + + r = (r > N ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92); + g = (g > N ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92); + b = (b > N ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92); + + return { + X: r * M.X[0] + g * M.X[1] + b * M.X[2], + Y: r * M.Y[0] + g * M.Y[1] + b * M.Y[2], + Z: r * M.Z[0] + g * M.Z[1] + b * M.Z[2] + }; + }, + + XYZ2Lab: function(XYZ) { + var R = _instance.options.XYZReference, + X = XYZ.X / R.X, + Y = XYZ.Y / R.Y, + Z = XYZ.Z / R.Z, + N = 16 / 116, M = 1 / 3, K = 0.008856, L = 7.787037; + + X = X > K ? Math.pow(X, M) : (L * X) + N; + Y = Y > K ? Math.pow(Y, M) : (L * Y) + N; + Z = Z > K ? Math.pow(Z, M) : (L * Z) + N; + + return { + L: (116 * Y) - 16, + a: 500 * (X - Y), + b: 200 * (Y - Z) + }; + }, + + Lab2XYZ: function(Lab) { + var R = _instance.options.XYZReference, + Y = (Lab.L + 16) / 116, + X = Lab.a / 500 + Y, + Z = Y - Lab.b / 200, + X3 = Math.pow(X, 3), + Y3 = Math.pow(Y, 3), + Z3 = Math.pow(Z, 3), + N = 16 / 116, K = 0.008856, L = 7.787037; + + return { + X: (X3 > K ? X3 : (X - N) / L) * R.X, + Y: (Y3 > K ? Y3 : (Y - N) / L) * R.Y, + Z: (Z3 > K ? Z3 : (Z - N) / L) * R.Z + }; + }, + + rgb2Lab: function(rgb, dependent) { + var XYZ = ColorConverter.rgb2XYZ(rgb); + + return ColorConverter.XYZ2Lab(dependent ? XYZ : (_colors.XYZ = XYZ)); + }, + + Lab2rgb: function(Lab, dependent) { + var XYZ = ColorConverter.Lab2XYZ(Lab); + + return ColorConverter.XYZ2rgb(dependent ? XYZ : (_colors.XYZ = XYZ), dependent); + } + }; + + // ------------------------------------------------------ // + // ------------------ helper functions ------------------ // + // -------------------------------------------------------// + + function getClosestWebColor(RGB, val) { + var out = {}, + tmp = 0, + half = val / 2; + + for (var n in RGB) { + tmp = RGB[n] % val; // 51 = 'web save', 17 = 'web smart' + out[n] = RGB[n] + (tmp > half ? val - tmp : -tmp); + } + return out; + } + + function getHueDelta(rgb1, rgb2, nominal) { + return (Math.max(rgb1.r - rgb2.r, rgb2.r - rgb1.r) + + Math.max(rgb1.g - rgb2.g, rgb2.g - rgb1.g) + + Math.max(rgb1.b - rgb2.b, rgb2.b - rgb1.b)) * (nominal ? 255 : 1) / 765; + } + + function getLuminance(rgb, normalized) { + var div = normalized ? 1 : 255, + RGB = [rgb.r / div, rgb.g / div, rgb.b / div], + luminance = _instance.options.luminance; + + for (var i = RGB.length; i--; ) { + RGB[i] = RGB[i] <= 0.03928 ? RGB[i] / 12.92 : Math.pow(((RGB[i] + 0.055) / 1.055), 2.4); + } + return ((luminance.r * RGB[0]) + (luminance.g * RGB[1]) + (luminance.b * RGB[2])); + } + +/* function mixColors(topColor, bottomColor, topAlpha, bottomAlpha) { + // http://stackoverflow.com/questions/726549/algorithm-for-additive-color-mixing-for-rgb-values + var newColor = {}, + alphaTop = (topAlpha !== undefined ? topAlpha : 1), + alphaBottom = (bottomAlpha !== undefined ? bottomAlpha : 1); + + // if (alphaTop >= 1) return topColor; + + for(var n in topColor) { + newColor[n] = topColor[n] * alphaTop + + bottomColor[n] * alphaBottom * (1 - alphaTop); + } + newColor.a = alphaTop + alphaBottom * (1 - alphaTop); + return newColor; + } +*/ + function mixColors(topColor, bottomColor, topAlpha, bottomAlpha) { + var newColor = {}, + alphaTop = (topAlpha !== undefined ? topAlpha : 1), + alphaBottom = (bottomAlpha !== undefined ? bottomAlpha : 1), + alpha = alphaTop + alphaBottom * (1 - alphaTop); // 1 - (1 - alphaTop) * (1 - alphaBottom); + + for(var n in topColor) { + newColor[n] = (topColor[n] * alphaTop + bottomColor[n] * alphaBottom * (1 - alphaTop)) / alpha; + } + newColor.a = alpha; + return newColor; + } + + function getWCAG2Ratio(lum1, lum2) { + var ratio = 1; + + if (lum1 >= lum2) { + ratio = (lum1 + 0.05) / (lum2 + 0.05); + } else { + ratio = (lum2 + 0.05) / (lum1 + 0.05); + } + return Math.round(ratio * 100) / 100; + } + + function limitValue(value, min, max) { + return (value > max ? max : value < min ? min : value); + } +})(window); \ No newline at end of file diff --git a/colorPicker.css b/colorPicker.css new file mode 100644 index 0000000..e126cd6 --- /dev/null +++ b/colorPicker.css @@ -0,0 +1,646 @@ +/* -------- main app -------- */ + +.cp-app { + color: #bbb; + font-family: "Courier New", Courier, mono; /* "Courier New", */ + font-size: 12px; + line-height: 15px; + font-weight: bold; + cursor: default; + + width: 412px; + height: 323px; + background-color: #444; + border-radius: 7px; +} +.S { + width: 266px; + height: 177px; +} +.XS { + width: 158px; + height: 173px; +} +.XXS { + height: 105px; + width: 154px; +} +.no-alpha { + height: 308px; +} +.no-alpha .cp-opacity, .no-alpha .cp-alpha { + display: none; +} +.S.no-alpha { /* IE6 */ + height: 162px; +} +.XS.no-alpha { + height: 158px; +} +.XXS.no-alpha { + height: 90px; +} + + +.cp-app, +.cp-app div { /* reset for all children */ + border: none; + padding: 0; + float: none; + margin: 0; + outline: none; + /* to be IE <7 compatible */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + -ms-box-sizing: content-box; + box-sizing: content-box; +} +.cp-app div { + position: absolute; +} + +/* -------- images -------- */ + +.cp-slds .cp-curm, +.cp-panel .cp-disp, +.cp-panel .cp-nsarrow, +.cp-app .cp-exit, +.cp-app .cp-memo-cursor, +.cp-app .cp-resize { + background-image: url(_icons.png); +} +.cp-app .do-drag div { + cursor: url(_blank.png), auto; +} +.cp-app .cp-opacity, +.cp-memo .cp-raster-bg, +.cp-app .cp-raster { + background-image: url(_bgs.png); +} + +/* -------- left sliders -------- */ + +.cp-app .cp-slds { + width: 287px; + height: 256px; + top: 10px; + left: 10px; + overflow: hidden; + cursor: crosshair; +} +.S .cp-slds { + width: 143px; + height: 128px; + left: 9px; + top: 9px; +} +.XS .cp-slds { + left: 7px; + top: 7px; +} +.XXS .cp-slds { + left: 5px; + top: 5px; +} + +/* .cp-slds .cp-sldl-1, +.cp-slds .cp-sldl-2, +.cp-slds .cp-sldl-3, +.cp-slds .cp-sldl-4 { */ +.cp-slds div { + width: 256px; + height: 256px; + left: 0; +} +.S .cp-sldl-1, +.S .cp-sldl-2, +.S .cp-sldl-3, +.S .cp-sldl-4 { + width: 128px; + height: 128px; +} +.XXS .cp-slds, +.XXS .cp-slds .cp-sldl-1, +.XXS .cp-slds .cp-sldl-2, +.XXS .cp-slds .cp-sldl-3, +.XXS .cp-slds .cp-sldl-4 { + height: 64px; +} + +/* -------- right sliders -------- */ + +.cp-slds .cp-sldr-1, +.cp-slds .cp-sldr-2, +.cp-slds .cp-sldr-3, +.cp-slds .cp-sldr-4 { + width: 31px; + /* height: 256px; */ + left: 256px; + cursor: default; +} +.S .cp-sldr-1, +.S .cp-sldr-2, +.S .cp-sldr-3, +.S .cp-sldr-4 { + width: 15px; + height: 128px; + left: 128px; +} + +/* -------- Cursors -------- */ + +.cp-slds .cp-curm { + margin: -5px; + width: 11px; + height: 11px; + background-position: -36px -30px; + /* cursor: crosshair; */ +} +.light .cp-curm { + background-position: -7px -30px; +} + +.cp-slds .cp-curl, +.cp-slds .cp-curr { + width: 0px; + height: 0px; + margin: -3px -4px; + border: 4px solid; + background-image: none; + cursor: default; + left: auto; /* due to .cp-slds div */ +} + +.cp-slds .cp-curl, +.cp-app .cp-slds .cp-curl-dark, +.hue-dark div.cp-curl { + right: 27px; + border-color: transparent transparent transparent #fff; +} +.light .cp-curl, +.cp-app .cp-slds .cp-curl-light, +.hue-light .cp-curl { + border-color: transparent transparent transparent #000; +} +.S .cp-slds .cp-curl, +.S .cp-slds .cp-curr { + border-width: 3px; +} +.S .cp-slds .cp-curl-light, +.S .cp-slds .cp-curl { + right: 13px; +} + +.cp-slds .cp-curr, +.cp-app .cp-slds .cp-curr-dark { + right: 4px; + border-color: transparent #fff transparent transparent; +} +.light .cp-curr, +.cp-app .cp-slds .cp-curr-light { + border-color: transparent #000 transparent transparent; +} + +/* -------- alpha bar -------- */ + +.cp-app .cp-opacity { + bottom: 44px; + left: 10px; + height: 10px; + width: 287px; + background-position: 0 -87px; +} +.S .cp-opacity { + bottom: 27px; + left: 9px; + width: 143px; + background-position: 0 -100px; +} +.XS .cp-opacity { + left: 7px; + bottom: 25px; +} +.XXS .cp-opacity { + left: 5px; + bottom: 23px; +} +.cp-opacity div { + width: 100%; + height: 16px; + margin-top: -3px; + overflow: hidden; +} +.cp-opacity .cp-opacity-slider { + margin: 0 -4px; + width: 0px; + height: 8px; /* IE7 */ + + border: 4px solid #aaa; + border-color: #eee transparent; +} + +/* -------- color memory -------- */ + +.cp-app .cp-memo { + bottom: 10px; + left: 10px; + width: 288px; + height: 31px; + background-color: #fff; +} +.S .cp-memo { + height: 15px; + width: 144px; + left: 9px; + bottom: 9px; +} +.XS .cp-memo { + left: 7px; + bottom: 7px; +} +.XXS .cp-memo { + left: 5px; + bottom: 5px; +} +.cp-memo div { + position: relative; + float: left; + width: 31px; + height: 31px; + margin-right: 1px; +} +.S .cp-memo div { + width: 15px; + height: 15px; +} +.cp-app .cp-raster, /* also for .cp-ctrl section */ +.cp-memo .cp-raster-bg, +.S .cp-memo .cp-raster, +.S .cp-memo .cp-raster-bg { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; +} +.S .cp-memo .cp-raster-bg { + background-position: 0 -31px; +} +.cp-app .cp-raster { + background-position: 0px -49px; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)"; + filter: alpha(opacity=20); + -moz-opacity: 0.2; + -khtml-opacity: 0.2; + opacity: .2; +} +.alpha-bg-b .cp-memo { + background-color: #333; +} +.alpha-bg-b .cp-raster { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; + filter: alpha(opacity=100); + -moz-opacity: 1; + -khtml-opacity: 1; + opacity: 1; +} + +.cp-memo .cp-memo-cursor { + position: absolute; + right: 0; + background-position: -26px -87px; +} +.cp-app .light .cp-memo-cursor { + background-position: 3px -87px; +} +.S .cp-memo-cursor { + background-position: -34px -95px; +} +.S .light .cp-memo-cursor { + background-position: -5px -95px; +} + +/* -------- panel -------- */ + +.cp-app .cp-panel { + position: absolute; + top: 10px; + right: 10px; + bottom: 10px; + width: 96px; + background-color: #333; + border: 1px solid; + border-color: #222 #555 #555 #222; + overflow: hidden; +} +.S .cp-panel { + top: 9px; + right: 9px; + bottom: 9px; +} +.XS .cp-panel { + display: none; +} + +.cp-panel div { + position: relative; + /*overflow: visible;*/ /* especially for .cp-disp */ +} + +/* -------- panel sections -------- */ + +.cp-panel .cp-hsv, /* not very happy with this ... */ +.cp-panel .cp-hsl, +.cp-panel .cp-rgb, +.cp-panel .cp-cmyk, +.cp-panel .cp-Lab, +.cp-panel .cp-alpha, +.no-alpha .cp-panel .cp-HEX, +.cp-panel .cp-HEX { + width: 86px; + margin: -1px 0 1px 4px; + padding: 1px 0 3px; + border-top: 1px solid #444; + border-bottom: 1px solid #222; + float: left; +} +.cp-panel .cp-hsv, +.cp-panel .cp-hsl { + padding-top: 2px; +} +.S .cp-hsv, +.S .cp-hsl { + padding-top: 1px; +} +.cp-panel .cp-HEX { + border-bottom: none; /* 1px solid #333; */ + border-top: 0; + margin-top: -4px; + padding-top: 0; +} +.no-alpha .cp-panel .cp-HEX { + border-bottom: none; +} + +.cp-panel .cp-alpha { + border-bottom: none; +} +.S .rgb-r .cp-hsv, +.S .rgb-g .cp-hsv, +.S .rgb-b .cp-hsv, +.S .rgb-r .cp-hsl, +.S .rgb-g .cp-hsl, +.S .rgb-b .cp-hsl, +.S .hsv-h .cp-rgb, +.S .hsv-s .cp-rgb, +.S .hsv-v .cp-rgb, +.S .hsl-h .cp-rgb, +.S .hsl-s .cp-rgb, +.S .hsl-l .cp-rgb, +.S .cp-cmyk, +.S .cp-Lab { + display: none; +} + +/* -------- panel sections' elements -------- */ + +.cp-panel .cp-butt, +.cp-panel .cp-labl { + float: left; + width: 16px; width: 14px; /* IE 7 */ + height: 16px; height: 14px; /* IE 7 */ + margin-top: 2px; + text-align: center; + border: 1px solid; +} +.cp-panel .cp-butt { + border-color: #555 #222 #222 #555; +} +.cp-panel .cp-butt:active { + background-color: #444; +} +.cp-panel .cp-labl { + border-color: transparent; +} +.cp-panel .Lab-mode, +.cp-panel .cmyk-mode, +.cp-panel .hsv-mode, +.cp-panel .hsl-mode { + position: absolute; + right: 0; + top: 0; /* IE 7 */ + height: 52px; +} +.cp-panel .cmyk-mode { + height: 70px; +} +.hsl-h .hsl-h-labl, +.hsl-s .hsl-s-labl, +.hsl-l .hsl-l-labl, +.hsv-h .hsv-h-labl, +.hsv-s .hsv-s-labl, +.hsv-v .hsv-v-labl { + color: #FF9900; +} + +.cp-panel .cmyk-mode, +.cp-panel .hsv-mode, + +.rgb-r .rgb-r-butt, .rgb-g .rgb-g-butt, .rgb-b .rgb-b-butt, +.hsv-h .hsv-h-butt, .hsv-s .hsv-s-butt, .hsv-v .hsv-v-butt, +.hsl-h .hsl-h-butt, .hsl-s .hsl-s-butt, .hsl-l .hsl-l-butt, + +.cp-panel .rgb-r-labl, +.cp-panel .rgb-g-labl, +.cp-panel .rgb-b-labl, + +.cp-panel .alpha-butt, +.cp-panel .HEX-butt, +.cp-panel .Lab-x-labl/*, +.cp-panel .alpha-labl*/ { /* ON */ + background-color: #444; + border-color: #222 #555 #555 #222; +} + +.no-rgb-r .rgb-r-labl, +.no-rgb-g .rgb-g-labl, +.no-rgb-b .rgb-b-labl, + +.mute-alpha .alpha-butt, +.no-HEX .HEX-butt, +.cmy-only .Lab-x-labl/*, +.alpha-bg .alpha-labl*/ { /* OFF */ + background-color: #333; + border-color: #555 #222 #222 #555; +} + +.Lab-x-disp, +.cmy-only .cmyk-k-disp, +.cmy-only .cmyk-k-butt { + visibility: hidden; +} +.cp-panel .HEX-disp { + background-image: none; +} + +.cp-panel .cp-disp { + float: left; + width: 50px; width: 48px; /* IE 7 */ + height: 16px; height: 14px; /* IE 7 */ + margin: 2px 2px 0; + cursor: text; + text-align: left; + text-indent: 3px; + border: 1px solid; + border-color: #222 #555 #555 #222; +} +.cp-app .cp-nsarrow { + position: absolute; + top: 0; + left: -13px; + width: 8px; + height: 16px; + background-position: -87px -23px; + display: none; +} +.cp-app .start-change .cp-nsarrow { + display: block; +} +.cp-app .do-change .cp-nsarrow { + display: block; + background-position: -87px -36px; +} +.do-change .cp-disp { + cursor: default; +} + +.cp-panel .cp-hide { + display: none; +} + +/* -------- controller color/contrast bars -------- */ + +.cp-panel .cp-cont, +.cp-panel .cp-cold { + position: absolute; + top: -5px; + left: 0; /* IE7 */ + height: 5px; height: 3px; /* IE7 */ + border: 1px solid #333; +} +.cp-panel .cp-cold { + background-color: #c00; + z-index: 1; +} +.cp-panel .cp-cont { + margin-right: -1px; + z-index: 2; +} +.cp-panel .contrast .cp-cont { + background-color: #ccc; + z-index: 1; +} +.cp-panel .orange .cp-cold { + background-color: #FF9900; +} +.cp-panel .green .cp-cold { + background-color: #44DD00; +} + +/* -------- controller buttons -------- */ + +.cp-panel .cp-ctrl { + position: absolute; + bottom: 0; + left: 0; + width: 100%; /* IE7 */ + /* overflow: visible; */ + background-color: #fff; +} + +.alpha-bg-b .cp-ctrl, +.cp-panel .cp-bres, +.cp-panel .cp-bsav { + background-color: #333; +} + +.cp-panel .cp-col1, +.cp-panel .cp-col2, +.cp-panel .cp-bres, +.cp-panel .cp-bsav { + border: 1px solid; + border-color: #555 #222 #222 #555; + float: left; + width: 47px; width: 46px; /* IE7 */ + line-height: 28px; + text-align: center; + top: 0; +} +.cp-panel div div { + height: 100%; /* IE7 */ +} +.S .cp-ctrl div { + line-height: 25px; +} +.S .cp-panel .cp-bres, +.S .cp-panel .cp-bsav { + line-height: 26px; +} + +/* -------- app controls -------- */ + +.cp-app .cp-exit, +.cp-app .cp-resize { + right: 3px; + top: 3px; + width: 15px; + height: 15px; + background-position: 0 -52px; +} +.cp-app .cp-resize { + top: auto; + bottom: 3px; + background-position: -15px -52px; + cursor: nwse-resize; +} + +.S .cp-exit { + background-position: 1px -52px; +} +.XS .cp-resize, +.XS .cp-exit { + width: 10px; + height: 10px; + right: 0; + background-image: none; +} +.XS .cp-exit { + top: 0; +} +.XS .cp-resize { + bottom: 0; +} + +.cp-app .cp-resizer, +.cp-app .cp-resizer div { + position: absolute; + border: 1px solid #888; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; + z-index: 2; /* overwrites: .cp-panel .cp-cont, .cp-panel .cp-cold */ + display: none; + cursor: nwse-resize; +} +.cp-app .cp-resizer div { + border: 1px dashed #333; + background-color: #bbb; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; + filter: alpha(opacity=30); + -moz-opacity: 0.3; + -khtml-opacity: 0.3; + opacity: .30; + display: block; +} \ No newline at end of file diff --git a/colorPicker.data.js b/colorPicker.data.js new file mode 100644 index 0000000..aedb35e --- /dev/null +++ b/colorPicker.data.js @@ -0,0 +1,30 @@ +;(function(window, undefined){ + "use strict" + + // see colorPicker.html for the following encrypted variables... will only be used in buildView() + var _html = ('^§app alpha-bg-w">^§slds">^§sldl-1">$^§sldl-2">$^§sldl-3">$^§curm">$^§sldr-1">$^§sldr-2">$^§sldr-4">$^§curl">$^§curr">$$^§opacity">|^§opacity-slider">$$$^§memo">^§raster">$^§raster-bg">$|$|$|$|$|$|$|$|$^§memo-store">$^§memo-cursor">$$^§panel">^§hsv">^hsl-mode §ß">$^hsv-h-ß §ß">H$^hsv-h-~ §~">-^§nsarrow">$$^hsl-h-@ §@">H$^hsv-s-ß §ß">S$^hsv-s-~ §~">-$^hsl-s-@ §@">S$^hsv-v-ß §ß">B$^hsv-v-~ §~">-$^hsl-l-@ §@">L$$^§hsl §hide">^hsv-mode §ß">$^hsl-h-ß §ß">H$^hsl-h-~ §~">-$^hsv-h-@ §@">H$^hsl-s-ß §ß">S$^hsl-s-~ §~">-$^hsv-s-@ §@">S$^hsl-l-ß §ß">L$^hsl-l-~ §~">-$^hsv-v-@ §@">B$$^§rgb">^rgb-r-ß §ß">R$^rgb-r-~ §~">-$^rgb-r-@ §ß"> $^rgb-g-ß §ß">G$^rgb-g-~ §~">-$^rgb-g-@ §ß"> $^rgb-b-ß §ß">B$^rgb-b-~ §~">-$^rgb-b-@ §ß"> $$^§cmyk">^Lab-mode §ß">$^cmyk-c-ß §@">C$^cmyk-c-~ §~">-$^Lab-L-@ §@">L$^cmyk-m-ß §@">M$^cmyk-m-~ §~">-$^Lab-a-@ §@">a$^cmyk-y-ß §@">Y$^cmyk-y-~ §~">-$^Lab-b-@ §@">b$^cmyk-k-ß §@">K$^cmyk-k-~ §~">-$^Lab-x-@ §ß"> $$^§Lab §hide">^cmyk-mode §ß">$^Lab-L-ß §@">L$^Lab-L-~ §~">-$^cmyk-c-@ §@">C$^Lab-a-ß §@">a$^Lab-a-~ §~">-$^cmyk-m-@ §@">M$^Lab-b-ß §@">b$^Lab-b-~ §~">-$^cmyk-y-@ §@">Y$^Lab-x-ß §@"> $^Lab-x-~ §~">-$^cmyk-k-@ §@">K$$^§alpha">^alpha-ß §ß">A$^alpha-~ §~">-$^alpha-@ §ß">W$$^§HEX">^HEX-ß §ß">#$^HEX-~ §~">-$^HEX-@ §ß">M$$^§ctrl">^§raster">$^§cont">$^§cold">$^§col1">| $$^§col2">| $$^§bres">RESET$^§bsav">SAVE$$$^§exit">$^§resize">$^§resizer">|$$$'). + replace(/\^/g, '
').\n\t" + + "replace(/~/g, 'disp').\n\t" + + "replace(/ß/g, 'butt').\n\t" + + "replace(/@/g, 'labl').\n\t" + + "replace(/\\|/g, '
')"; + + display.firstChild.data = html; + + + /* ------------ Compress CSS ------------ */ + var display = document.getElementById('displayCSS'), + css = document.getElementsByTagName('link')[1], + rules = css.sheet.rules, + path = css.href.split('/'), + CSS = [], + bgPosCSS = {}, + // CSSSplit = [], + reUnion = '', + txt = '', key = '', val = '', end = 0, start = 0; + + path.pop(); + path = path.join('/') + '/'; + + for (var n = 0, len = rules.length; n < len; n++) { + txt = rules[n].cssText; + if (/background-position/.test(txt)) { + // .hsl-l div.cp-sldl-1 {background-position: -256px 0} + end = txt.indexOf(' { '); + val = txt.substr(0, end); // good now + + start = txt.indexOf(' }'); + key = txt.substr(end + 24, start - end - 25); + + if (!bgPosCSS[key]) { + bgPosCSS[key] = [val]; + } else { + bgPosCSS[key].push(val); + } + } else { + CSS.push(txt.replace(new RegExp(path, 'g'), '')); + } + } + + for (var n in bgPosCSS) { + // console.log(bgPosCSS[n].join(',') + '{background-position:' + n + '}'); + CSS.push( + bgPosCSS[n].join(',') + '{background-position:' + n + '}' + ); + } + + css = CSS.join(''). // recycle css + replace(/cp-/g, '§'). + replace(/\: /g, ':'). + replace(/ \{ /g, '{'). + replace(/; \}/g, '}'). + replace(/, \./g, ',.'). + replace(/:0px /g, ':0 '). + replace(/ 0px\}/g, ' 0}'). + replace(/rgb\((\d+), (\d+), (\d+)\)/g, function($1, $2, $3, $4){ + var hex = ('#' + + ($2 < 16 ? '0' : '') + (+$2).toString(16) + + ($3 < 16 ? '0' : '') + (+$3).toString(16) + + ($4 < 16 ? '0' : '') + (+$4).toString(16) + ) + if ($2 === $3 && $3 === $4) { + hex = hex.substring(0, 4); + } else if (hex[1] === hex[2] && hex[3] === hex[4] && hex[5] === hex[6]) { + hex = '#' + hex[1] + hex[3] + hex[5]; + } + return hex; + }). + + replace(/ .\§sldl-/g, '^'). + replace(/ .\§sldr-/g, '?'). + replace(/ .no-rgb-/g, '~'). + + replace(/\.rgb-/g, 'ä'). + replace(/\.hsv-/g, 'ö'). + replace(/\.hsl-/g, 'ü'). + + replace(/background/g, '@'). + replace(/-position\:/g, '|'). + + replace(/,\.S /g, 'Ä'). + replace(/px}/g, 'Ö'). + replace(/\{@\|0 /g, 'Ü'); // !!! + + + reUnion = + "replace(/Ü/g, '{@|0 ').\n\t" + + "replace(/Ö/g, 'px}').\n\t" + + "replace(/Ä/g, ',.S ').\n\t" + + + "replace(/\\|/g, '-position:').\n\t" + + "replace(/@/g, 'background').\n\t" + + + "replace(/ü/g, '.hsl-').\n\t" + + "replace(/ö/g, '.hsv-').\n\t" + + "replace(/ä/g, '.rgb-').\n\t" + + + "replace(/~/g, ' .no-rgb-}').\n\t" + + "replace(/\\?/g, ' .§sldr-').\n\t" + + "replace(/\\^/g, ' .§sldl-')\n\t"; + + + // CSSSplit = css.split('.thisIsTheBreakPoint{}'); + // -------------- + // css = CSSSplit[0]; // first half + CSS = []; + + for (var n = 0, len = css.length; n < len; n += !n ? 92 : 100) { + CSS.push('\'' + css.substr(n, !n ? 92 : 100)); + } + var cssMain = "_cssFunc = (" + CSS.join("' +\n\t") + "').\n\t" + reUnion; + + // -------------- + // css = CSSSplit[1]; // second half + // CSS = []; + // for (var n = 0, len = css.length; n < len; n += !n ? 92 : 100) { + // CSS.push('\'' + css.substr(n, !n ? 92 : 100)); + // } + // cssMain += "\n\n\n_cssFunc = (" + CSS.join("' +\n\t") + "').\n\t" + reUnion; + + + + display.firstChild.data = cssMain; + + /* --------------------- MAIN CSS ---------------------------- */ + + var display = document.getElementById('displayCSS'), + css = document.getElementsByTagName('link')[0], + rules = css.sheet.rules, + path = css.href.split('/'), + CSS = [], + bgPosCSS = {}, + // CSSSplit = [], + reUnion = '', + txt = '', key = '', val = '', end = 0, start = 0; + + path.pop(); + path = path.join('/') + '/'; + + for (var n = 0, len = rules.length; n < len; n++) { + txt = rules[n].cssText; + CSS.push(txt.replace(new RegExp(path, 'g'), '')); + } + + + css = CSS.join(''). // recycle css + replace(/cp-/g, '§'). + replace(/\: /g, ':'). + replace(/ \{ /g, '{'). + replace(/; /g, ';'). + replace(/;\}/g, '}'). + replace(/, \./g, ',.'). + replace(/:0px /g, ':0 '). + replace(/ 0px\}/g, ' 0}'). + replace(/rgb\((\d+), (\d+), (\d+)\)/g, function($1, $2, $3, $4){ + var hex = ('#' + + ($2 < 16 ? '0' : '') + (+$2).toString(16) + + ($3 < 16 ? '0' : '') + (+$3).toString(16) + + ($4 < 16 ? '0' : '') + (+$4).toString(16) + ) + if ($2 === $3 && $3 === $4) { + hex = hex.substring(0, 4); + } else if (hex[1] === hex[2] && hex[3] === hex[4] && hex[5] === hex[6]) { + hex = '#' + hex[1] + hex[3] + hex[5]; + } + return hex; + }). + + replace(/\.§sld/g, '^'). + replace(/border\-/g, '?'). + replace(/width\:/g, '~'). + replace(/transparent/g, '†'). + replace(/\.§memo/g, 'ø'). + + replace(/height\:/g, 'ä'). + replace(/background\-/g, 'ö'). + // replace(/position\:/g, 'ü'). + + replace(/color\:/g, '@'). + replace(/position\:/g, '|'). + replace(/px\;/g, '¥'). + replace(/\.§panel \./g, '«'). + replace(/\.§app/g, '∑'). + + //replace(/color\:/g, 'Ä'). + replace(/left\}/g, 'Ö'). + replace(/right/g, 'Ü'); // !!! + + // /.§slds/ 24 + // /border-/ 33 + // /width:/ 36 + // /height:/ 29 + // /background-/ 33 + // /position:/ 28 + // /color-/ 31 + // /left/ 25 + // /right/ 14 + // /px;/ 108 + // /.§panel ./ 45 + // /.§app/ 27 .§memo + + reUnion = + "replace(/Ü/g, 'right').\n\t" + + "replace(/Ö/g, 'left}').\n\t" + + //"replace(/Ä/g, ',color:').\n\t" + + + "replace(/∑/g, '.§app').\n\t" + + "replace(/«/g, '.§panel .').\n\t" + + "replace(/¥/g, 'px;').\n\t" + + "replace(/\\|/g, 'position:').\n\t" + + "replace(/@/g, 'color:').\n\t" + + + // "replace(/ü/g, 'position:').\n\t" + + "replace(/ö/g, 'background-').\n\t" + + "replace(/ä/g, 'height:').\n\t" + + + "replace(/ø/g, '.§memo').\n\t" + + "replace(/†/g, 'transparent').\n\t" + + "replace(/\\~/g, 'width:').\n\t" + + "replace(/\\?/g, 'border-').\n\t" + + "replace(/\\^/g, '.§sld')\n\t"; + + + // CSSSplit = css.split('.thisIsTheBreakPoint{}'); + // -------------- + // css = CSSSplit[0]; // first half + CSS = []; + + for (var n = 0, len = css.length; n < len; n += !n ? 92 : 100) { + CSS.push('\'' + css.substr(n, !n ? 92 : 100)); + } + cssMain = "\n\n_cssMain = (" + CSS.join("' +\n\t") + "').\n\t" + reUnion; + + + display.firstChild.data += cssMain; + + + /* ------------ Compress images to BASE64 ------------ */ + // var canvas = document.createElement('canvas'), + // ctx = canvas.getContext('2d'), + // myimage = new Image(), + // IMG64 = '', + // images = ['_horizontal.png', '_vertical.png', '_patches.png'], + // counter = 0, + // encode = function(callback) { + // var IMG = []; + + // canvas.width = myimage.width; + // canvas.height = myimage.height; + + // ctx.drawImage(myimage, 0, 0); + // IMG64 = canvas.toDataURL("image/png"), + // imgName = images[counter]; + + // for (var n = 0, len = IMG64.length; n < len; n += !n ? 100 - imgName.length + 2 : 100) { + // IMG.push('\'' + IMG64.substr(n, !n ? 100 - imgName.length + 2 : 100)); + // } + // IMG = IMG.join("' +\n\t") + "'"; + // // display.firstChild.data += "\n\n\n" + imgName.replace('.p', 'P') + ' = ' + IMG; + // if (images[++counter]) { + // myimage.src = images[counter]; + // } + // }; + + // myimage.onload = function() { + // encode(); + // }; + // myimage.src = images[counter]; + + + /* + BASE64 conversion via canvas turns out to be bigger than expected.. + had to upload them via http://webcodertools.com/imagetobase64converter/ + */ + var images = { + '_horizontalPng' : 'iVBORw0KGgoAAAANSUhEUgAABIAAAAABCAYAAACmC9U0AAABT0lEQVR4Xu2S3Y6CMBCFhyqIsjGBO1/B9/F5DC/pK3DHhVkUgc7Zqus2DVlGU/cnQZKTjznttNPJBABA149HyRf1iN//4mIBCg0jV4In+j9xJiuihly1V/Z9X88v//kNeDXVvyO/lK+IPR76B019+1Riab3H1zkmeqerKnL+Bzwxx6PAgZxaSQU8vB62T28pxcQeRQ2sHw6GxCOWHvP78zwHAARBABOfdYtd30rwxXOEPDF+dj2+91r6vV/id3k+/brrXmaGUkqKhX3i+ffSt16HQ/dorTGZTHrs7ev7Tl7XdZhOpzc651nfsm1bRFF0YRiGaJoGs9nsQuN/xafTCXEco65rzOdzHI9HJEmCqqqwXC6x3++RZRnKssRqtUJRFFiv19jtdthutyAi5Hl+Jo9VZg7+7f3yXuvZf5c3KaXYzByb+WIzO5ymKW82G/0BNcFhO/tOuuMAAAAASUVORK5CYII=', + '_verticalPng' : 'iVBORw0KGgoAAAANSUhEUgAAAAEAABfACAYAAABn2KvYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABHtJREFUeNrtnN9SqzAQxpOF1to6zuiVvoI+j6/gva/lA/kKeqUzjtX+QTi7SzSYBg49xdIzfL34+e1usoQQklCnmLwoCjImNwDQA2xRGMqNAYB+gPEH9IdCgIUA6Aem0P1fLoMQAPYNHYDoCKAv8OMHFgKgX2AjDPQDXn4t1l+gt/1fId//yWgE/hUJ+mAn8EyY5wCwXxhrbaHzn8E9iPlv79DdHxXTqciZ4KROnXRVZMF/6U2OPhcEavtAbZH1SM7wRDD7VoHZItCiyEQf4t6+MW9UOxaZybmdCGKqNrB9Eb5SfMg3wTyiagMtigTmWofiSDCOYNTSNz6sLDIoaCU9GWDd0tdhoMMsRm+r8U/EfB0GfjmLXiqzimDd0tdhoLMsI7la45+I+ToM/HIW0kfGVQTrlr7tA91kaUr//fxrKo8jUFB7VAn6AKpHJf+EKwAAAIYD/f7F7/8MVgMo7P+gBqDKr57Lf72V8x8AAMDgYIuvH4EAAAAMDQX6AACAQcI9GGMjDADA4MA/P2KlP8IEAAAYFCz6AACAgaLA8y8AAIN+CMYXoQAADA7u/UPYCAMAMDjI7z9S+SdwDFQX2C9Gh9GMEOWriz8/Pw1lWQZsi/L3R4czzP678Ve+P8f9nCv/C7hwLq99ah8NfKrU15zPB5pVcwtiJt9qGy0IfEE+jQa+Fn0VtI/fkxUPqBlEfRENeF+tqUpbGpi1iu8epwJzvV5XA4GpWC6XGz7F+/u766EgwJ+ckiTJKU3TnI6OjnI6OzvLZf6zMggt3dzckPhIoiTlSGpQ+eEsVegdz0fbCCi4fRs+Po+4yWdeDXiT+6pBSTeHple1pkz3FZ+avpyavoiPxgLN0B7yprY08PlyQTTm0+PWmkH7ynedNKraar4F/lRj1WpTtYh+ozL/cY2sAvZl0gcbZm0gSLBLvkxGoaogiy/HDXemQk2t5pUm8OAhH8/HH6e0mkJ9q9XKKQXfb07xfZnJbZrRxcVFVt6/t7e3Kc1ms5RGo1Eq5VIZuyl9fHw4k/M5xYeoKj64A7eqCt1ZeqWFVSl8NV9OTV3fmvP5qE9VmzSoEcsXpArK1UHen/hZbgL53BZSdyEXalGau/hU8TEW0u3VcoFPy3EDFrTgT+njydeZ0+l0UV7fu7u7iVzziQQmUm4iqRw4n/NxMxw4s/Mp1NSALxf4NEtQ10cjMDwSl+b+/j6hp6enVGb+jUvrn05iKobm6PboOt8vPISY5Pr6OqGXlxe3fOokoGtAbMUJZmqvYmaLQDP+sdrecOjtO/SXeH69P8Imutm5urqy9PDwYOny8tLS4+OjpfPzc0vPz8+WTk9PLb2+vlpZbCzN53NLx8fHVtYZS5PJxMoEZWWqsjKULY3HYytTi1Pex5OMldXKRVXxuLcy/20onmms3BBOxcr5qCrZtsrd45SPel8sGlOxGoGy0neynQ6VL9fsa1YtWlCrtj9G83G7PjdVush5n5q1iJWLZW6u21a1bUvbVnVzlru0pe3RdmlV1/23fZtbZv4Dx+7FBypx77kAAAAASUVORK5CYII=', + '_patchesPng' : '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', + '_iconsPng' : 'iVBORw0KGgoAAAANSUhEUgAAAGEAAABDCAMAAAC7vJusAAAAkFBMVEUAAAAvLy9ERERubm7///8AAAD///9EREREREREREREREQAAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8cHBwkJCQnJycoKCgpKSkqKiouLi4vLy8/Pz9AQEBCQkJDQ0NdXV1ubm58fHykpKRERERVVVUzMzPx7Ab+AAAAHXRSTlMAAAAAAAQEBQ4QGR4eIyMtLUVFVVVqapKSnJy7u9JKTggAAAFUSURBVHja7dXbUoMwEAbgSICqLYeW88F6KIogqe//dpoYZ0W4AXbv8g9TwkxmvtndZMrEwlw/F8YIRjCCEYxgBCOsFmzqGMEI28J5zzmt0Pc9rdDL0NYgMxIYC5KiKpKAzZphWtZlGm4SjlnkOV6UHeeEUx77rh/npw1dCrI9k9lnwUwF+UG9D3m4ftJJxH4SJdPtaawXcbr+tBaeFrxiur309cIv19+4ytGCU0031a5euPVigLYGqjlAqM4ShOQ+QAYQUO80AMMAAkUGGfMfR9Ul+kmvPq2QGxXKOQBAKdjUgk0t2NiCGEVP+rHT3/iCUMBT90YrPMsKsIWP3x/VolaonJEETchHCS8AYAmaUICQQwaAQnjoXgHAES7jLkEFaHO4bdq/k25HAIpgWY34FwAE5xjCffM+D2DV8B0gRsAZT7hr5gE8wdrJcU+CJqhcqQD7Cx5L7Ph4WnrKAAAAAElFTkSuQmCC', + '_bgsPng' : 'iVBORw0KGgoAAAANSUhEUgAAASAAAABvCAYAAABM+h2NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABORJREFUeNrs3VtTW1UYBuCEcxAI4YydWqTWdqr1V7T/2QsvvPDCCy9qjxZbamsrhZIQUHsCEtfafpmJe8qFjpUxfZ4Zuvt2feydJvAOARZUut1u5bRerl692nV913f99/f6QxWAU6KAAAUEKCAABQQoIAAFBCggAAUEKCAABQQoIAAFBCggAAUEKCAABQQoIEABASggQAEBKCBAAQEoIEABASggQAEBKCBAAQEoIGBQC+jatWvd07zxrv9+Xx8fAQEoIEABASggQAEBKCBAAQEoIEABAQoIQAEBCghAAQEKCEABAQOk2u36kS6AAgLetwJKL29toFRM1be+QrVq3rx58//KvM8BAadGAQEKCFBAAAoIGHwnfhneZ+/Nmzf/LufzrI+AAE/BAAUEoIAABQTwztgLZt68eXvBAE/BABQQoIAAFBAweOwFM2/evL1ggKdgAAoIUEAACggYPPaCmTdv3l4wwFMwAAUEKCAABQQMHnvBzJs3by8Y4CkYgAICFBCAAgIGz4lfBQNQQMDgFlCtVisaaHV1tThubW1VInciD0U+ysdnz54N5+PKysphOnRTHsvHlN9EHo/1l5FrkV9Enoz8W87b29tTOS8vLx9EnoncjlyPvBe5EbkZeT4fU96NvBDr2znv7Ows57y0tLQVeSXy08gf5mNfPhPrjyOfrVarlcXFxZ9yfv78+bl8TPlh5LU8n/KDyOuxfj/y+VjfyHl3d/dCKv28fi/yp/m4sLDwQ+SLke9GvhT5Tinfjnw5f4/F/Pz8rZybzeZn+ZjyzVK+EfnzUr4S+Xopf9/L+fxzc3M5d1qt1hf531Mu5k/IxzGf85VYL+fefHH+RqNRrO/t7RW3L+UbkS9Hvhk5/386Kd/qW8/5duRLMV/OdyJfzNebnZ0t7t92u53v/07K9yJfiLwROT9+ef7HyOux/iDyWuSHkT+K+eLtZX9//2xer9frjyOfyY9/Wn8S86v59qT1p7Ge315zLt4RU16K19+O9YXIu5HnYn435hux3opcj9yOPB3z+5E/iPXf43y1yMX778HBQS3f3pTz+28l5bHIr2N+LN3+zszMzGHkoh/S+mHMF98XlNaP8zHd/0W/pMe943NAwKlSQIACAhQQgAICFBCAAgIUEIACAhQQgAIC/n9GqtXqYbfbHa38+RtSu32llPdqdNL6aOSj+LfxyMVekLTem39Ryr/mPDQ0NBznzXtROikPRW6W8k7k3m9rzXthOsPDw73bUuylGRkZ6cR63nvTSfko8oPIr+Pnz96P/DLW816ezujoaN6DdtyX9+P8eS9QZ2xs7Hxf7qa8Xlr/JO6Ljcjrcf6cj1P+OO+N6V1/fHz8XLz+/Tjfubh+sZcorZ+N9Ycxfybyo8ircf6fc56YmFiJ1/8l8mLk7cjzkfP92U15Ns63G+u9nPcKdWq12lQ8Xu3Ixd6f9Pd8P3UmJycnUszzL2N9LM7/anNzs9V7Q2q32395w/q7ubdH6L/KrVbrpPxlKX9Vyl+X8jel/G0pf5f/aDabvXy9tH6ztH63lDdKebOUH5Xyk1LeKuWd/ry2tlap9P125Onp6Zf9eWpq6lW3b8f6zMzM6/71er3+ppSP+u/XNN/pz41Go+sjIMBTMEABASggQAEBKCBAAQEoIEABASggQAEB/CN/CDAAw78uW9AVDw4AAAAASUVORK5CYII=', + }, + IMG = [], + IMG64 = ''; + //AAAAAA + + for (var m in images) { + IMG64 = images[m]; + var IMG = [], + isPatch = m === '_patchesPng'; + + if (isPatch) { + IMG64 = IMG64.replace(/AAAAAA/g, '§').replace(/AAAA/g, '^').replace(/AAA/g, '#'); + } + for (var n = 0, len = IMG64.length; n < len; n += !n ? 100 - m.length + (isPatch ? 0 : 1) : 100) { + IMG.push('\'' + IMG64.substr(n, !n ? 100 - m.length + (isPatch ? 0 : 1) : 100)); + } + + IMG = (isPatch ? '(' : '') + IMG.join("' +\n\t") + "'"; + display.firstChild.data += "\n\n\n" + m + ' = ' + IMG + (isPatch ? ')' : '') + + (isPatch ? ".\n\treplace(/§/g, 'AAAAAA').replace(/\\^/g, 'AAAA').replace(/#/g, 'AAA')" : ''); + } + + + /* + var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" + function encode64(input) { + input = escape(input) + var output = "" + var chr1, chr2, chr3 = "" + var enc1, enc2, enc3, enc4 = "" + var i = 0 + do { + chr1 = input.charCodeAt(i++) + chr2 = input.charCodeAt(i++) + chr3 = input.charCodeAt(i++) + enc1 = chr1 >> 2 + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4) + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6) + enc4 = chr3 & 63 + if (isNaN(chr2)) { + enc3 = enc4 = 64 + } else if (isNaN(chr3)) { + enc4 = 64 + } + output = output + + keyStr.charAt(enc1) + + keyStr.charAt(enc2) + + keyStr.charAt(enc3) + + keyStr.charAt(enc4) + chr1 = chr2 = chr3 = "" + enc1 = enc2 = enc3 = enc4 = "" + } while(i < input.length) + return output + } + function decode64(input) { + var output = "" + var chr1, chr2, chr3 = "" + var enc1, enc2, enc3, enc4 = "" + var i = 0 + // remove all characters that are not A-Z, a-z, 0-9, +, /, or = + var base64test = /[^A-Za-z0-9\+\/\=]/g + if (base64test.exec(input)) { + alert("There were invalid base64 characters in the input text.\n" + + "Valid base64 characters are A-Z, a-z, 0-9, '+', '/', and '='\n" + + "Expect errors in decoding.") + } + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "") + do { + enc1 = keyStr.indexOf(input.charAt(i++)) + enc2 = keyStr.indexOf(input.charAt(i++)) + enc3 = keyStr.indexOf(input.charAt(i++)) + enc4 = keyStr.indexOf(input.charAt(i++)) + chr1 = (enc1 << 2) | (enc2 >> 4) + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2) + chr3 = ((enc3 & 3) << 6) | enc4 + output = output + String.fromCharCode(chr1) + if (enc3 != 64) { + output = output + String.fromCharCode(chr2) + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3) + } + chr1 = chr2 = chr3 = "" + enc1 = enc2 = enc3 = enc4 = "" + } while (i < input.length) + return unescape(output) + } + */ + +})(window); \ No newline at end of file diff --git a/colorPicker.html b/colorPicker.html new file mode 100644 index 0000000..be6d5d2 --- /dev/null +++ b/colorPicker.html @@ -0,0 +1,194 @@ + + + + + + + + +colorPicker markup + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
H
+
-
+
H
+
S
+
-
+
S
+
B
+
-
+
L
+
+
+
+
H
+
-
+
H
+
S
+
-
+
S
+
L
+
-
+
B
+
+
+
R
+
-
+
 
+
G
+
-
+
 
+
B
+
-
+
 
+
+
+
+
C
+
-
+
L
+
M
+
-
+
a
+
Y
+
-
+
b
+
K
+
-
+
 
+
+
+
+
L
+
-
+
C
+
a
+
-
+
M
+
b
+
-
+
Y
+
 
+
-
+
K
+
+
+
A
+
-
+
W
+
+
+
#
+
-
+
M
+
+
+
+
+
+
+
 
+
+
+
 
+
+
RESET
+
SAVE
+
+
+
+
+
+
+ + + +
 
+
 
+ + + + + + + + + \ No newline at end of file diff --git a/colorPicker.js b/colorPicker.js new file mode 100644 index 0000000..c50d536 --- /dev/null +++ b/colorPicker.js @@ -0,0 +1,1314 @@ +;(function(window, undefined){ + "use strict" + + var _data = window.ColorPicker, // will be deleted in buildView() and holds: + // window.ColorPicker = { // comes from colorPicker.data.js and will be overwritten. + // _html: ..., // holds the HTML markup of colorPicker + // _cssFunc: ..., // CSS for all the sliders + // _cssMain: ..., // CSS of the GUI + // _horizontalPng: ..., // horizontal background images for sliders + // _verticalPng: ..., // vertical background images for sliders + // _patchesPng: ..., // background images for square sliders in RGB mode + // _iconsPng: ..., // some icon sprite images + // _bgsPng: ..., // some more icon sprite images + // _blankPng: ... // the blank 16x16px image for the transparent cursor + // } + _devMode = !_data, // if no _data we assume that colorPicker.data.js is missing (for development) + _isIE = document.createStyleSheet !== undefined && document.getElementById, + // _isIE8 = _isIE && document.querySelectorAll, + + _valueRanges = {}, // will be assigned in initInstance() by Colors instance + // _valueRanges = { + // rgb: {r: [0, 255], g: [0, 255], b: [0, 255]}, + // hsv: {h: [0, 360], s: [0, 100], v: [0, 100]}, + // hsl: {h: [0, 360], s: [0, 100], l: [0, 100]}, + // cmyk: {c: [0, 100], m: [0, 100], y: [0, 100], k: [0, 100]}, + // cmy: {c: [0, 100], m: [0, 100], y: [0, 100]}, + // XYZ: {X: [0, 100], Y: [0, 100], Z: [0, 100]}, + // Lab: {L: [0, 100], a: [-128, 127], b: [-128, 127]}, + // alpha: {alpha: [0, 1]}, + // HEX: {HEX: [0, 16777215]} + // }, + _bgTypes = {w: 'White', b: 'Black', c: 'Custom'}, + + _mouseMoveAction, // current mouseMove handler assigned on mouseDown + _mainTarget, // target on mouseDown, might be parent element though... + _valueType, // check this variable; gets missused/polutet over time + _delayState = 1, // mouseMove offset (y-axis) in display elements // same here... + _startCoords = {}, + _targetOrigin = {}, + _renderTimer, // animationFrame/interval variable + _newData = true, + _txt = { + selection: document.selection || window.getSelection(), + range: (document.createRange ? document.createRange() : document.body.createTextRange()) + }, + + _renderVars = {}, // used only in renderAll and convertColors + _cashedVars = {}, // reset in initSliders + + _colorPicker, + _previousInstance, // only used for recycling purposes in buildView() + _colorInstance = {}, + _colors = {}, + _options = {}, + _nodes = {}, + + animationFrame = 'AnimationFrame', // we also need this later + requestAnimationFrame = 'request' + animationFrame, + cancelAnimationFrame = 'cancel' + animationFrame, + vendors = ['ms', 'moz', 'webkit', 'o'], + + ColorPicker = function(options) { // as tiny as possible... + this.options = { + color: 'rgba(204, 82, 37, 0.8)', + mode: 'rgb-b', + fps: 60, // 1000 / 60 = ~16.7ms + delayOffset: 8, + CSSPrefix: 'cp-', + scale: 1, + allMixDetails: true, + alphaBG: 'w' + // noAlpha: true, + // customBG: '#808080' + // size: 0, + // cmyOnly: false, + + // memoryColors: [{r: 100, g: 200, b: 10}]// , a: 0.5 + + // opacityPositionRelative: undefined, + // customCSS: undefined, + // appenTo: document.body, + // noRangeBackground: false, + // textRight: false, ????? + // noHexButton: false, + // noResize: false, + + // noRGBr: false, + // noRGBg: false, + // noRGBb: false, + + // CSSStrength: 'div.', + // XYZMatrix: XYZMatrix, + // XYZReference: {}, + // grey: grey, + // luminance: luminance, + + // renderCallback: undefined, + // actionCallback: undefined, + // convertCallback: undefined, + }; + initInstance(this, options || {}); + }; + + window.ColorPicker = ColorPicker; // export differently + ColorPicker.addEvent = addEvent; + ColorPicker.removeEvent = removeEvent; + ColorPicker.getOrigin = getOrigin; + ColorPicker.limitValue = limitValue; + ColorPicker.changeClass = changeClass; + + // ------------------------------------------------------ // + + ColorPicker.prototype.setColor = function(newCol, type, alpha, forceRender) { + focusInstance(this); + _valueType = true; // right cursor... + // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers + preRenderAll(_colorInstance.setColor.apply(_colorInstance, arguments)); + if (forceRender) { + this.startRender(true); + } + } + + ColorPicker.prototype.saveAsBackground = function() { + focusInstance(this); + return saveAsBackground(); + }; + + Colors.prototype.setCustomBackground = function(col) { + focusInstance(this); // needed??? + return _colorInstance.setCustomBackground(col); + }; + + ColorPicker.prototype.startRender = function(oneTime) { + focusInstance(this); + if (oneTime) { + _mouseMoveAction = false; // prevents window[requestAnimationFrame] in renderAll() + renderAll(); + this.stopRender(); + } else { + _mouseMoveAction = 1; + _renderTimer = window[requestAnimationFrame](renderAll); + } + }; + + ColorPicker.prototype.stopRender = function() { + focusInstance(this); // check again + window[cancelAnimationFrame](_renderTimer); + if (_valueType) { + // renderAll(); + _mouseMoveAction = 1; + stopChange(undefined, 'external'); + // _valueType = undefined; + } + }; + + ColorPicker.prototype.setMode = function(mode) { // check again ... right cursor + focusInstance(this); + setMode(mode); + initSliders(); + renderAll(); + }; + + ColorPicker.prototype.destroyAll = function() { // check this again... + var html = this.nodes.colorPicker, + destroyReferences = function(nodes) { + for (var n in nodes) { + if (nodes[n] && nodes[n].toString() === '[object Object]' || nodes[n] instanceof Array) { + destroyReferences(nodes[n]); + } + nodes[n] = null; + delete nodes[n]; + }; + }; + + this.stopRender(); + installEventListeners(this, true); + destroyReferences(this); + html.parentNode.removeChild(html); + html = null; + }; + + // ------------------------------------------------------ // + + function initInstance(THIS, options) { + var exporter, // do something here.. + memory, + mode = '', + CSSPrefix = '', + optionButtons; + + for (var option in options) { // deep copy ?? + THIS.options[option] = options[option]; + } + _colorInstance = new Colors(THIS.options); + // We transfer the responsibility to the instance of Color (to save space and memory) + delete THIS.options; + _options = _colorInstance.options; + CSSPrefix = _options.CSSPrefix; + + THIS.color = _colorInstance; // check this again... + _valueRanges = _options.valueRanges; + THIS.nodes = _nodes = getInstanceNodes(buildView(THIS), THIS); // ha, ha,... make this different + setMode(_options.mode); + focusInstance(THIS); + saveAsBackground(); + + mode = ' ' + _options.mode.type + '-' + _options.mode.z; + _nodes.slds.className += mode; + _nodes.panel.className += mode; + //_nodes.colorPicker.className += ' cmy-' + _options.cmyOnly; + + if (_options.noHexButton) { + changeClass(_nodes.HEX_butt, CSSPrefix + 'butt', CSSPrefix + 'labl') + } + + if (_options.size !== undefined) { + resizeApp (undefined, _options.size); + } + + optionButtons = { + alphaBG: _nodes.alpha_labl, + cmyOnly: _nodes.HEX_labl // test... take out + } + for (var n in optionButtons) { + if (_options[n] !== undefined) { + buttonActions({target: optionButtons[n], data: _options[n]}); + } + } + if (_options.noAlpha) { + _nodes.colorPicker.className += ' no-alpha'; // IE6 ??? maybe for IE6 on document.body + } + + memory = _options.memoryColors; + for (var n = _nodes.memos.length; n--; ) { // check again how to handle alpha... + _nodes.memos[n].style.cssText = 'background-color: ' + (memory && memory[n] !== undefined ? + color2string(memory[n]) + ';' + getOpacityCSS(memory[n]['a'] || 1) : 'rgb(0,0,0);'); + } + + installEventListeners(THIS); + + _mouseMoveAction = true; + stopChange(undefined, 'init'); + + if (_previousInstance) { + focusInstance(_previousInstance); + renderAll(); + } + } + + function focusInstance(THIS) { + _newData = true; + if (_colorPicker !== THIS) { + _colorPicker = THIS; + _colors = THIS.color.colors; + _options = THIS.color.options; + _nodes = THIS.nodes; + _colorInstance = THIS.color; + + _cashedVars = {}; + preRenderAll(_colors); + } + } + + function getUISizes() { + var sizes = ['L', 'S', 'XS', 'XXS']; + _options.sizes = {}; + _nodes.testNode.style.cssText = 'position:absolute;left:-1000px;top:-1000px;'; + document.body.appendChild(_nodes.testNode); + for (var n = sizes.length; n--; ) { + _nodes.testNode.className = _options.CSSPrefix + 'app ' + sizes[n]; + _options.sizes[sizes[n]] = [_nodes.testNode.offsetWidth, _nodes.testNode.offsetHeight]; + } + if (_nodes.testNode.removeNode) { // old IEs + _nodes.testNode.removeNode(true); + } else { + document.body.removeChild(_nodes.testNode); + } + } + + function buildView(THIS) { + var app = document.createElement('div'), + style, + prefix = _options.CSSPrefix, + urlData = 'data:image/png;base64,'; + + // development mode + if (_devMode) { + return THIS.color.options.devPicker; + } + + // HTML + if (_previousInstance = _colorPicker) { + // we need to be careful with recycling HTML as slider calssNames might have been changed... + initSliders(); + } + app.innerHTML = _colorPicker ? _colorPicker.nodes.colorPicker.outerHTML : _data._html.replace(/§/g, prefix); + // _html = null; + + // CSS + if (!document.getElementById('colorPickerCSS')) { // only once needed + // CSS - system + style = document.createElement('style'); + style.setAttribute('type', 'text/css'); + style.setAttribute('id', 'colorPickerCSS'); + + _data._cssFunc = _data._cssFunc. + replace(/§/g, prefix). + replace('_patches.png', !_isIE ? urlData + _data._patchesPng : '_patches.png'). + replace('_vertical.png', !_isIE ? urlData + _data._verticalPng : '_vertical.png'). + replace('_horizontal.png', !_isIE ? urlData + _data._horizontalPng : '_horizontal.png'); + if (!style.styleSheet) { + style.appendChild(document.createTextNode(_data._cssFunc)); + } + document.getElementsByTagName('head')[0].appendChild(style); + if (style.styleSheet) { // IE compatible + document.styleSheets[document.styleSheets.length-1].cssText = _data._cssFunc; + } + + // CSS - main + if (!_options.customCSS) { + style = document.createElement('style'); + style.setAttribute('type', 'text/css'); + _data._cssMain = _data._cssMain. + replace(/§/g, prefix). + replace('_bgs.png', !_isIE ? urlData + _data._bgsPng : '_bgs.png'). + replace('_icons.png', !_isIE ? urlData + _data._iconsPng : '_icons.png'). + replace('_blank.png', !_isIE ? urlData + _data._blankPng : '_blank.cur'). + replace('"Courier New",', !_isIE ? '' : '"Courier New",'); + // style.appendChild(document.createTextNode(_data._cssFunc)); + if (!style.styleSheet) { + style.appendChild(document.createTextNode(_data._cssMain)); + } + document.getElementsByTagName('head')[0].appendChild(style); + if (style.styleSheet) { // IE compatible + document.styleSheets[document.styleSheets.length-1].cssText = _data._cssMain; + } + } + for (var n in _data) { // almost 25k of memory ;o) + _data[n] = null; + } + } + + return (_options.appenTo || document.body).appendChild(app.children[0]); + } + + function getInstanceNodes(colorPicker, THIS) { // check nodes again... are they all needed? + var all = colorPicker.getElementsByTagName('*'), + nodes = {colorPicker: colorPicker}, // length ?? // rename nodes.colorPicker + node, + className, + memoCounter = 0, + regexp = new RegExp(_options.CSSPrefix); + + // nodes.displayStyles = {}; // not needed ... or change to CSS + nodes.styles = {}; + // nodes.styles.displays = {}; + + nodes.textNodes = {}; + nodes.memos = []; + nodes.testNode = document.createElement('div'); + + for (var n = 0, m = all.length; n < m; n++) { + node = all[n]; + if ((className = node.className) && regexp.test(className)) { + className = className.split(' ')[0].replace(_options.CSSPrefix, '').replace(/-/g, '_'); + if (/_disp/.test(className)) { + className = className.replace('_disp', ''); + // nodes.styles.displays[className] = node.style; + nodes.styles[className] = node.style; + nodes.textNodes[className] = node.firstChild; + node.contentEditable = true; // does this slow down rendering?? + } else { + if (!(/(?:hs|cmyk|Lab).*?(?:butt|labl)/.test(className))) { + nodes[className] = node; + } + if (/(?:cur|sld[^s]|opacity|cont|col)/.test(className)) { + nodes.styles[className] = /(?:col\d)/.test(className) ? node.children[0].style : node.style; + } + } + } else if (/memo/.test(node.parentNode.className)) { + nodes.memos.push(node); + } + } + + return nodes; + } + + // ------------------------------------------------------ // + // ---- Add event listners to colorPicker and window ---- // + // -------------------------------------------------------// + + function installEventListeners(THIS, off) { + var onOffEvent = off ? removeEvent : addEvent; + + onOffEvent(_nodes.colorPicker, 'mousedown', function(e) { + var event = e || window.event, + page = getPageXY(event), + target = event.target || event.srcElement, + className = target.className; + + focusInstance(THIS); + _mainTarget = target; + stopChange(undefined, 'resetEventListener'); + + if (target == _nodes.sldl_3 || target == _nodes.curm) { + _mainTarget = _nodes.sldl_3; + _mouseMoveAction = changeXYValue; + changeClass(_nodes.slds, 'do-drag'); + } else if (/sldr/.test(className) || target == _nodes.curl || target == _nodes.curr) { + _mainTarget = _nodes.sldr_4; + _mouseMoveAction = changeZValue; + } else if (target == _nodes.opacity.children[0] || target == _nodes.opacity_slider) { + _mainTarget = _nodes.opacity; + _mouseMoveAction = changeOpacityValue; + } else if (/-disp/.test(className) && !/HEX-/.test(className)) { + _mouseMoveAction = changeInputValue; + (target.nextSibling.nodeType === 3 ? target.nextSibling.nextSibling : target.nextSibling). + appendChild(_nodes.nsarrow); // nextSibling for better text selection + _valueType = className.split('-disp')[0].split('-'); + _valueType = {type: _valueType[0], z: _valueType[1] || ''}; + changeClass(_nodes.panel, 'start-change'); + _delayState = 0; + } else if (target == _nodes.resize && !_options.noResize) { + if (!_options.sizes) { + getUISizes(); + } + _mainTarget = _nodes.resizer; + _mouseMoveAction = resizeApp; + } else { + _mouseMoveAction = undefined; + } + + if (_mouseMoveAction) { + _startCoords = {pageX: page.X, pageY: page.Y}; + _mainTarget.style.display = 'block'; + _targetOrigin = getOrigin(_mainTarget); + _targetOrigin.width = _nodes.opacity.offsetWidth; // ??????? + _targetOrigin.childWidth = _nodes.opacity_slider.offsetWidth; // ??????? + _mouseMoveAction(event); + addEvent(_isIE ? document.body : window, 'mousemove', _mouseMoveAction); + _renderTimer = window[requestAnimationFrame](renderAll); + } else { + // console.log(className) + // console.log(THIS.nodes[className.split(' ')[0].replace('cp-', '').replace('-', '_')]) + // resize, button states, etc... + } + + // if (_mouseMoveAction !== changeInputValue) preventDefault(event); + if (!/-disp/.test(className)) { + return preventDefault(event); + // document.activeElement.blur(); + } + }); + + onOffEvent(_nodes.colorPicker, 'click', function(e) { + focusInstance(THIS); + buttonActions(e); + }); + + onOffEvent(_nodes.colorPicker, 'dblclick', buttonActions); + + onOffEvent(_nodes.colorPicker, 'keydown', function(e) { + focusInstance(THIS); + keyControl(e); + }); + + // keydown is before keypress and focuses already + onOffEvent(_nodes.colorPicker, 'keypress', keyControl); + // onOffEvent(_nodes.colorPicker, 'keyup', keyControl); + + onOffEvent(_nodes.colorPicker, 'paste', function(e) { + e.target.firstChild.data = e.clipboardData.getData('Text'); + return preventDefault(event); + }); + } + + addEvent(_isIE ? document.body : window, 'mouseup', stopChange); + + // ------------------------------------------------------ // + // --------- Event listner's callback functions -------- // + // -------------------------------------------------------// + + function stopChange(e, action) { + var mouseMoveAction = _mouseMoveAction; + + if (_mouseMoveAction) { // why??? please test again... + // if (document.selection && _mouseMoveAction !== changeInputValue) { + // //ie -> prevent showing the accelerator menu + // document.selection.empty(); + // } + window[cancelAnimationFrame](_renderTimer); + removeEvent(_isIE ? document.body : window, 'mousemove', _mouseMoveAction); + if (_delayState) { // hapens on inputs + _valueType = {type: 'alpha'}; + renderAll(); + } + // this is dirty... has to do with M|W|! button + if (typeof _mouseMoveAction === 'function' || typeof _mouseMoveAction === 'number') { + delete _options.webUnsave; + } + + _delayState = 1; + _mouseMoveAction = undefined; + + changeClass(_nodes.slds, 'do-drag', ''); + changeClass(_nodes.panel, '(?:start-change|do-change)', ''); + + _nodes.resizer.style.cssText = ''; + + _nodes.memo_store.style.cssText = 'background-color: ' + + color2string(_colors.RND.rgb) + '; ' + getOpacityCSS(_colors.alpha); + _nodes.memo.className = _nodes.memo.className.replace(/\s+(?:dark|light)/, '') + + // (/dark/.test(_nodes.colorPicker.className) ? ' dark' : ' light'); + (_colors['rgbaMix' + _bgTypes[_options.alphaBG]].luminance < 0.22 ? ' dark' : ' light'); + // (_colors.rgbaMixCustom.luminance < 0.22 ? ' dark' : ' light') + + _valueType = undefined; + + resetCursors(); + + if (_options.actionCallback) { + _options.actionCallback(e, mouseMoveAction.name || action || 'external'); + } + } + } + + function changeXYValue(e) { + var event = e || window.event, + scale = _options.scale, + page = getPageXY(event), + x = (page.X - _targetOrigin.left) * (scale === 4 ? 2 : scale), + y = (page.Y - _targetOrigin.top) * scale, + mode = _options.mode; + + _colors[mode.type][mode.x] = limitValue(x / 255, 0, 1); + _colors[mode.type][mode.y] = 1 - limitValue(y / 255, 0, 1); + convertColors(); + return preventDefault(event); + } + + function changeZValue(e) { // make this part of changeXYValue + var event = e || window.event, + page = getPageXY(event), + z = (page.Y - _targetOrigin.top) * _options.scale, + mode = _options.mode; + + _colors[mode.type][mode.z] = 1 - limitValue(z / 255, 0, 1); + convertColors(); + return preventDefault(event); + } + + function changeOpacityValue(e) { + var event = e || window.event, + page = getPageXY(event); + + _newData = true; + _colors.alpha = limitValue(Math.round( + (page.X - _targetOrigin.left) / _targetOrigin.width * 100), 0, 100 + ) / 100; + convertColors('alpha'); + return preventDefault(event); + } + + function changeInputValue(e) { + var event = e || window.event, + page = getPageXY(event), + delta = _startCoords.pageY - page.Y, + delayOffset = _options.delayOffset, + type = _valueType.type, + isAlpha = type === 'alpha', + ranges; + + if (_delayState || Math.abs(delta) >= delayOffset) { + if (!_delayState) { + _delayState = (delta > 0 ? -delayOffset : delayOffset) + + (+_mainTarget.firstChild.data) * (isAlpha ? 100 : 1); + _startCoords.pageY += _delayState; + delta += _delayState; + _delayState = 1; + changeClass(_nodes.panel, 'start-change', 'do-change'); + window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); + document.activeElement.blur(); + _renderTimer = window[requestAnimationFrame](renderAll); + } + + if (type === 'cmyk' && _options.cmyOnly) { + type = 'cmy'; + } + + if (isAlpha) { + _newData = true; + _colors.alpha = limitValue(delta / 100, 0, 1); + } else { + ranges = _valueRanges[type][_valueType.z]; + _colors[type][_valueType.z] = type === 'Lab' ? limitValue(delta, ranges[0], ranges[1]) : + limitValue(delta / ranges[1], 0, 1); + } + convertColors(isAlpha ? 'alpha' : type); + // event.returnValue is deprecated. Please use the standard event.preventDefault() instead. + // event.returnValue = false; // see: pauseEvent(event); + return preventDefault(event); + } + } + + function keyControl(e) { // this is quite big for what it does... + var event = e || window.event, + keyCode = event.which || event.keyCode, + key = String.fromCharCode(keyCode), + elm = document.activeElement, + + cln = elm.className.replace(_options.CSSPrefix, '').split('-'), + type = cln[0], + mode = cln[1], + + isAlpha = type === 'alpha', + isHex = type === 'HEX', + arrowKey = {k40: -1, k38: 1, k34: -10, k33: 10}['k' + keyCode] / (isAlpha ? 100 : 1), + validKeys = {'HEX': /[0-9a-fA-F]/, 'Lab': /[\-0-9]/, 'alpha': /[\.0-9]/}[type] || /[0-9]/, + valueRange = _valueRanges[type][type] || _valueRanges[type][mode], // let op! + + textNode = elm.firstChild, // chnge on TAB key + rangeData = caret(elm), + origValue = textNode.data, // do not change + value, + val = origValue === '0' && !isHex ? [] : origValue.split(''); // gefixt + + if (/^(?:27|13)$/.test(keyCode)) { // ENTER || ESC + // preventDefault(event); + elm.blur(); + } else if (event.type === 'keydown') { // functional keys + if (arrowKey) { // arrow/page keys + value = limitValue(Math.round((+origValue + arrowKey) * 1e+6) / 1e+6, valueRange[0], valueRange[1]); + } else if (/^(?:8|46)$/.test(keyCode)) { // DELETE / BACKSPACE + if (!rangeData.range) { + rangeData.range++; + rangeData.start -= keyCode === 8 ? 1 : 0; + } + val.splice(rangeData.start, rangeData.range); + value = val.join('') || '0'; // never loose elm.firstChild + } + + if (value !== undefined) { // prevent keypress + preventDefault(event, true); + } + } else if (event.type === 'keypress') { + if (!/^(?:37|39|8|46|9)$/.test(keyCode)) { // left, right,DEL, BACK, TAB for FF + preventDefault(event, true); + } + if (validKeys.test(key)) { // regular input + val.splice(rangeData.start, rangeData.range, key); + value = val.join(''); + } + rangeData.start++; + } + + if (keyCode === 13 && isHex) { + if (textNode.data.length % 3 === 0 || textNode.data === '0') { // textNode.data.length && + return _colorPicker.setColor(textNode.data === '0' ? '000' : textNode.data, 'rgb', _colors.alpha, true); + } else { + preventDefault(event, true); + return elm.focus(); + } + } + + if (isHex && value !== undefined) { + value = /^0+/.test(value) ? value : parseInt(''+value, 16) || 0; + } + + if (value !== undefined && value !== '' && +value >= valueRange[0] && +value <= valueRange[1]) { + if (isHex) { + value = value.toString(16).toUpperCase() || '0'; + } + if (isAlpha) { + _colors[type] = +value; + } else if (!isHex) { + _colors[type][mode] = +value / (type === 'Lab' ? 1 : valueRange[1]); + } + convertColors(isAlpha ? 'alpha' : type); + + preRenderAll(_colors); + _mouseMoveAction = true; + stopChange(e, event.type); + + textNode.data = value; // if + caret(elm, Math.min(elm.firstChild.data.length, rangeData.start < 0 ? 0 : rangeData.start)); + } + } + + function buttonActions(e) { + var event = e || window.event, + target = event.target || event.srcElement, + targetClass = target.className, + parent = target.parentNode, + options = _options, + RGB = _colors.RND.rgb, + customBG, alphaBG, + mode = _options.mode, + newMode = '', + prefix = options.CSSPrefix, + isModeButton = /(?:hs|rgb)/.test(parent.className) && /^[HSBLRG]$/.test( + target.firstChild ? target.firstChild.data : '' + ), + isDblClick = /dblc/.test(event.type), + buttonAction = ''; // think this over again.... + + if (isDblClick && !isModeButton) { + return; + } else if (targetClass.indexOf('-labl ' + prefix + 'labl') !== -1) { // HSB -> HSL; CMYK -> Lab buttons + changeClass(_nodes[targetClass.split('-')[0]], prefix + 'hide', ''); + changeClass(_nodes[parent.className.split('-')[1]], prefix + 'hide'); + } else if (targetClass.indexOf(prefix + 'butt') !== -1) { // BUTTONS + if (isModeButton) { // set render modes + if (isDblClick && _options.scale === 2) { + newMode = /hs/.test(mode.type) ? 'rgb' : /hide/.test(_nodes.hsl.className) ? 'hsv' : 'hsl'; + newMode = newMode + '-' + newMode[mode.type.indexOf(mode.z)]; + } + _colorPicker.setMode(newMode ? newMode : targetClass.replace('-butt', '').split(' ')[0]); + buttonAction = 'modeChange'; + } else if (/^[rgb]/.test(targetClass)) { // no vertical slider rendering in RGB mode + newMode = targetClass.split('-')[1]; + changeClass(_nodes.colorPicker, 'no-rgb-' + newMode, + (options['noRGB' + newMode] = !options['noRGB' + newMode]) ? undefined : ''); + buttonAction = 'noRGB' + newMode; + // preRenderAll(); + } else if (target === _nodes.alpha_labl) { // alpha button right (background of raster) + customBG = options.customBG; + alphaBG = options.alphaBG; + changeClass(_nodes.colorPicker, 'alpha-bg-' + alphaBG, 'alpha-bg-' + + (alphaBG = options.alphaBG = e.data || (alphaBG === 'w' ? (customBG ? 'c' : 'b') : + alphaBG === 'c' ? 'b' : 'w'))); + target.firstChild.data = alphaBG.toUpperCase(); + _nodes.ctrl.style.backgroundColor = _nodes.memo.style.backgroundColor = + alphaBG !== 'c' ? '' : 'rgb(' + Math.round(customBG.r * 255) + ', ' + + Math.round(customBG.g * 255) + ', ' + + Math.round(customBG.b * 255) + ')'; + _nodes.raster.style.cssText = _nodes.raster_bg.previousSibling.style.cssText = + alphaBG !== 'c' ? '' : getOpacityCSS(customBG.luminance < 0.22 ? 0.5 : 0.4); + buttonAction = 'alphaBackground'; + } else if (target === _nodes.alpha_butt) { // alpha button left (disable alpha rendering) + changeClass(_nodes.colorPicker, 'mute-alpha', (options.muteAlpha = !options.muteAlpha) ? undefined : ''); + buttonAction = 'alphaState'; + } else if (target === _nodes.HEX_butt) { // make it on/off + changeClass(_nodes.colorPicker, 'no-HEX', (options.HEXState = !options.HEXState) ? undefined : ''); + buttonAction = 'HEXState'; + } else if (target === _nodes.HEX_labl) { // web save state change + var isWebSave = _colors.saveColor === "web save"; + + if (_colors.saveColor !== "web smart" && !isWebSave) { + options.webUnsave = copyColor(RGB); + _colorPicker.setColor(_colors.webSmart, 'rgb'); + } else if (!isWebSave) { + if (!options.webUnsave) { + options.webUnsave = copyColor(RGB); + } + _colorPicker.setColor(_colors.webSave, 'rgb'); + } else { + _colorPicker.setColor(options.webUnsave, 'rgb'); + } + buttonAction = 'webColorState'; + } else if (/Lab-x-labl/.test(targetClass)) { //target === _nodes.cmyk_type) { + // switch between CMYK and CMY + changeClass(_nodes.colorPicker, 'cmy-only', (options.cmyOnly = !options.cmyOnly) ? undefined : ''); + buttonAction = 'cmykState'; + } + } else if (target === _nodes.bsav) { // SAVE + saveAsBackground(); + buttonAction = 'saveAsBackground'; + } else if (target === _nodes.bres) { // RESET + var tmpColor = copyColor(RGB), + tmpAlpha = _colors.alpha; + + // a bit heavy but... doesn't matter here + // newCol, type, alpha, forceRender + _colorPicker.setColor(options.color); + saveAsBackground(); + _colorPicker.setColor(tmpColor, 'rgb', tmpAlpha); + buttonAction = 'resetColor'; + } else if (parent === _nodes.col1) { // COLOR left + // _colors.hsv.h = (_colors.hsv.h + 0.5) % 1; // not acurate + _colors.hsv.h -= (_colors.hsv.h > 0.5 ? 0.5 : -0.5); + convertColors('hsv'); + buttonAction = 'shiftColor'; + + } else if (parent === _nodes.col2) { // COLOR right + _colorPicker.setColor(target.style.backgroundColor, 'rgb', _colors.background.alpha); + buttonAction = 'setSavedColor'; + } else if (parent === _nodes.memo) { // MEMORIES // revisit... + var resetBlink = function() { + if (_nodes.memos.blinker) _nodes.memos.blinker.style.cssText = _nodes.memos.cssText; + }, + doBlink = function(elm) { + _nodes.memos.blinker = elm; + elm.style.cssText = 'background-color:' + (_colors.RGBLuminance > 0.22 ? '#333' : '#DDD'); + window.setTimeout(resetBlink, 200); + }; + + if (target === _nodes.memo_cursor) { // save color in memo + resetBlink(); + _nodes.memos.blinker = undefined; + _nodes.testNode.style.cssText = _nodes.memo_store.style.cssText; + _nodes.memos.cssText = _nodes.testNode.style.cssText; // ...how browser sees css + for (var n = _nodes.memos.length - 1; n--; ) { // check if color already exists + if (_nodes.memos.cssText === _nodes.memos[n].style.cssText) { + doBlink(_nodes.memos[n]); // sets _nodes.memos.blinker + break; + } + } + if (!_nodes.memos.blinker) { // right shift colors + for (var n = _nodes.memos.length - 1; n--; ) { + _nodes.memos[n + 1].style.cssText = _nodes.memos[n].style.cssText; + } + _nodes.memos[0].style.cssText = _nodes.memo_store.style.cssText; + } + buttonAction = 'toMemery'; + } else { // reset color from memo + resetBlink(); + _colorPicker.setColor(target.style.backgroundColor, 'rgb', target.style.opacity || 1); + _nodes.memos.cssText = target.style.cssText; + doBlink(target); + // this is dirty... has to do with M|W|! button + _mouseMoveAction = 1; + buttonAction = 'fromMemory'; + } + + } + // think this over again, does this need to be like this?? + if (buttonAction) { + preRenderAll(_colors); + _mouseMoveAction = _mouseMoveAction || true; // !!!! search for: // this is dirty... + stopChange(e, buttonAction); + } + } + + function resizeApp(e, size) { + var event = e || window.event, + page = getPageXY(event), + isSize = size !== undefined, + x = isSize ? size : page.X - _targetOrigin.left + 8, + y = isSize ? size : page.Y - _targetOrigin.top + 8, + values = [' S XS XXS', ' S XS', ' S', ''], + sizes = _options.sizes, // from getUISizes(); + value = isSize ? values[size] : + y < sizes.XXS[1] + 25 ? values[0] : + x < sizes.XS[0] + 25? values[1] : + x < sizes.S[0] + 25 || y < sizes.S[1] + 25 ? values[2] : values[3], + isXXS = false, + mode, + tmp = ''; + + if (_cashedVars.resizer !== value) { + isXXS = /XX/.test(value); + mode = _options.mode; + + if (isXXS && (!/hs/.test(mode.type) || mode.z === 'h')) { + tmp = mode.type + '-' + mode.z; + _colorPicker.setMode(/hs/.test(mode.type) ? mode.type + '-s': 'hsv-s'); + _options.mode.original = tmp; + } else if (mode.original) { + // setMode(mode) creates a new object so mode.original gets deleted automatically + _colorPicker.setMode(mode.original); + } + + _nodes.colorPicker.className = _nodes.colorPicker.className.replace(/\s+(?:S|XS|XXS)/g, '') + value; + _options.scale = isXXS ? 4 : /S/.test(value) ? 2 : 1; + + _cashedVars.resizer = value; + + // fix this... from this point on inside if() ... convertColors(); + _newData = true; + renderAll(); + resetCursors(); + } + + _nodes.resizer.style.cssText = 'display: block;' + + 'width: ' + (x > 10 ? x : 10) + 'px;' + + 'height: ' + (y > 10 ? y : 10) + 'px;'; + } + + // ------------------------------------------------------ // + // --- Colors calculation and rendering related stuff --- // + // -------------------------------------------------------// + + function setMode(mode) { + var ModeMatrix = { + rgb_r : {x: 'b', y: 'g'}, + rgb_g : {x: 'b', y: 'r'}, + rgb_b : {x: 'r', y: 'g'}, + + hsv_h : {x: 's', y: 'v'}, + hsv_s : {x: 'h', y: 'v'}, + hsv_v : {x: 'h', y: 's'}, + + hsl_h : {x: 's', y: 'l'}, + hsl_s : {x: 'h', y: 'l'}, + hsl_l : {x: 'h', y: 's'} + }, + key = mode.replace('-', '_'), + regex = '\\b(?:rg|hs)\\w\\-\\w\\b'; // \\b\\w{3}\\-\\w\\b'; + + // changeClass(_nodes.colorPicker, '(?:.*?)$', mode); + // changeClass(_nodes.colorPicker, '\\b\\w{3}\\-\\w\\b', mode); + // changeClass(_nodes.slds, '\\b\\w{3}\\-\\w\\b', mode); + changeClass(_nodes.panel, regex, mode); + changeClass(_nodes.slds, regex, mode); + + mode = mode.split('-'); + return _options.mode = { + type: mode[0], + x: ModeMatrix[key].x, + y: ModeMatrix[key].y, + z: mode[1] + }; + } + + function initSliders() { // function name... + var regex = /\s+(?:hue-)*(?:dark|light)/g; + + _nodes.curl.className = _nodes.curl.className.replace(regex, ''); // ..... + _nodes.curr.className = _nodes.curr.className.replace(regex, ''); // ..... + _nodes.slds.className = _nodes.slds.className.replace(regex, ''); + // var sldrs = ['sldr_2', 'sldr_4', 'sldl_3']; + // for (var n = sldrs.length; n--; ) { + // _nodes[sldrs[n]].className = _options.CSSPrefix + sldrs[n].replace('_', '-'); + // } + _nodes.sldr_2.className = _options.CSSPrefix + 'sldr-2'; + _nodes.sldr_4.className = _options.CSSPrefix + 'sldr-4'; + _nodes.sldl_3.className = _options.CSSPrefix + 'sldl-3'; + + for (var style in _nodes.styles) { + if (!style.indexOf('sld')) _nodes.styles[style].cssText = ''; + } + _cashedVars = {}; + } + + function resetCursors() { + // _renderVars.isNoRGB = undefined; + _nodes.styles.curr.cssText = _nodes.styles.curl.cssText; // only coordinates + _nodes.curl.className = _options.CSSPrefix + 'curl' + ( + _renderVars.noRGBZ ? ' ' + _options.CSSPrefix + 'curl-' +_renderVars.noRGBZ: ''); + _nodes.curr.className = _options.CSSPrefix + 'curr ' + _options.CSSPrefix + 'curr-' + + (_options.mode.z === 'h' ? _renderVars.HUEContrast : _renderVars.noRGBZ ? + _renderVars.noRGBZ : _renderVars.RGBLuminance); + } + + function convertColors(type) { + preRenderAll(_colorInstance.setColor(undefined, type || _options.mode.type)); + _newData = true; + } + + function saveAsBackground() { + _colorInstance.saveAsBackground(); + _nodes.styles.col2.cssText = 'background-color: ' + color2string(_colors.background.RGB) + ';' + + getOpacityCSS(_colors.background.alpha); + + return (_colors); + } + + function preRenderAll(colors) { // do we need this??? yes, only calculate if values change... but how about _newData + var renderVars = _renderVars, + bgType = _bgTypes[_options.alphaBG]; + + renderVars.hueDelta = Math.round(colors['rgbaMixBGMix' + bgType].hueDelta * 100); + // renderVars.RGBLuminanceDelta = Math.round(colors.RGBLuminanceDelta * 100); + renderVars.luminanceDelta = Math.round(colors['rgbaMixBGMix' + bgType].luminanceDelta * 100); + renderVars.RGBLuminance = colors.RGBLuminance > 0.22 ? 'light' : 'dark'; + renderVars.HUEContrast = colors.HUELuminance > 0.22 ? 'light' : 'dark'; + // renderVars.contrast = renderVars.RGBLuminanceDelta > renderVars.hueDelta ? 'contrast' : ''; + renderVars.contrast = renderVars.luminanceDelta > renderVars.hueDelta ? 'contrast' : ''; + renderVars.readabiltiy = + colors['rgbaMixBGMix' + bgType].WCAG2Ratio >= 7 ? 'green' : + colors['rgbaMixBGMix' + bgType].WCAG2Ratio >= 4.5 ? 'orange': ''; + renderVars.noRGBZ = _options['no' + _options.mode.type.toUpperCase() + _options.mode.z] ? + (_options.mode.z === 'g' && colors.rgb.g < 0.59 || _options.mode.z === 'b' || _options.mode.z === 'r' ? + 'dark' : 'light') : undefined; + } + + function renderAll() { // maybe render alpha seperately... + if (_mouseMoveAction) { + // _renderTimer = window[requestAnimationFrame](renderAll); + if (!_newData) return (_renderTimer = window[requestAnimationFrame](renderAll)); + _newData = false; + } + // console.time('renderAll'); + var options = _options, colors = _colors, renderVars = _renderVars, cashedVars = _cashedVars, + mode = options.mode, nodes = _nodes, + prefix = options.CSSPrefix, + valueRanges = _valueRanges, + valueType = _valueType, + CSS = nodes.styles, + textNodes = nodes.textNodes, + scale = _options.scale, + x = colors[mode.type][mode.x], X = Math.round(x * 255 / (scale === 4 ? 2 : scale)), + y_ = colors[mode.type][mode.y], y = 1 - y_, Y = Math.round(y * 255 / scale), + z = 1 - colors[mode.type][mode.z], Z = Math.round(z * 255 / scale), + coords = (1 === 1) ? [x, y_] : [0, 0], a = 0, b = 0, // (1 === 2) button label up + isRGB = mode.type === 'rgb', isHue = mode.z === 'h', isHSL = mode.type === 'hsl', + isHSL_S = isHSL && mode.z === 's', + display, tmp, value, slider, + moveXY = _mouseMoveAction === changeXYValue, moveZ = _mouseMoveAction === changeZValue; + + if (isRGB) { + if (coords[0] >= coords[1]) b = 1; else a = 1; + if (cashedVars.sliderSwap !== a) { + nodes.sldr_2.className = options.CSSPrefix + 'sldr-' + (3 - a); + cashedVars.sliderSwap = a; + } + } + if ((isRGB && !moveZ) || (isHue && !moveXY) || (!isHue && !moveZ)) { + CSS[isHue ? 'sldl_2' : 'sldr_2'][isRGB ? 'cssText' : 'backgroundColor'] = + isRGB ? getOpacityCSS((coords[a] - coords[b]) / (1 - (coords[b]) || 0)) : color2string(colors.hueRGB); + } + if (!isHue) { + if (!moveZ) CSS.sldr_4.cssText = getOpacityCSS(isRGB ? coords[b] : isHSL_S ? Math.abs(1 - y * 2) : y); + if (!moveXY) CSS.sldl_3.cssText = getOpacityCSS(isHSL && mode.z === 'l' ? Math.abs(1 - z * 2) : z); + if (isHSL) { // switch slider class name for black/white color half way through in HSL(S|L) mode(s) + slider = isHSL_S ? 'sldr_4' : 'sldl_3'; + tmp = isHSL_S ? 'r-' : 'l-'; + value = isHSL_S ? (y > 0.5 ? 4 : 3) : (z > 0.5 ? 3 : 4); + + if (cashedVars[slider] !== value) { + nodes[slider].className = options.CSSPrefix + 'sld' + tmp + value; + cashedVars[slider] = value; + } + } + } + + if (!moveZ) CSS.curm.cssText = 'left: ' + X + 'px; top: ' + Y + 'px;'; + if (!moveXY) CSS.curl.top = Z + 'px'; + if (valueType) CSS.curr.top = Z + 'px'; // && valueType.type !== mode.type + if ((valueType && valueType.type === 'alpha') || _mainTarget === nodes.opacity) { + CSS.opacity_slider.left = options.opacityPositionRelative ? (colors.alpha * ( + (_targetOrigin.width || nodes.opacity.offsetWidth) - + (_targetOrigin.childWidth || nodes.opacity_slider.offsetWidth))) + 'px' : + (colors.alpha * 100) + '%'; + } + + CSS.col1.cssText = 'background-color: ' + color2string(colors.RND.rgb) + '; ' + + (options.muteAlpha ? '' : getOpacityCSS(colors.alpha)); + CSS.opacity.backgroundColor = color2string(colors.RND.rgb); + CSS.cold.width = renderVars.hueDelta + '%'; + CSS.cont.width = renderVars.luminanceDelta + '%'; + + for (display in textNodes) { + tmp = display.split('_'); + if (options.cmyOnly) { + tmp[0] = tmp[0].replace('k', ''); + } + value = tmp[1] ? colors.RND[tmp[0]][tmp[1]] : colors.RND[tmp[0]] || colors[tmp[0]]; + if (cashedVars[display] !== value) { + cashedVars[display] = value; + textNodes[display].data = value > 359.5 && display !== 'HEX' ? 0 : value; + + if (display !== 'HEX' && !options.noRangeBackground) { + value = colors[tmp[0]][tmp[1]] !== undefined ? colors[tmp[0]][tmp[1]] : colors[tmp[0]]; + if (tmp[0] === 'Lab') { + value = (value - valueRanges[tmp[0]][tmp[1]][0]) / + (valueRanges[tmp[0]][tmp[1]][1] - valueRanges[tmp[0]][tmp[1]][0]); + } + CSS[display].backgroundPosition = Math.round((1 - value) * 100) + '% 0%'; + } + } + } + // Lab out of gammut + tmp = colors._rgb ? [ + colors._rgb.r !== colors.rgb.r, + colors._rgb.g !== colors.rgb.g, + colors._rgb.b !== colors.rgb.b + ] : []; + if (tmp.join('') !== cashedVars.outOfGammut) { + nodes.rgb_r_labl.firstChild.data = tmp[0] ? '!' : ' '; + nodes.rgb_g_labl.firstChild.data = tmp[1] ? '!' : ' '; + nodes.rgb_b_labl.firstChild.data = tmp[2] ? '!' : ' '; + cashedVars.outOfGammut = tmp.join(''); + } + if (renderVars.noRGBZ) { + if (cashedVars.noRGBZ !== renderVars.noRGBZ) { + nodes.curl.className = prefix + 'curl ' + prefix + 'curl-' + renderVars.noRGBZ; + + if (!moveZ) { + nodes.curr.className = prefix + 'curr ' + prefix + 'curr-' + renderVars.noRGBZ; + } + cashedVars.noRGBZ = renderVars.noRGBZ; + } + } + if (cashedVars.HUEContrast !== renderVars.HUEContrast && mode.z === 'h') { + nodes.slds.className = nodes.slds.className.replace(/\s+hue-(?:dark|light)/, '') + + ' hue-' + renderVars.HUEContrast; + if (!moveZ) { + nodes.curr.className = prefix + 'curr ' + prefix + 'curr-' + renderVars.HUEContrast; + } + cashedVars.HUEContrast = renderVars.HUEContrast; + } else if (cashedVars.RGBLuminance !== renderVars.RGBLuminance) { // test for no else + nodes.colorPicker.className = nodes.colorPicker.className.replace(/\s+(?:dark|light)/, '') + + ' ' + renderVars.RGBLuminance; + if (!moveZ && mode.z !== 'h' && !renderVars.noRGBZ) { + nodes.curr.className = prefix + 'curr ' + prefix + 'curr-' + renderVars.RGBLuminance; + } + cashedVars.RGBLuminance = renderVars.RGBLuminance; + } + + if (cashedVars.contrast !== renderVars.contrast || cashedVars.readabiltiy !== renderVars.readabiltiy) { + nodes.ctrl.className = nodes.ctrl.className.replace(' contrast', '').replace(/\s*(?:orange|green)/, '') + + (renderVars.contrast ? ' ' + renderVars.contrast : '') + + (renderVars.readabiltiy ? ' ' + renderVars.readabiltiy : ''); + cashedVars.contrast = renderVars.contrast; + cashedVars.readabiltiy = renderVars.readabiltiy; + } + + if (cashedVars.saveColor !== colors.saveColor) { + nodes.HEX_labl.firstChild.data = !colors.saveColor ? '!' : colors.saveColor === 'web save' ? 'W' : 'M'; + cashedVars.saveColor = colors.saveColor; + } + + if (options.renderCallback) { + options.renderCallback(colors, mode); // maybe more parameters + } + + if (_mouseMoveAction) { + _renderTimer = window[requestAnimationFrame](renderAll); + } + + // console.timeEnd('renderAll') + } + + + // ------------------------------------------------------ // + // ------------------ helper functions ------------------ // + // -------------------------------------------------------// + + function copyColor(color) { + var newColor = {}; + + for (var n in color) { + newColor[n] = color[n]; + } + return newColor; + } + + function color2string(color, type) { + var out = [], + n = 0; + + type = type || 'rgb'; + while (type[n] || type.charAt(n)) { // IE7 + out.push(color[type[n] || type.charAt(n)]); + n++; + } + return type + '(' + out.join(', ') + ')'; + } + + function limitValue(value, min, max) { + return (value > max ? max : value < min ? min : value); + } + + function getOpacityCSS(value) { + if (value === undefined) value = 1; + + if (_isIE) { + return 'filter: alpha(opacity=' + Math.round(value * 100) + ');'; + } else { + return 'opacity: ' + (Math.round(value * 10000000000) / 10000000000) + ';'; // value.toFixed(16) = 99% slower + // some speed test: + // return ['opacity: ', (Math.round(value * 1e+10) / 1e+10), ';'].join(''); + } + } + + function preventDefault(e, skip) { + e.preventDefault ? e.preventDefault() : e.returnValue = false; + if (!skip) window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); + return false; + } + + function changeClass(elm, cln, newCln) { + return !elm ? false : elm.className = (newCln !== undefined ? + elm.className.replace(new RegExp('\\s+?' + cln, 'g'), newCln ? ' ' + newCln : '') : + elm.className + ' ' + cln); + } + + function getOrigin(elm) { + var box = (elm.getBoundingClientRect) ? elm.getBoundingClientRect() : {top: 0, left: 0}, + doc = elm && elm.ownerDocument, + body = doc.body, + win = doc.defaultView || doc.parentWindow || window, + docElem = doc.documentElement || body.parentNode, + clientTop = docElem.clientTop || body.clientTop || 0, // border on html or body or both + clientLeft = docElem.clientLeft || body.clientLeft || 0; + + return { + left: box.left + (win.pageXOffset || docElem.scrollLeft) - clientLeft, + top: box.top + (win.pageYOffset || docElem.scrollTop) - clientTop + }; + } + + function getPageXY(e) { + return { + X: e.pageX || e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft, + Y: e.pageY || e.clientY + document.body.scrollTop + document.documentElement.scrollTop + } + } + + function addEvent(obj, type, func) { + addEvent.cache = addEvent.cache || { + _get: function(obj, type, func, checkOnly) { + var cache = addEvent.cache[type] || []; + + for (var n = cache.length; n--; ) { + if (obj === cache[n].obj && '' + func === '' + cache[n].func) { + func = cache[n].func; + if (!checkOnly) { + cache[n] = cache[n].obj = cache[n].func = null; + cache.splice(n, 1); + } + return func; + } + } + }, + _set: function(obj, type, func) { + var cache = addEvent.cache[type] = addEvent.cache[type] || []; + + if (addEvent.cache._get(obj, type, func, true)) { + return true; + } else { + cache.push({ + func: func, + obj: obj + }); + } + } + }; + + if (!func.name && addEvent.cache._set(obj, type, func) || typeof func !== 'function') { + return; + } + + if (obj.addEventListener) obj.addEventListener(type, func, false); + else obj.attachEvent("on" + type, func); + } + + function removeEvent(obj, type, func) { + if (typeof func !== 'function') return; + if (!func.name) { + func = addEvent.cache._get(obj, type, func) || func; + } + + if (obj.removeEventListener) obj.removeEventListener(type, func, false); + else obj.detachEvent("on" + type, func); + } + + function caret(target, pos) { // only for contenteditable + var out = {}; + + if (pos === undefined) { // get + if (window.getSelection) { // HTML5 + target.focus(); + var range1 = window.getSelection().getRangeAt(0), + range2 = range1.cloneRange(); + range2.selectNodeContents(target); + range2.setEnd(range1.endContainer, range1.endOffset); + out = { + end: range2.toString().length, + range: range1.toString().length + } + } else { // IE < 9 + target.focus(); + var range1 = document.selection.createRange(), + range2 = document.body.createTextRange(); + range2.moveToElementText(target); + range2.setEndPoint('EndToEnd', range1); + out = { + end: range2.text.length, + range: range1.text.length + } + } + out.start = out.end - out.range; + return out; + } + // set + if (pos == -1) pos = target['text']().length; + + if (window.getSelection) { // HTML5 + target.focus(); + window.getSelection().collapse(target.firstChild, pos); + } else { // IE < 9 + var range = document.body.createTextRange(); + range.moveToElementText(target); + range.moveStart('character', pos); + range.collapse(true); + range.select(); + } + return pos; + } + + // ------------- requestAnimationFrame shim ------------- // + // ---------- quite optimized for minification ---------- // + + for(var n = vendors.length; n-- && !window[requestAnimationFrame]; ) { + window[requestAnimationFrame] = window[vendors[n] + 'Request' + animationFrame]; + window[cancelAnimationFrame] = window[vendors[n] + 'Cancel' + animationFrame] || + window[vendors[n] + 'CancelRequest' + animationFrame]; + } + + window[requestAnimationFrame] = window[requestAnimationFrame] || function(callback) { + // this is good enough... and better than setTimeout + return window.setTimeout(callback, 1000 / _options.fps); + // return _renderTimer ? _renderTimer : window.setInterval(callback, 1000 / _options.fps); + }; + + window[cancelAnimationFrame] = window[cancelAnimationFrame] || function(id) { + // console.log('OFF-', id + '-' + _renderTimer) + window.clearTimeout(id); + return _renderTimer = null; + }; + +})(window); \ No newline at end of file diff --git a/index.css b/index.css new file mode 100644 index 0000000..2eecb63 --- /dev/null +++ b/index.css @@ -0,0 +1,308 @@ +body{ + background-color: #222; + background: url(data:image/jpg;base64,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); +} +.cp-app { + position: relative; + float: left; + margin: 10px 0 0 10px; +} + +#testPatch { + position: absolute; + right: 20px; + top: 20px; + width: 100px; + height: 48px; + text-align: center; + line-height: 48px; + font-family: Courier,mono; + border: 1px solid #444; + cursor: default; +} +#contrastPatch { + position: absolute; + right: 20px; + top: 72px; + width: 100px; + height: 48px; + text-align: center; + line-height: 48px; + font-family: Courier,mono; + border: 1px solid #444; + cursor: default; +} +#contrastPatch div { + position: absolute; + top: 5px; + right: 50%; + bottom: 5px; + left: 5px; +} +#contrastPatch i { + display: block; + position: absolute; + top: 0px; + width: 100%; + height: 100%; + font-weight: bold; +} +#colorValues { + position: absolute; + right: 140px; + top: 20px; + height: 102px; + /* width: 183px; */ + width: 200px; + font-family: Courier,mono; + border: 1px solid #444; + color: #aaaaaa; + padding: 2px 0px 2px 4px; + box-sizing: border-box; + -moz-box-sizing: border-box; + font-size: 14px; + white-space: pre-wrap; + line-height: 16px; + background-color: #222; + cursor: default; +} +.sliders { + position: absolute; + right: 20px; + top: 140px; + width: 303px; +} +.sliders div { + height: 10px; + margin-bottom: 10px; + border: 1px solid #444; + background-color: #222; +} +.sliders div div { + height: 10px; + margin-bottom: 0px; + border: none; + background-color: #333; + border-right: 1px solid #555; +} +#rgbR { + background-color: #0ff; +} +#rgbG { + background-color: #f0f; +} +#rgbB { + background-color: #ff0; +} +#rgbR div { + background-color: #c00; +} +#rgbG div { + background-color: #0a0; +} +#rgbB div { + background-color: #00f; +} +#cmyC div { + background-color: #0ff; +} +#cmyM div { + background-color: #f0f; +} +#cmyY div { + background-color: #ff0; +} + +#rgbR:before, #rgbG:before, #rgbB:before, +#hslH:before, #hslS:before, #hslL:before, +#cmyC:before, #cmyM:before, #cmyY:before{ + display: block; + float: left; + margin-left: -18px; + margin-top: -3px; + color: #808080; + + font-family: Courier,mono; + font-size: 15px; + line-height: 15px; + cursor: default; +} +#rgbR:after, #rgbG:after, #rgbB:after { + display: block; + float: right; + margin-top: -12px; + margin-right: -1em; + color: #808080; + + font-family: Courier,mono; + font-size: 15px; + line-height: 15px; + cursor: default; +} +#rgbR:before { + content: 'R'; +} +#rgbG:before { + content: 'G'; +} +#rgbB:before { + content: 'B'; +} +#rgbR:after { + content: 'C'; +} +#rgbG:after { + content: 'M'; +} +#rgbB:after { + content: 'Y'; +} +#hslH:before { + content: 'H'; +} +#hslS:before { + content: 'S'; +} +#hslL:before { + content: 'L'; +} +#cmyC:before { + content: 'C'; +} +#cmyM:before { + content: 'M'; +} +#cmyY:before { + content: 'Y'; +} + + + +#hsv_map { + width: 240px; + height: 200px; + position: absolute; + right: 350px; + top: 20px; +} +#hsv_map .cover { + opacity: 0; + background-color: #000; + position: absolute; + top: -1px; + right: 39px; + bottom: -1px; + left: -1px; + border-radius: 50%; + cursor: crosshair; +} +#hsv_map .bar-bg, #hsv_map .bar-white { + position: absolute; + right: 0; + top: 0; + width: 25px; + height: 200px; + +} +#hsv_map .bar-bg { + +} +#hsv_map .bar-white { + background-color: #fff; +} +.hsv-cursor { + position: absolute; + border: 1px solid #eee; + border-radius: 50%; + width: 9px; + height: 9px; + cursor: default; + margin: -5px; + cursor: crosshair; +} +.dark .hsv-cursor { + border-color: #333; +} +.no-cursor .hsv-cursor, #hsv_map.no-cursor .cover { + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQI12P4//8/MwAI/wMBbrqo4gAAAABJRU5ErkJggg==), auto; + /*url(_blank.gif), url(_blank.png), url(_blank.cur), auto;*/ +} +#luminanceBar { + position: absolute; + right: 0; + top: 0; + /* background-color: red; */ +} +.hsv-barcursors { + position: absolute; + right: 0; + width: 25px; + top: 0; + height: 200px; + overflow: hidden; +} +.hsv-barcursor-l, .hsv-barcursor-r { + position: absolute; + width: 0; + height: 0; + border: 4px solid transparent; + margin-top: -4px; +} +.hsv-barcursor-l { + left: 0; + border-left: 4px solid #eee; +} +.hsv-barcursor-r { + right: 0; + border-right: 4px solid #eee; +} +.dark .hsv-barcursor-l { + border-left-color: #333; +} +.dark .hsv-barcursor-r { + border-right-color: #333; +} + +#color_squares { + position: absolute; + right: 350px; + top: 233px; +} +#color_squares div { + width: 27px; + height: 27px; + margin-left: 6px; + float: left; + border: 1px solid #444; +} + + + +#model_display { + font-family: Courier,mono; + border: 1px solid #444; + color: #aaaaaa; + padding: 2px 3px; + font-size: 14px; + list-style: none; + height: 400px; + width: 50%; + overflow: auto; +} +#model_display ul { + margin: 0; + padding: 0 0 0 20px; +} +#model_display li { + list-style: none; +} + +#description { + position: absolute; + right: 20px; + top: 270px; + width: 568px; + font-family: Courier,mono; + font-size: 14px; + color: #999; +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..fb11e87 --- /dev/null +++ b/index.html @@ -0,0 +1,68 @@ + + + + + + + +colorPicker_new + + + + +
+ +
-Test-
+ +
+ +
+
+
+
+ +
+
+
+ + +
+ +
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
Demo patches: demonstrate how to build color pickers and how Colors' / ColorPicker's API work. Patches are linked to
+ + + + + + + + + + + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..b2f90df --- /dev/null +++ b/index.js @@ -0,0 +1,537 @@ +;(function(window, undefined){ + "use strict" + + + if (1 === 2) { // to run ColorPicker on its own.... + myColor = window.myColor = new window.ColorPicker({ + // customCSS: true + }); + return; + } + + // Some common use variables + var ColorPicker = window.ColorPicker, + Tools = ColorPicker || window.Tools, // provides functions like addEvent, ... getOrigin, etc. + colorSourceSelector = document.getElementById('description').getElementsByTagName('select')[0], + startPoint, + currentTarget, + currentTargetWidth = 0, + currentTargetHeight = 0; + + /* ---------------------------------- */ + /* ------- Render color patch ------- */ + /* ---------------------------------- */ + var testPatch = document.getElementById('testPatch'), + renderTestPatch = function(color) { // used in renderCallback of 'new ColorPicker' + var RGB = color.RND.rgb; + + testPatch.style.cssText = + 'background-color: rgba(' + RGB.r + ',' + RGB.g + ',' + RGB.b + ',' + color.alpha + ');' + + 'color: ' + (color.rgbaMixBlack.luminance > 0.22 ? '#222' : '#ddd'); + testPatch.firstChild.data = '#' + color.HEX; + }; + + /* ---------------------------------- */ + /* ------ Render contrast patch ----- */ + /* ---------------------------------- */ + var contrastPatch = document.getElementById('contrastPatch'), + backGround = contrastPatch.firstChild, + renderContrastPatch = function(color) { // used in renderCallback of 'new ColorPicker' + var RGB = color.RND.rgb, + bgColor = color.background.RGB, + options = myColor.options ? myColor.options : myColor.color.options, + cBGColor = myColor ? options.customBG : {}, + bgType, + alphaBG; + + if (!cBGColor) { + // contrastPatch.style.display = 'none'; + // return; + cBGColor = {r: 1, g: 1, b: 1}; + } + alphaBG = options.alphaBG; + bgType = {w: 'White', b: 'Black', c: 'Custom'}[alphaBG]; + cBGColor = alphaBG === 'b' ? {r: 0, g: 0, b: 0} : alphaBG === 'w' ? {r: 1, g: 1, b: 1} : cBGColor; + contrastPatch.style.cssText = + 'background-color: rgb(' + + Math.round(cBGColor.r * 255) + ',' + + Math.round(cBGColor.g * 255) + ',' + + Math.round(cBGColor.b * 255) + ');' + + 'color: ' + 'rgba(' + RGB.r + ',' + RGB.g + ',' + RGB.b + ',' + color.alpha + ');'; + backGround.style.cssText = + 'background-color: rgba(' + + bgColor.r + ',' + + bgColor.g + ',' + + bgColor.b + ',' + color.background.alpha + ');'; + contrastPatch.children[1].firstChild.data = color['rgbaMixBGMix' + bgType] ? + '*' + color['rgbaMixBGMix' + bgType].WCAG2Ratio + '*' : + '-Test-'; + }; + + /* ---------------------------------- */ + /* ------- Render color values ------ */ + /* ---------------------------------- */ + var colorValues = document.getElementById('colorValues'), + renderColorValues = function(color) { // used in renderCallback of 'new ColorPicker' + var RND = color.RND; + + colorValues.firstChild.data = + 'rgba(' + RND.rgb.r + ',' + RND.rgb.g + ',' + RND.rgb.b + ',' + color.alpha + ')' + "\n" + + 'hsva(' + RND.hsv.h + ',' + RND.hsv.s + ',' + RND.hsv.v + ',' + color.alpha + ')' + "\n" + + 'hsla(' + RND.hsl.h + ',' + RND.hsl.s + ',' + RND.hsl.l + ',' + color.alpha + ')' + "\n" + + 'CMYK(' + RND.cmyk.c + ',' + RND.cmyk.m + ',' + RND.cmyk.y + ',' + RND.cmyk.k + ')' + "\n" + + 'CMY(' + RND.cmy.c + ',' + RND.cmy.m + ',' + RND.cmy.y + ')' + "\n" + + 'Lab(' + RND.Lab.L + ',' + RND.Lab.a + ',' + RND.Lab.b + ')'; // + "\n" + + + // 'mixBG: ' + (color.rgbaMixBG.luminance).toFixed(10) + "\n" + + // 'mixBGCBG: ' + (color.rgbaMixCustom.luminance).toFixed(10); + // 'XYZ(' + RND.XYZ.X + ',' + RND.XYZ.Y + ',' + RND.XYZ.Z + ')'; + }; + + /* ---------------------------------- */ + /* ---------- Color squares --------- */ + /* ---------------------------------- */ + var colorSquares = document.getElementById('color_squares'), + squares = colorSquares.children, + n = squares.length; + + for ( ; n--; ) { // draw random color values as background + squares[n].style.backgroundColor = 'rgb(' + + Math.round(Math.random() * 255) + ',' + + Math.round(Math.random() * 255) + ',' + + Math.round(Math.random() * 255) +')'; + } + + Tools.addEvent(colorSquares, 'click', function(e){ // event delegation + if (e.target.parentNode === this) { + myColor.setColor(e.target.style.backgroundColor); + startRender(true); + } + }); + + /* ---------------------------------- */ + /* ---------- Color sliders --------- */ + /* ---------------------------------- */ + var sliders = document.getElementById('sliders'), + sliderChildren = sliders.children, + type, + mode, + max = { + rgb: {r: 255, g: 255, b: 255}, + hsl: {h: 360, s: 100, l: 100}, + cmy: {c: 100, m: 100, y: 100} + // hsv: {h: 360, s: 100, v: 100}, + // cmyk: {c: 100, m: 100, y: 100, k: 100}, + }, + sliderDown = function (e) { // mouseDown callback + var target = e.target, + id, len; + + if (e.target !== this) { + e.preventDefault(); + + currentTarget = target.id ? target : target.parentNode; + id = currentTarget.id; // rgbR + len = id.length - 1; + type = id.substr(0, len); // rgb + mode = id[len].toLowerCase(); // R -> r + startPoint = Tools.getOrigin(currentTarget); + currentTargetWidth = currentTarget.offsetWidth; + + sliderMove(e); + Tools.addEvent(window, 'mousemove', sliderMove); + startRender(); + } + }, + sliderMove = function (e) { // mouseMove callback + var newColor = {}; + + // The idea here is (so in the HSV-color-picker) that you don't + // render anything here but just send data to the colorPicker, no matter + // if it's out of range. colorPicker will take care of that and render it + // then in the renderColorSliders correctly (called in renderCallback). + newColor[mode] = (e.clientX - startPoint.left) / currentTargetWidth * max[type][mode]; + myColor.setColor(newColor, type); + }, + renderColorSliders = function(color) { // used in renderCallback of 'new ColorPicker' + for (var n = sliderChildren.length; n--; ) { + var child = sliderChildren[n], + len = child.id.length - 1, + type = child.id.substr(0, len), + mode = child.id[len].toLowerCase(); + + child.children[0].style.width = (color.RND[type][mode] / max[type][mode] * 100) + '%'; + } + }; + + Tools.addEvent(sliders, 'mousedown', sliderDown); // event delegation + Tools.addEvent(window, 'mouseup', function() { + Tools.removeEvent (window, 'mousemove', sliderMove); + stopRender(); + }); + + /* ---------------------------------- */ + /* ---- HSV-circle color picker ----- */ + /* ---------------------------------- */ + var hsv_map = document.getElementById('hsv_map'), + hsv_mapCover = hsv_map.children[1], // well... + hsv_mapCursor = hsv_map.children[2], + hsv_barBGLayer = hsv_map.children[3], + hsv_barWhiteLayer = hsv_map.children[4], + hsv_barCursors = hsv_map.children[6], + hsv_barCursorsCln = hsv_barCursors.className, + hsv_Leftcursor = hsv_barCursors.children[0], + hsv_Rightcursor = hsv_barCursors.children[1], + + colorDisc = document.getElementById('surface'), + colorDiscRadius = colorDisc.offsetHeight / 2, + luminanceBar = document.getElementById('luminanceBar'), + + hsvDown = function(e) { // mouseDown callback + var target = e.target; + + e.preventDefault(); + + currentTarget = target.id ? target : target.parentNode; + startPoint = Tools.getOrigin(currentTarget); + currentTargetHeight = currentTarget.offsetHeight; // as diameter of circle + + Tools.addEvent(window, 'mousemove', hsvMove); + hsv_map.className = 'no-cursor'; + hsvMove(e); + startRender(); + }, + hsvMove = function(e) { // mouseMove callback + var r, x, y, h, s; + + if(currentTarget === hsv_map) { // the circle + r = currentTargetHeight / 2, + x = e.clientX - startPoint.left - r, + y = e.clientY - startPoint.top - r, + h = 360 - ((Math.atan2(y, x) * 180 / Math.PI) + (y < 0 ? 360 : 0)), + s = (Math.sqrt((x * x) + (y * y)) / r) * 100; + myColor.setColor({h: h, s: s}, 'hsv'); + } else if (currentTarget === hsv_barCursors) { // the luminanceBar + myColor.setColor({ + v: (currentTargetHeight - (e.clientY - startPoint.top)) / currentTargetHeight * 100 + }, 'hsv'); + } + }, +/* renderHSVPicker = function(color) { // used in renderCallback of 'new ColorPicker' + var pi2 = Math.PI * 2, + x = Math.cos(pi2 - color.hsv.h * pi2), + y = Math.sin(pi2 - color.hsv.h * pi2), + r = color.hsv.s * (colorDiscRadius - 5), // - border + // this approach useing hsl is not the fastest (I just wanted to try out)... so, + // better would be to have 2 extra layers underneath luminanceBar, the middle one + // being white and opac with color.hsl.l, the 2nd one bgColor to color.heuRGB. + // This approach would then be faster and also work with older IEs. + hsv2hsl = function(hsv) { // there is no hsv(h, s, v) in CSS + var l = (2 - hsv.s) * hsv.v, + s = hsv.s * hsv.v; + + return { + h: hsv.h, + s: !hsv.s ? 0 : l < 1 ? (l ? s / l : 0) : s / (2 - l), + l: l / 2 + } + }, + hslFull = hsv2hsl({ + h: color.hsv.h, + s: color.hsv.s, + v: 1 + }); + + hsv_mapCover.style.opacity = 1 - color.hsv.v; + hsv_mapCursor.style.cssText = + 'left: ' + (x * r + colorDiscRadius) + 'px;' + + 'top: ' + (y * r + colorDiscRadius) + 'px;' + + (color.RGBLuminance > 0.22 ? 'background-position: 0 -36px;' : ''); + + luminanceBar.style.backgroundColor = 'hsl(' + + Math.round(hslFull.h * 360) + ',' + + Math.round(hslFull.s * 100) + '%,' + + Math.round(hslFull.l * 100) + '%)'; + hsv_barCursors.className = color.RGBLuminance > 0.22 ? hsv_barCursorsCln + ' dark' : hsv_barCursorsCln; + hsv_Leftcursor.style.top = hsv_Rightcursor.style.top = ((1 - color.hsv.v) * colorDiscRadius * 2) + 'px'; + }; +*/ renderHSVPicker = function(color) { // used in renderCallback of 'new ColorPicker' + var pi2 = Math.PI * 2, + x = Math.cos(pi2 - color.hsv.h * pi2), + y = Math.sin(pi2 - color.hsv.h * pi2), + r = color.hsv.s * (colorDiscRadius - 5); + + hsv_mapCover.style.opacity = 1 - color.hsv.v; + // this is the faster version... + hsv_barWhiteLayer.style.opacity = 1 - color.hsv.s; + hsv_barBGLayer.style.backgroundColor = 'rgb(' + + color.hueRGB.r + ',' + + color.hueRGB.g + ',' + + color.hueRGB.b + ')'; + + hsv_mapCursor.style.cssText = + 'left: ' + (x * r + colorDiscRadius) + 'px;' + + 'top: ' + (y * r + colorDiscRadius) + 'px;' + + // maybe change className of hsv_map to change colors of all cursors... + 'border-color: ' + (color.RGBLuminance > 0.22 ? '#333;' : '#ddd'); + hsv_barCursors.className = color.RGBLuminance > 0.22 ? hsv_barCursorsCln + ' dark' : hsv_barCursorsCln; + hsv_Leftcursor.style.top = hsv_Rightcursor.style.top = ((1 - color.hsv.v) * colorDiscRadius * 2) + 'px'; + }; + + Tools.addEvent(hsv_map, 'mousedown', hsvDown); // event delegation + Tools.addEvent(window, 'mouseup', function() { + Tools.removeEvent (window, 'mousemove', hsvMove); + hsv_map.className = ''; + stopRender(); + }); + + // generic function for drawing a canvas disc + var drawDisk = function(ctx, coords, radius, steps, colorCallback) { + var x = coords[0] || coords, // coordinate on x-axis + y = coords[1] || coords, // coordinate on y-axis + a = radius[0] || radius, // radius on x-axis + b = radius[1] || radius, // radius on y-axis + angle = 360, + rotate = 0, coef = Math.PI / 180; + + ctx.save(); + ctx.translate(x - a, y - b); + ctx.scale(a, b); + + steps = (angle / steps) || 360; + + for (; angle > 0 ; angle -= steps){ + ctx.beginPath(); + if (steps !== 360) ctx.moveTo(1, 1); // stroke + ctx.arc(1, 1, 1, + (angle - (steps / 2) - 1) * coef, + (angle + (steps / 2) + 1) * coef); + + if (colorCallback) { + colorCallback(ctx, angle); + } else { + ctx.fillStyle = 'black'; + ctx.fill(); + } + } + ctx.restore(); + }, + drawCircle = function(ctx, coords, radius, color, width) { // uses drawDisk + width = width || 1; + radius = [ + (radius[0] || radius) - width / 2, + (radius[1] || radius) - width / 2 + ]; + drawDisk(ctx, coords, radius, 1, function(ctx, angle){ + ctx.restore(); + ctx.lineWidth = width; + ctx.strokeStyle = color || '#000'; + ctx.stroke(); + }); + }; + + drawDisk( // HSV color wheel with white center + colorDisc.getContext("2d"), + [colorDisc.width / 2, colorDisc.height / 2], + [colorDisc.width / 2 - 1, colorDisc.height / 2 - 1], + 360, + function(ctx, angle) { + var gradient = ctx.createRadialGradient(1, 1, 1, 1, 1, 0); + gradient.addColorStop(0, 'hsl(' + (360 - angle + 0) + ', 100%, 50%)'); + gradient.addColorStop(1, "#FFFFFF"); + + ctx.fillStyle = gradient; + ctx.fill(); + } + ); + drawCircle( // gray border + colorDisc.getContext("2d"), + [colorDisc.width / 2, colorDisc.height / 2], + [colorDisc.width / 2, colorDisc.height / 2], + '#555', + 3 + ); + // draw the luminanceBar bar + var ctx = luminanceBar.getContext("2d"), + gradient = ctx.createLinearGradient(0, 0, 0, 200); + + gradient.addColorStop(0,"transparent"); + gradient.addColorStop(1,"black"); + + ctx.fillStyle = gradient; + ctx.fillRect(0, 0, 30, 200); + + + // experimental stuff + + // var colorModel = document.getElementById('model_display'), + // displayModel = function(model) { + // var html = ['
    ']; + // for (var n in model) { + // if (typeof model[n] === 'object') { + // html.push(n + ': ' + displayModel(model[n])); + // // return html.join(''); + // } else { + // html.push('
  • ' + n + ': ' + model[n] + '
  • '); + // } + // } + // html.push('
'); + // return html.join(''); + // }; + + + /* + * This script is set up so it runs either with ColorPicker or with Color only. + * The difference here is that ColorPicker has a renderCallback that Color doesn't have + * therefor we have to set a render intervall in case it's missing... + * setInterval() can be exchanged to window.requestAnimationFrame(callBack)... + * + * If you want to render on mouseMove only then get rid of startRender(); in + * all the mouseDown callbacks and add doRender(myColor.colors); in all + * mouseMove callbacks. (Also remove all stopRender(); in mouseUp callbacks) + */ + var doRender = function(color) { + renderTestPatch(color); + renderContrastPatch(color); + renderColorValues(color); + renderColorSliders(color); + renderHSVPicker(color); + // colorModel.innerHTML = displayModel(color); // experimental + }, + renderTimer, + // those functions are in case there is no ColorPicker but only Colors involved + startRender = function(oneTime){ + if (isColorPicker) { // ColorPicker present + myColor.startRender(oneTime); + } else if (oneTime) { // only Colors is instanciated + doRender(myColor.colors); + } else { + renderTimer = window.setInterval( + function() { + doRender(myColor.colors); + // http://stackoverflow.com/questions/2940054/ + }, 13); // 1000 / 60); // ~16.666 -> 60Hz or 60fps + } + }, + stopRender = function(){ + if (isColorPicker) { + myColor.stopRender(); + } else { + window.clearInterval(renderTimer); + } + }, + renderCallback = doRender, + // finally the instance of either ColorPicker or Colors (export for debugging purposes) + color_ColorPicker = new (ColorPicker || Colors)({ + customBG: '#808080' + // renderCallback: renderCallback, // doesn't work in Colors, but also doesn't matter + // convertCallback: function(color, type){console.log(color, type)} + // resizeCallback: function(e, value, scale, original){console.log(e, value, scale, original)} + // actionCallback: function(e, value){console.log(e, value)}, + // customCSS: true, +/* memoryColors: [ + {r: 100, g: 200, b: 10, a: 0.6}, + {r: 80, g: 100, b: 50, a: 0.9}, + {r: 70, g: 80, b: 10, a: 0.9}, + {r: 20, g: 200, b: 60, a: 0.9}, + {r: 88, g: 0, b: 30, a: 0.4}, + {r: 100, g: 0, b: 100, a: 0.6}, + {r: 200, g: 0, b: 0}, + {r: 200, g: 30, b: 100} + ], +*/ // size: 2 + }), + color_Colors = new Colors(), + myColor, + isColorPicker = colorSourceSelector.value === 'ColorPicker'; + + myColor = window.myColor = color_Colors; + // mySecondColor = window.mySecondColor = new ColorPicker({instanceName: 'mySecondColor'}); + + // in case ColorPicker is not there... + if (!isColorPicker) { // initial rendering + doRender(myColor.colors); + } + + colorSourceSelector.onchange = function(e) { + if (this.value === 'Colors') { + color_ColorPicker.color.options.renderCallback = function(color){}; + myColor = window.myColor = color_Colors; + isColorPicker = false; + doRender(myColor.colors); + } else { + color_ColorPicker.color.options.renderCallback = doRender; + myColor = window.myColor = color_ColorPicker; + isColorPicker = true; + doRender(myColor.color.colors); + } + } + + + function conversionTest () { + // conversion test + var convert = myColor.color ? myColor.color.convertColor : myColor.convertColor, + x = 0.85, y = 0.33, z = 0.23, k = 0.1, + modes = ['hsl', 'hsv', 'rgb', 'cmy', 'cmyk', 'Lab', 'XYZ', 'HEX'], + color = {}, + fromMode = '', + toMode = '', + counter = 0, + value, + colorOut = [], + valueOut = [], + isLab = false; + + for (var o = 2; o--; ) { + for (var n = 0, m = modes.length; n < m; n++) { + if (modes[n] === 'HEX') { + color = '89ABCD'; + } else { + color = {}; + isLab = modes[n] === 'Lab'; + color[modes[n][0]] = o && !isLab ? x : Math.round(x * 100) + (isLab ? x : 0); + color[modes[n][1]] = o && !isLab ? y : Math.round(y * 100) + (isLab ? y : 0); + color[modes[n][2]] = o && !isLab ? z : Math.round(z * 100) + (isLab ? z : 0); + if (modes[n] === 'cmyk') { + color[modes[n][3]] = o ? k : Math.round(k * 100);; + } + } + fromMode = o ? modes[n] : modes[n].toUpperCase(); + for (var d = 2; d--; ) { + for (var p = 0, q = modes.length; p < q; p++) { + toMode = d ? modes[p] : modes[p].toUpperCase(); + if (fromMode !== toMode) {// && fromMode !== 'LAB' && toMode !== 'LAB') { + if ((!d && /(?:XYZ|HEX)/.test(toMode)) || // good to avoid double 2XYZ or 2HEX + (!o && /(?:XYZ|HEX)/.test(fromMode))) { // good to avoid double XYZ2 or HEX2 + // do nothing + } else { + value = convert(color, fromMode + '2' + toMode); + colorOut = []; + for (var s in color) { + colorOut.push(s + ': ' + color[s]); + } + colorOut = fromMode === 'HEX' ? '"' + color + '"' : '{' + colorOut.join(', ') + '}'; + + valueOut = []; + for (var s in value) { + valueOut.push(s + ': ' + value[s]); + } + valueOut = toMode === 'HEX' ? '"' + value + '"' : '{' + valueOut.join(', ') + '}'; + + console.log('convertColor(' + colorOut + ', "' + fromMode + + '2' + toMode + '") = ' + valueOut); + counter++; + } + } + } + } + } + } + console.log('Tested ' + counter + ' conversion combinations (excluding same to same)'); + } + + window.conversionTest = conversionTest; + + // conversionTest(); + +})(window); \ No newline at end of file