From 7028d4ef20178de4f2d475896714df1ad7aa14e2 Mon Sep 17 00:00:00 2001 From: Will Bamberg Date: Tue, 10 Aug 2021 09:46:09 -0700 Subject: [PATCH 1/2] Add border-image generator --- .../arrow-down-white.png | Bin 0 -> 172 bytes .../arrow-right-white.png | Bin 0 -> 181 bytes .../border-image-generator/arrow-up-white.png | Bin 0 -> 175 bytes tools/border-image-generator/arrows.png | Bin 0 -> 372 bytes .../border-image-generator/border-image-1.png | Bin 0 -> 507 bytes .../border-image-generator/border-image-2.png | Bin 0 -> 1344 bytes .../border-image-generator/border-image-3.png | Bin 0 -> 1366 bytes .../border-image-generator/border-image-4.png | Bin 0 -> 367 bytes .../border-image-generator/border-image-5.png | Bin 0 -> 577 bytes .../border-image-generator/border-image-6.svg | 1 + tools/border-image-generator/checked.png | Bin 0 -> 275 bytes tools/border-image-generator/close.png | Bin 0 -> 271 bytes tools/border-image-generator/config.png | Bin 0 -> 287 bytes tools/border-image-generator/disabled.png | Bin 0 -> 344 bytes .../drop_arrow_icon.png | Bin 0 -> 534 bytes tools/border-image-generator/grain.png | Bin 0 -> 4716 bytes tools/border-image-generator/index.html | 155 ++ tools/border-image-generator/resize.png | Bin 0 -> 150 bytes tools/border-image-generator/script.js | 1393 +++++++++++++++++ tools/border-image-generator/styles.css | 1047 +++++++++++++ 20 files changed, 2596 insertions(+) create mode 100644 tools/border-image-generator/arrow-down-white.png create mode 100644 tools/border-image-generator/arrow-right-white.png create mode 100644 tools/border-image-generator/arrow-up-white.png create mode 100644 tools/border-image-generator/arrows.png create mode 100644 tools/border-image-generator/border-image-1.png create mode 100644 tools/border-image-generator/border-image-2.png create mode 100644 tools/border-image-generator/border-image-3.png create mode 100644 tools/border-image-generator/border-image-4.png create mode 100644 tools/border-image-generator/border-image-5.png create mode 100644 tools/border-image-generator/border-image-6.svg create mode 100644 tools/border-image-generator/checked.png create mode 100644 tools/border-image-generator/close.png create mode 100644 tools/border-image-generator/config.png create mode 100644 tools/border-image-generator/disabled.png create mode 100644 tools/border-image-generator/drop_arrow_icon.png create mode 100644 tools/border-image-generator/grain.png create mode 100644 tools/border-image-generator/index.html create mode 100644 tools/border-image-generator/resize.png create mode 100644 tools/border-image-generator/script.js create mode 100644 tools/border-image-generator/styles.css diff --git a/tools/border-image-generator/arrow-down-white.png b/tools/border-image-generator/arrow-down-white.png new file mode 100644 index 0000000000000000000000000000000000000000..ab65bddbafc306170dee6cefbc142137a4b04f32 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@5Lt z8c`CQpH@<5)bc)mm`RR&FBpR*?#BhCV4D#Z2Fl>oo*3vLs&@{orMEsf4&T?^-me@J4u Xl%;3+Ppj!1&@={5S3j3^P6i< literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/arrow-up-white.png b/tools/border-image-generator/arrow-up-white.png new file mode 100644 index 0000000000000000000000000000000000000000..74749e5c68bea4a040aab7973741571237deb092 GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@5Lt z8c`CQpH@W}Sq!2)3;ffV7`|WD^LWEt R9}6^x!PC{xWt~$(69Bk^H3|R# literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/arrows.png b/tools/border-image-generator/arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..30d630fdaf96be7baa2d7da9de6cda337a5ab769 GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^3P3Et!3-oF?)7E^DVB6cUq=Rpjs4tz5?O(K#^NA% zCx&(BWL^R}2?0JKuI>ds_4V~NH8qbOJ*udvxOM9mko*7t|MvEFhhKoOt9UUD&Ms00v8)Hrk&@Q=>AirRS zE!#K+*|}KG9yrLmP57Xs2$RsoJ;%72xespTIeO{Vt&kF+$_`H##}JM4y%XKV4k&Q2 zn(h_9EPdzyG*2;>+e+*9ojcLoF0kMKPT{+x>GF@S1;5+=aYN;%$5StPx#Ay7<|4sn^y<7iG0RO#Q|Gr%RO91~&0RO&R z|4ab?zFa(Qhspo|010$bPE!CUC+6nm<;=`hQHX>900Co3L_t(Y$L*G}PQ)+_hJAg4 z6G*UjNF~-ASu@_)k?lq{M%WM|D-u$6PC|J~(l|}*G?DCqt=^(9{`EVtqX5LXKSGJ& zgDg0L!{dpp%+J_EaOb{D=J4d_4hnhBl}zJ(5#w^KxdC%%TiMD@&YKmrI~ijzV=9vBpq1#=Jo}4>OY_igJ{!Bs`Ju4&#D_ zV_Zj$NM6XiDUv~yp(DJJrF$hC{Vzi=3Qf6BdF_hxl;4r!-sQcd=udgiE9OW(n~Hgt zzaj82LN7QP&bGI)LQ_7#O>ndvq3uaBWIR1W793&!%uPv-4C$VRWI=16+qO%BraU-} z!YL}FV|$Vb<;mGPdCKodaqse8QuL?1 x=M{4#pH0QQ%ioawZ?pex_P@>kxB2hC%^yc~XFj;PvyuP+002ovPDHLkV1lvW=2rj! literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/border-image-2.png b/tools/border-image-generator/border-image-2.png new file mode 100644 index 0000000000000000000000000000000000000000..64f16111c47e09084428983354d89e33f9b25688 GIT binary patch literal 1344 zcma)+`BPH|5XWPq77_vii3X^O0!qMAPz%KYl_L+LB4;96&~OAojB&(Namq-c9P)hO z5Fu(Q1rjWVD;$dAfF+oas1<|~5=u}A$Q20pAxirA54!W&{m#zp?0kRN+01~`J{Xia z3V}diNWR`dutsmB9ulrTZnPL!%-F<9~kugy$LHC-d~b3KZW3!fFw=Cm(9Op0q?Un*)KBb_b@_dZTr<(pUm+V^UHhVu_s`9C&L|!(F3(Jk)eH<*$p?Gq z`>Jc-j(_;rJw5q!=wm&%d9YF%)!!4e#PxoY@l-SMT&L4f0(HZ%p9Acm)4_22e*@7j z*M|^@&E_O;kC24EhQ8i-3nzmu0luh$=%(Pp0rkFhosJj=Mj{<{4XJ#xW8Q}D%|ss{ zEOq=Ad-A2x?xhvv^y-wdH26vl6`FD(X1s7SusgU6W|gu7Za z#XE0Jv-S#hNPidxo!|2=Ctm_HhP{I!jT?~0A<7={z5G@fI<^Z6yuX1Uhp_-sVZyLo z9E$MRB}W9A}xemom_P3)d&Uh2v6sQ!tg*NP7ou-WCgA+18*iF)<|0W+AjU7wa94q`bJh!aPX4qWO+P|ysl|}Yz)c-`7B+E*V`z34-S#rEy-GZ;<6#}E{786X?iA=GxpGo9H`#CBbBpFU_spEQE*5E6aoN+YCW1Ne21r6 z5rC_$xzN!G-(Dlhyo^rGI+Zb%i<~n0F)2L5omlQBGD>1(`&XcCvxTX_=%S@eftx5M zEJJ@X>wVI|M5qjT`;w7#evH=5Yk{smIdG2a(UU&XXxR1yZSr^M<$B+LvJ4wh*Hzot zynB5{=Nk3<+oTD3@`!Iv`ulbMp-OV`NLmI=hqdS1be3tr8+5PBhe~r;he7wm0#3c>Ur%k9@ZpE*Jf%O_FQGT7LUAb) zfuhDaCl@P{kZLb{T?azBh-o4WMIwyyvl}EyD`8u%|_f9 zTghKAb10XT6}<7jcm&di+8t-iZiN$);UkwCcJ z04BQby9IEc3x-BQ$hfHo{yET5kL}`%t3umPX=RppukCNa-aHniv!}w*B1+&7`rLOX wteBj=2R%A=V_Br0j?yWc40ixl>!wtMKVvxUjow!V@OMFwh^M`)J*g@G0axL#@c;k- literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/border-image-3.png b/tools/border-image-generator/border-image-3.png new file mode 100644 index 0000000000000000000000000000000000000000..847675cb7a4306ad22ce5b9c2c82851c86d7472a GIT binary patch literal 1366 zcmV-c1*!UpP)mYsaP+2H{`vIsuxa$6Qt!%+@w<5M(3ShruK2NY{pHd5xPSZ0 zqWZ;_{NKg%t6})7XYs&)?$w?4mqhI9yZ`_Hl0J@_0000XbW%=J|NsC0|NsC0|NsC0 z|NsC0|NsC0|NsC0|NsC0|NsC00H49oApigbTuDShRCwC7n(NwYFc5`D9P8YoEp12c z|0;J71VO*u%=~SiyewACOa@-}nv+K5Fz^uJ8Bh`I2Saoq!K^`id5L*K;+2STgB5Vc z^22u~cqg*if0hZ*y1H%5IPe1i0qU+E6S}?#U!0g=Byf z=(dY+ua=N4*fK=q8I}b@>)o&Q7LQdgle}Vd_yDo-+OFf43fT&K!{`>aFqcWkLY#YYvKNi!-H2yfK*+UXY z_twbM-m3?Z>tvGAnPh};2mO{Jtl{MwAl2FB{$KPanIN3S6p#oK6*6xv24gVE4AEKT z=g6^IKvr9enHWr>KnnbrW`xt0GeQ!KOhcqe6o`In`6;p&UqfosRvAsALiqmH@}DNb zWD9Z3T4gfH03rp4;WL>b z40DQ%C`^&n^PNy+5&est;XRQM!&{^JmR%7F`QT}?uA!ib@jgJv^y-U;Vt~-;)rQt< z^a-6_DF!2iOs`M>SpiO|m#D)M>a1RDVKsGDFRD4U2ohBggZo!q(}3E z<<(KuNJNKCS_3ecEjX%)gEXtoOcZW900DsW)7Usa^k14Jl;`k^Tq%}AC*t002XSmt`!U#O;|l|1aSou!#MK-l z?Z#(hH+jZf7wOf}AjWKxl}t)Ff~>UoCFXz>%07*qoM6N<$f&r7N)c^nh literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/border-image-4.png b/tools/border-image-generator/border-image-4.png new file mode 100644 index 0000000000000000000000000000000000000000..c11d34b0848d2aba569266fd0a0f39a53f941c25 GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^DIm666;Q<~pJv(3+^f z)AHSK`}bKrF1vNzBA?j1DxCf4F!Pk*M$aEBRJZI+6Dpb|l>20*ZT^z5Y-Qf<7x4Bco>V4zlXKd^+OkJwdZaRPd1gqz_PFVj= go9VlCJp(ht)oBN7rmWuW4fGI$r>mdKI;Vst0C`BBmjD0& literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/border-image-5.png b/tools/border-image-generator/border-image-5.png new file mode 100644 index 0000000000000000000000000000000000000000..0598418374627b632f9d5319bd6b7c0e2e4ec549 GIT binary patch literal 577 zcmeAS@N?(olHy`uVBq!ia0vp^DImgIgWzUjPjeE(!7rhKL}O44Z22a4;}1 z)_b}*hE&{ob2B>skO5CyBJ*1B1Ut1 ze)O()XR_=5Cj2YfuvUl1{nPeeHw&g4ylU#1U&E+$Xvc&ly-R+@P3Imc|N4xha{f^Wp`f6Ui!@`$f*%Ok#ClgE5LTORXumptO@`tpdc zv*a;fWx%dN_PeorcQh-Bl@o^lWy(F4h?jr%wttsa^-1~vnNv0A*NZ=U&;EAD?>~M& zii7_bIxzPLmCthPvkq0(^@x4!Fr`=aqM6d7JQkPxA50E_P?131s|Rh;KejV4Gq5d5 VF(` \ No newline at end of file diff --git a/tools/border-image-generator/checked.png b/tools/border-image-generator/checked.png new file mode 100644 index 0000000000000000000000000000000000000000..cd8e86540f89489d36d6cc9a5ab9033999a3b11e GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@5Lt z8c`CQpH@hp7|JyUG&S<>H zX285rQkCrt`y+b?8K*wR;(y8q{1y0)q%j!tot^wYxvBI8+Y087ye0Nbh5BM=Z#T~1 zy~!Y|P{%a&55tjT0UyhBX7Mu^s#i(KI0SzYJA2-sKqAt36JwFXpAYtR1w0*g03~Ot$DHFw2y=Y!%A_>zh7n2 RWq@vF@O1TaS?83{1ON%TT}uD} literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/close.png b/tools/border-image-generator/close.png new file mode 100644 index 0000000000000000000000000000000000000000..78bf9d7a5c8c721d5b64c07a18db15139e101fbd GIT binary patch literal 271 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@5Lt z8c`CQpH@;E0#mnmS1(pZPir03&wxYa{OlqIY|MX`rP>%!U{H7XB9D<@y_ikNlCXVQ-r6-POaPaX+s ziGiD>>O2Dk%#TT|Jiyi6!fQO&b<^U|XLrpuhc26Rq0%Sq+l*}$4E;MI1Z8@hj{@Dv N;OXk;vd$@?2>{3>T!sJu literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/config.png b/tools/border-image-generator/config.png new file mode 100644 index 0000000000000000000000000000000000000000..bd4c549baf392e412ced63f4376b54bc87cf6f51 GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@5Lt z8c`CQpH@h2izNIZ-c|6&K z`4N9Wj@uf>lMZtjQq!3})@z(|5$Zma>R>df?W)5cmd^hI9p*|OnK>mLINTq8I+SG+ zet==q52c(q2G$^{Nt?}+I5(7f-1BT^)$#enJWF`)28jo~%bqdYG4I(Z@u2ZM!whjb zC)Mi@KOPd!iEDV+o6-1!@#u@jZd2KmAgNx?jKHrlo&RM{a$5)sakMjUl%Kamrd!2- e_8Au=HikxKXDR00SCWA4X7F_Nb6Mw<&;$UL++^ec literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/disabled.png b/tools/border-image-generator/disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..1dd2c4c20a188993d385c72d92c3520685039a03 GIT binary patch literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstUx|vage(c z!@6@aFM*t>0G|+7_X3~)v;pxKV@?5Wku3@G3uX}I6T6icbmcf3`)6sn{PP!1f62Y^ zGd+WcSK!C>fVc0S0~Ho~x;TbNT<$&ZDb%3A!*ZabK|$-???3-%M=4jCZGRb})p=t5 zr(>-Tdg_bU9_$Kzb-yy~RMr;N#2vF;)i(7@aPWCMZY*fw)LOpAB2M5`*95mU0nbd5 z3f_qv5I7~a`0h5=3+JO&J}REEZvW-k>)!7^_P_cIll(&VU&sFcPykxb;OXk;vd$@? F2>=;FyV(E$ literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/drop_arrow_icon.png b/tools/border-image-generator/drop_arrow_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b4dffa3f8e6812934669ddae010e8388f050ed98 GIT binary patch literal 534 zcmV+x0_pvUP)*7I05Ee*FE>pV0db^TDu;jFFIIerBdPgCL51{N1!n_YMQnH!zcD}PfT1- ztExIB$2LuK(eoXmTrMXO;Tm`bZh@|4S$Q83^%UTI2hLD_7V7}eeMBkpY`tF31(p~F zfr%3=3<$BRP(0+jOd+vu`-rR%&Yr0Fl?ou=L{P*A+PXvKQS~vqfQTDGL>*`g zX>KSLh)Y3L$1wt@Y#VUT7XB&^HAHSRf7UUw-crl=k)q-_&T6$EEkPeSc-F%N zEC``EM{UlMZQEHwh&B*DT^4U*KxB|c1{qvf0q)%IXCUwbT+l}jxT!E1vd4Yk1Gq8_ zBZHRa2<*3Ddl0_9JXsS1mP(~0F6PBQ)|39T(d2dMBM00>)Gp68o6S9;sgC_x<$g2nmVNB{r; literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/grain.png b/tools/border-image-generator/grain.png new file mode 100644 index 0000000000000000000000000000000000000000..6aec29d1548370ba0d1b283ef01276610b424cc1 GIT binary patch literal 4716 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 u>|8zzz?VBuKM6s!_GYQm1#&MZhT + + + + + Border image generator + + + + + +
+ + + +
+ +
Upload image
+ +
+
+ +
+
Control Box
+
+
+
scale
+
+
+
+
+
+
draggable
+
+
+
+
section height
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ + +
+ + +
+
border-image-slice
+
+
fill
+
+
+
+ + +
+
border-image-width
+
+ + +
+
border-image-outset
+
+ + +
+
additional-properties
+
+
repeat-x
+
+
repeat
+
stretch
+
round
+
+
+
+
repeat-y
+
+
repeat
+
stretch
+
round
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
CSS Code
+
+ border-image-slice: + +
+
+ border-image-width: + +
+
+ border-image-outset: + +
+
+ border-image-repeat: + +
+
+ border-image-source: + +
+
+ border-style: + solid; +
+
+
+
+ + + + + diff --git a/tools/border-image-generator/resize.png b/tools/border-image-generator/resize.png new file mode 100644 index 0000000000000000000000000000000000000000..6a641c855bf2dfd20586edefdcb2dbe02c48a494 GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^93afZ3?z3ZhDiV^mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIBh0X`wF?gc)pR;@aJ{`~Xj&s&_M&VUq^1o;IsI6S+N2INS4x;Tb#Tu)9& rNJ@B+%Fw9BmKHCt_QH{Zo8k=olbM$Ar*bP0l+XkK24yRd literal 0 HcmV?d00001 diff --git a/tools/border-image-generator/script.js b/tools/border-image-generator/script.js new file mode 100644 index 00000000..62732a4b --- /dev/null +++ b/tools/border-image-generator/script.js @@ -0,0 +1,1393 @@ + +/** + * UI-SlidersManager + */ + +var InputSliderManager = (function InputSliderManager() { + + var subscribers = {}; + var sliders = []; + + var InputComponent = function InputComponent(obj) { + var input = document.createElement('input'); + input.setAttribute('type', 'text'); + input.style.width = 50 + obj.precision * 10 + 'px'; + + input.addEventListener('click', function(e) { + this.select(); + }); + + input.addEventListener('change', function(e) { + var value = parseFloat(e.target.value); + + if (isNaN(value) === true) + setValue(obj.topic, obj.value); + else + setValue(obj.topic, value); + }); + + return input; + }; + + var SliderComponent = function SliderComponent(obj, sign) { + var slider = document.createElement('div'); + var startX = null; + var start_value = 0; + + slider.addEventListener("click", function(e) { + document.removeEventListener("mousemove", sliderMotion); + setValue(obj.topic, obj.value + obj.step * sign); + }); + + slider.addEventListener("mousedown", function(e) { + startX = e.clientX; + start_value = obj.value; + document.body.style.cursor = "e-resize"; + + document.addEventListener("mouseup", slideEnd); + document.addEventListener("mousemove", sliderMotion); + }); + + var slideEnd = function slideEnd(e) { + document.removeEventListener("mousemove", sliderMotion); + document.body.style.cursor = "auto"; + slider.style.cursor = "pointer"; + }; + + var sliderMotion = function sliderMotion(e) { + slider.style.cursor = "e-resize"; + var delta = (e.clientX - startX) / obj.sensitivity | 0; + var value = delta * obj.step + start_value; + setValue(obj.topic, value); + }; + + return slider; + }; + + var InputSlider = function(node) { + var min = parseFloat(node.getAttribute('data-min')); + var max = parseFloat(node.getAttribute('data-max')); + var step = parseFloat(node.getAttribute('data-step')); + var value = parseFloat(node.getAttribute('data-value')); + var topic = node.getAttribute('data-topic'); + var unit = node.getAttribute('data-unit'); + var name = node.getAttribute('data-info'); + var sensitivity = node.getAttribute('data-sensitivity') | 0; + var precision = node.getAttribute('data-precision') | 0; + + this.min = isNaN(min) ? 0 : min; + this.max = isNaN(max) ? 100 : max; + this.precision = precision >= 0 ? precision : 0; + this.step = step < 0 || isNaN(step) ? 1 : step.toFixed(precision); + this.topic = topic; + this.node = node; + this.unit = unit === null ? '' : unit; + this.sensitivity = sensitivity > 0 ? sensitivity : 5; + value = isNaN(value) ? this.min : value; + + var input = new InputComponent(this); + var slider_left = new SliderComponent(this, -1); + var slider_right = new SliderComponent(this, 1); + + slider_left.className = 'ui-input-slider-left'; + slider_right.className = 'ui-input-slider-right'; + + if (name) { + var info = document.createElement('span'); + info.className = 'ui-input-slider-info'; + info.textContent = name; + node.appendChild(info); + } + + node.appendChild(slider_left); + node.appendChild(input); + node.appendChild(slider_right); + + this.input = input; + sliders[topic] = this; + setValue(topic, value); + }; + + InputSlider.prototype.setInputValue = function setInputValue() { + this.input.value = this.value.toFixed(this.precision) + this.unit; + }; + + var setValue = function setValue(topic, value, send_notify) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + value = parseFloat(value.toFixed(slider.precision)); + + if (value > slider.max) value = slider.max; + if (value < slider.min) value = slider.min; + + slider.value = value; + slider.node.setAttribute('data-value', value); + + slider.setInputValue(); + + if (send_notify === false) + return; + + notify.call(slider); + }; + + var setMax = function setMax(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.max = value; + setValue(topic, slider.value); + }; + + var setMin = function setMin(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.min = value; + setValue(topic, slider.value); + }; + + var setUnit = function setUnit(topic, unit) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.unit = unit; + setValue(topic, slider.value); + }; + + var setStep = function setStep(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.step = parseFloat(value); + setValue(topic, slider.value); + }; + + var setPrecision = function setPrecision(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + value = value | 0; + slider.precision = value; + + var step = parseFloat(slider.step.toFixed(value)); + if (step === 0) + slider.step = 1 / Math.pow(10, value); + + setValue(topic, slider.value); + }; + + var setSensitivity = function setSensitivity(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + value = value | 0; + + slider.sensitivity = value > 0 ? value : 5; + }; + + var getNode = function getNode(topic) { + return sliders[topic].node; + }; + + var getPrecision = function getPrecision(topic) { + return sliders[topic].precision; + }; + + var getStep = function getStep(topic) { + return sliders[topic].step; + }; + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + subscribers[topic].push(callback); + }; + + var unsubscribe = function unsubscribe(topic, callback) { + subscribers[topic].indexOf(callback); + subscribers[topic].splice(index, 1); + }; + + var notify = function notify() { + if (subscribers[this.topic] === undefined) + return; + for (var i = 0; i < subscribers[this.topic].length; i++) + subscribers[this.topic][i](this.value); + }; + + var createSlider = function createSlider(topic, label) { + var slider = document.createElement('div'); + slider.className = 'ui-input-slider'; + slider.setAttribute('data-topic', topic); + + if (label !== undefined) + slider.setAttribute('data-info', label); + + new InputSlider(slider); + return slider; + }; + + var init = function init() { + var elem = document.querySelectorAll('.ui-input-slider'); + var size = elem.length; + for (var i = 0; i < size; i++) + new InputSlider(elem[i]); + }; + + return { + init : init, + setMax : setMax, + setMin : setMin, + setUnit : setUnit, + setStep : setStep, + getNode : getNode, + getStep : getStep, + setValue : setValue, + subscribe : subscribe, + unsubscribe : unsubscribe, + setPrecision : setPrecision, + setSensitivity : setSensitivity, + getPrecision : getPrecision, + createSlider : createSlider, + }; + +})(); + +/** + * UI-DropDown Select + */ + +var DropDownManager = (function DropdownManager() { + + var subscribers = {}; + var dropdowns = []; + var active = null; + + var visibility = ["hidden", "visible"]; + + var DropDown = function DropDown(node) { + var topic = node.getAttribute('data-topic'); + var label = node.getAttribute('data-label'); + var selected = node.getAttribute('data-selected') | 0; + + var select = document.createElement('div'); + var list = document.createElement('div'); + var uval = 0; + var option = null; + var option_value = null; + + list.className = 'ui-dropdown-list'; + select.className = 'ui-dropdown-select'; + + while (node.firstElementChild !== null) { + option = node.firstElementChild; + option_value = option.getAttribute('data-value'); + + if (option_value === null) + option.setAttribute('data-value', uval); + + list.appendChild(node.firstElementChild); + uval++; + } + + node.appendChild(select); + node.appendChild(list); + + select.onclick = this.toggle.bind(this); + list.onclick = this.updateValue.bind(this); + document.addEventListener('click', clickOut); + + this.state = 0; + this.time = 0; + this.dropmenu = list; + this.select = select; + this.toggle(false); + this.value = {}; + this.topic = topic; + + if (label) + select.textContent = label; + else + this.setNodeValue(list.children[selected]); + + dropdowns[topic] = this; + + }; + + DropDown.prototype.toggle = function toggle(state) { + if (typeof(state) === 'boolean') + this.state = state === false ? 0 : 1; + else + this.state = 1 ^ this.state; + + if (active !== this) { + if (active) + active.toggle(false); + active = this; + } + + if (this.state === 0) + this.dropmenu.setAttribute('data-hidden', 'true'); + else + this.dropmenu.removeAttribute('data-hidden'); + + }; + + var clickOut = function clickOut(e) { + if (active.state === 0 || + e.target === active.dropmenu || + e.target === active.select) + return; + + active.toggle(false); + }; + + DropDown.prototype.updateValue = function updateValue(e) { + + if (Date.now() - this.time < 500) + return; + + if (e.target.className !== "ui-dropdown-list") { + this.setNodeValue(e.target); + this.toggle(false); + } + + this.time = Date.now(); + }; + + DropDown.prototype.setNodeValue = function setNodeValue(node) { + this.value['name'] = node.textContent; + this.value['value'] = node.getAttribute('data-value'); + + this.select.textContent = node.textContent; + this.select.setAttribute('data-value', this.value['value']); + + notify.call(this); + }; + + var createDropDown = function createDropDown(topic, options) { + + var dropdown = document.createElement('div'); + dropdown.setAttribute('data-topic', topic); + dropdown.className = 'ui-dropdown'; + + for (var i in options) { + var x = document.createElement('div'); + x.setAttribute('data-value', i); + x.textContent = options[i]; + dropdown.appendChild(x); + } + + new DropDown(dropdown); + + return dropdown; + }; + + var setValue = function setValue(topic, index) { + if (dropdowns[topic] === undefined || + index >= dropdowns[topic].dropmenu.children.length) + return; + + dropdowns[topic].setNodeValue(dropdowns[topic].dropmenu.children[index]); + }; + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + subscribers[topic].push(callback); + }; + + var unsubscribe = function unsubscribe(topic, callback) { + var index = subscribers[topic].indexOf(callback); + subscribers[topic].splice(index, 1); + }; + + var notify = function notify() { + if (subscribers[this.topic] === undefined) + return; + + for (var i in subscribers[this.topic]) { + subscribers[this.topic][i](this.value); + } + }; + + var init = function init() { + var elem, size; + + elem = document.querySelectorAll('.ui-dropdown'); + size = elem.length; + for (var i = 0; i < size; i++) + new DropDown(elem[i]); + + }; + + return { + init : init, + setValue : setValue, + subscribe : subscribe, + unsubscribe : unsubscribe, + createDropDown : createDropDown + }; + +})(); + +/** + * UI-ButtonManager + */ + +var ButtonManager = (function CheckBoxManager() { + + var subscribers = []; + var buttons = []; + + var CheckBox = function CheckBox(node) { + var topic = node.getAttribute('data-topic'); + var state = node.getAttribute('data-state'); + var name = node.getAttribute('data-label'); + var align = node.getAttribute('data-text-on'); + + state = (state === "true"); + + var checkbox = document.createElement("input"); + var label = document.createElement("label"); + + var id = 'checkbox-' + topic; + checkbox.id = id; + checkbox.setAttribute('type', 'checkbox'); + checkbox.checked = state; + + label.setAttribute('for', id); + if (name) { + label.className = 'text'; + if (align) + label.className += ' ' + align; + label.textContent = name; + } + + node.appendChild(checkbox); + node.appendChild(label); + + this.node = node; + this.topic = topic; + this.checkbox = checkbox; + + checkbox.addEventListener('change', function(e) { + notify.call(this); + }.bind(this)); + + buttons[topic] = this; + }; + + var getNode = function getNode(topic) { + return buttons[topic].node; + }; + + var setValue = function setValue(topic, value) { + var obj = buttons[topic]; + if (obj === undefined) + return; + + obj.checkbox.checked = value; + notify.call(obj); + }; + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + + subscribers[topic].push(callback); + }; + + var unsubscribe = function unsubscribe(topic, callback) { + subscribers[topic].indexOf(callback); + subscribers[topic].splice(index, 1); + }; + + var notify = function notify() { + if (subscribers[this.topic] === undefined) + return; + for (var i = 0; i < subscribers[this.topic].length; i++) + subscribers[this.topic][i](this.checkbox.checked); + }; + + var init = function init() { + var elem = document.querySelectorAll('.ui-checkbox'); + var size = elem.length; + for (var i = 0; i < size; i++) + new CheckBox(elem[i]); + }; + + return { + init : init, + setValue : setValue, + subscribe : subscribe, + unsubscribe : unsubscribe + }; + +})(); + +window.addEventListener("load", function() { + BorderImage.init(); +}); + +var BorderImage = (function BorderImage() { + + var getElemById = document.getElementById.bind(document); + + var subject; + var preview; + var guidelines = []; + var positions = ['top', 'right', 'bottom', 'left']; + + var makeDraggable = function makeDraggable(elem) { + + var offsetTop; + var offsetLeft; + + elem.setAttribute('data-draggable', 'true'); + + var dragStart = function dragStart(e) { + if (e.target.getAttribute('data-draggable') !== 'true' || + e.target !== elem || e.button !== 0) + return; + + offsetLeft = e.clientX - elem.offsetLeft; + offsetTop = e.clientY - elem.offsetTop; + + document.addEventListener('mousemove', mouseDrag); + document.addEventListener('mouseup', dragEnd); + }; + + var dragEnd = function dragEnd(e) { + if (e.button !== 0) + return; + + document.removeEventListener('mousemove', mouseDrag); + document.removeEventListener('mouseup', dragEnd); + }; + + var mouseDrag = function mouseDrag(e) { + + elem.style.left = e.clientX - offsetLeft + 'px'; + elem.style.top = e.clientY - offsetTop + 'px'; + }; + + elem.addEventListener('mousedown', dragStart, false); + }; + + var PreviewControl = function PreviewControl() { + + var dragging = false; + var valueX = null; + var valueY = null; + + var dragStart = function dragStart(e) { + if (e.button !== 0) + return; + + valueX = e.clientX - preview.clientWidth; + valueY = e.clientY - preview.clientHeight; + dragging = true; + + document.addEventListener('mousemove', mouseDrag); + }; + + var dragEnd = function dragEnd(e) { + if (e.button !== 0 || dragging === false) + return; + + document.removeEventListener('mousemove', mouseDrag); + dragging = false; + }; + + var mouseDrag = function mouseDrag(e) { + InputSliderManager.setValue('preview-width', e.clientX - valueX); + InputSliderManager.setValue('preview-height', e.clientY - valueY); + }; + + var init = function init() { + + makeDraggable(preview); + makeDraggable(subject); + + var handle = document.createElement('div'); + handle.className = 'resize-handle'; + + handle.addEventListener('mousedown', dragStart); + document.addEventListener('mouseup', dragEnd); + + preview.appendChild(handle); + + }; + + return { + init: init + }; + + }(); + + var ImageReader = (function ImageReader() { + + var fReader = new FileReader(); + var browse = document.createElement('input'); + + var loadImage = function loadImage(e) { + if (browse.files.length === 0) + return; + + var file = browse.files[0]; + + if (file.type.slice(0, 5) !== 'image') + return; + + fReader.readAsDataURL(file); + + return false; + }; + + fReader.onload = function(e) { + ImageControl.loadRemoteImage(e.target.result); + }; + + var load = function load() { + browse.click(); + }; + + browse.setAttribute('type', 'file'); + browse.style.display = 'none'; + browse.onchange = loadImage; + + return { + load: load + }; + + })(); + + var ImageControl = (function ImageControl() { + + var scale = 0.5; + var imgSource = new Image(); + var imgState = null; + var selected = null; + + var topics = ['slice', 'width', 'outset']; + var properties = {}; + properties['border1'] = { + fill : false, + + slice_values : [27, 27, 27, 27], + width_values : [20, 20, 20, 20], + outset_values : [0, 0, 0, 0], + + slice_units : [0, 0, 0, 0], + width_units : [0, 0, 0, 0], + outset_units : [0, 0, 0, 0], + + repeat : [1, 1], + size : [300, 200], + preview_area : 400 + }; + + properties['border2'] = { + fill : false, + + slice_values : [33, 33, 33, 33], + width_values : [1.5, 1.5, 1.5, 1.5], + outset_values : [0, 0, 0, 0], + + slice_units : [1, 1, 1, 1], + width_units : [2, 2, 2, 2], + outset_units : [0, 0, 0, 0], + + repeat : [2, 2], + size : [300, 200], + preview_area : 400 + }; + + properties['border3'] = { + fill : true, + + slice_values : [15, 15, 15, 15], + width_values : [10, 10, 10, 10], + outset_values : [0, 0, 0, 0], + + slice_units : [0, 0, 0, 0], + width_units : [0, 0, 0, 0], + outset_units : [0, 0, 0, 0], + + repeat : [2, 2], + size : [300, 200], + preview_area : 400 + }; + + properties['border4'] = { + fill : false, + + slice_values : [13, 13, 13, 13], + width_values : [13, 13, 13, 13], + outset_values : [13, 13, 13, 13], + + slice_units : [0, 0, 0, 0], + width_units : [0, 0, 0, 0], + outset_units : [0, 0, 0, 0], + + repeat : [0, 0], + size : [300, 200], + preview_area : 400 + }; + + properties['border5'] = { + fill : false, + + slice_values : [12, 12, 12, 12], + width_values : [12, 12, 12, 12], + outset_values : [0, 0, 0, 0], + + slice_units : [0, 0, 0, 0], + width_units : [0, 0, 0, 0], + outset_units : [0, 0, 0, 0], + + repeat : [0, 0], + size : [300, 200], + preview_area : 400, + }; + + properties['border6'] = { + fill : false, + + slice_values : [42, 42, 42, 42], + width_values : [42, 42, 42, 42], + outset_values : [0, 0, 0, 0], + + slice_units : [0, 0, 0, 0], + width_units : [0, 0, 0, 0], + outset_units : [0, 0, 0, 0], + + repeat : [2, 2], + size : [350, 350], + preview_area : 500, + }; + + var loadLocalImage = function loadLocalImage(source) { + var location = "images/" + source; + imgSource.src = location; + }; + + var loadRemoteImage = function loadRemoteImage(source) { + imgSource.src = source; + if (selected) + selected.removeAttribute('selected'); + Tool.setOutputCSS('source', 'url("' + source + '")'); + }; + + var pickImage = function pickImage(e) { + if (e.target.className === 'image') { + selected = e.target; + selected.setAttribute('selected', 'true'); + loadRemoteImage(e.target.src); + imgState = e.target.getAttribute('data-stateID'); + } + }; + + var loadImageState = function loadImageState(stateID) { + if (properties[stateID] === undefined) + return; + + var prop = properties[stateID]; + var topic; + var unit_array; + var value_array; + + for (var i in topics) { + for (var j=0; j<4; j++) { + topic = topics[i] + '-' + positions[j]; + unit_array = topics[i] + '_units'; + value_array = topics[i] + '_values'; + InputSliderManager.setValue(topic, prop[value_array][j]); + DropDownManager.setValue(topic, prop[unit_array][j]); + } + } + + ButtonManager.setValue('slice-fill', prop['fill']); + DropDownManager.setValue('image-repeat-X', prop['repeat'][0]); + DropDownManager.setValue('image-repeat-Y', prop['repeat'][1]); + InputSliderManager.setValue('preview-width', prop['size'][0]); + InputSliderManager.setValue('preview-height', prop['size'][1]); + InputSliderManager.setValue('preview-area-height', prop['preview_area']); + }; + + var update = function update() { + scale = Math.min(300, (30000 / this.width) | 0); + setScale(scale); + InputSliderManager.setValue('scale', scale, false); + + subject.style.backgroundImage = 'url("' + this.src + '")'; + preview.style.borderImageSource = 'url("' + this.src + '")'; + + guidelines['slice-top'].setMax(this.height); + guidelines['slice-right'].setMax(this.width); + guidelines['slice-bottom'].setMax(this.height); + guidelines['slice-left'].setMax(this.width); + + if (imgState) + loadImageState(imgState); + }; + + var setScale = function setScale(value) { + scale = value; + var w = imgSource.width * scale / 100 | 0; + var h = imgSource.height * scale / 100 | 0; + subject.style.width = w + 'px'; + subject.style.height = h + 'px'; + + for (var i = 0; i < positions.length; i++) + guidelines['slice-' + positions[i]].updateGuidelinePos(); + }; + + var getScale = function getScale() { + return scale/100; + }; + + var toggleGallery = function toggleGallery() { + var gallery = getElemById('image-gallery'); + var button = getElemById('toggle-gallery'); + var state = 1; + button.addEventListener('click', function() { + state = 1 ^ state; + if (state === 0) { + gallery.setAttribute('data-collapsed', 'true'); + button.setAttribute('data-action', 'show'); + } + else { + gallery.removeAttribute('data-collapsed'); + button.setAttribute('data-action', 'hide'); + } + }); + }; + + var init = function init() { + var gallery = getElemById('image-gallery'); + var browse = getElemById('load-image'); + var remote = getElemById('remote-url'); + var load_remote = getElemById('load-remote'); + + remote.addEventListener('change', function(){ + loadRemoteImage(this.value); + }); + + load_remote.addEventListener('click', function(){ + loadRemoteImage(remote.value); + }); + + browse.addEventListener('click', ImageReader.load); + gallery.addEventListener('click', pickImage); + imgSource.addEventListener('load', update); + + InputSliderManager.subscribe('scale', setScale); + InputSliderManager.setValue('scale', scale); + imgState = 'border1'; + loadRemoteImage('border-image-1.png'); + toggleGallery(); + }; + + return { + init: init, + getScale : getScale, + loadRemoteImage: loadRemoteImage + }; + + })(); + + var GuideLine = function GuideLine(node) { + var topic = node.getAttribute('data-topic'); + var axis = node.getAttribute('data-axis'); + + this.node = node; + this.topic = topic; + this.axis = axis; + this.info = topic.split('-')[1]; + + this.position = 0; + this.value = 0; + this.unit = 0; + this.max = 0; + this.pos = positions.indexOf(this.info); + + guidelines[topic] = this; + + var relative_container = document.createElement('div'); + var tooltip = document.createElement('div'); + var tooltip2 = document.createElement('div'); + + tooltip.className = 'tooltip'; + tooltip.setAttribute('data-info', this.info); + + tooltip2.className = 'tooltip2'; + tooltip2.textContent = this.info; + tooltip2.setAttribute('data-info', this.info); + + this.tooltip = tooltip; + + relative_container.appendChild(tooltip); + relative_container.appendChild(tooltip2); + node.appendChild(relative_container); + + var startX = 0; + var startY = 0; + var start = 0; + + var startDrag = function startDrag(e) { + startX = e.clientX; + startY = e.clientY; + start = guidelines[topic].position; + document.body.setAttribute('data-move', axis); + relative_container.setAttribute('data-active', ''); + node.setAttribute('data-active', ''); + + document.addEventListener('mousemove', updateGuideline); + document.addEventListener('mouseup', endDrag); + }; + + var endDrag = function endDrag() { + document.body.removeAttribute('data-move'); + relative_container.removeAttribute('data-active'); + node.removeAttribute('data-active'); + + document.removeEventListener('mousemove', updateGuideline); + }; + + var updateGuideline = function updateGuideline(e) { + var value; + if (topic === 'slice-top') + value = e.clientY - startY + start; + + if (topic === 'slice-right') + value = startX - e.clientX + start; + + if (topic === 'slice-bottom') + value = startY - e.clientY + start; + + if (topic === 'slice-left') + value = e.clientX - startX + start; + + if (this.unit === 0) + InputSliderManager.setValue(topic, value * 1 / ImageControl.getScale() | 0); + else { + InputSliderManager.setValue(topic, (value * 100 / (this.max * ImageControl.getScale())) | 0); + } + + }.bind(this); + + node.addEventListener("mousedown", startDrag); + + InputSliderManager.subscribe(topic, this.setPosition.bind(this)); + InputSliderManager.setValue(topic, this.position); + }; + + GuideLine.prototype.updateGuidelinePos = function updateGuidelinePos() { + if (this.unit === 0) + this.position = this.value * ImageControl.getScale() | 0; + else + this.position = this.value * this.max * ImageControl.getScale() / 100 | 0; + + this.node.style[this.info] = this.position + 'px'; + }; + + GuideLine.prototype.setPosition = function setPosition(value) { + this.value = value; + this.tooltip.textContent = value; + this.updateGuidelinePos(); + Tool.setBorderSlice(this.pos, value); + }; + + GuideLine.prototype.setMax = function setMax(max) { + this.max = max; + this.updateLimit(); + }; + + GuideLine.prototype.updateLimit = function updateLimit() { + if (this.unit === 1) + InputSliderManager.setMax(this.topic, 100); + else + InputSliderManager.setMax(this.topic, this.max); + }; + + GuideLine.prototype.setUnit = function setUnit(type) { + if (type === '%') this.unit = 1; + if (type === '') this.unit = 0; + this.updateLimit(); + }; + + /* + * Unit panel + */ + var UnitPanel = (function UnitPanel () { + + var panel; + var title; + var precision; + var step; + var unit_topic = null; // settings are made for this topic + var step_option = [1, 0.1, 0.01]; + + var updatePrecision = function updatePrecision(value) { + InputSliderManager.setPrecision('unit-step', value); + InputSliderManager.setStep('unit-step', step_option[value]); + InputSliderManager.setMin('unit-step', step_option[value]); + + if (unit_topic) + InputSliderManager.setPrecision(unit_topic, value); + }; + + var updateUnitSettings = function updateUnitSettings(value) { + if (unit_topic) + InputSliderManager.setStep(unit_topic, value); + }; + + var show = function show(e) { + var topic = e.target.getAttribute('data-topic'); + var precision = InputSliderManager.getPrecision(topic); + var step = InputSliderManager.getStep(topic); + + unit_topic = topic; + title.textContent = topic; + + panel.setAttribute('data-active', 'true'); + panel.style.top = e.target.offsetTop - 40 + 'px'; + panel.style.left = e.target.offsetLeft + 30 + 'px'; + + InputSliderManager.setValue('unit-precision', precision); + InputSliderManager.setValue('unit-step', step); + }; + + var init = function init() { + panel = document.createElement('div'); + title = document.createElement('div'); + var close = document.createElement('div'); + + step = InputSliderManager.createSlider('unit-step', 'step'); + precision = InputSliderManager.createSlider('unit-precision', 'precision'); + + InputSliderManager.setStep('unit-precision', 1); + InputSliderManager.setMax('unit-precision', 2); + InputSliderManager.setValue('unit-precision', 2); + InputSliderManager.setSensitivity('unit-precision', 20); + + InputSliderManager.setValue('unit-step', 1); + InputSliderManager.setStep('unit-step', 0.01); + InputSliderManager.setPrecision('unit-step', 2); + + InputSliderManager.subscribe('unit-precision', updatePrecision); + InputSliderManager.subscribe('unit-step', updateUnitSettings); + + close.addEventListener('click', function () { + panel.setAttribute('data-active', 'false'); + }); + + title.textContent = 'Properties'; + title.className = 'title'; + close.className = 'close'; + panel.id = 'unit-settings'; + panel.setAttribute('data-active', 'false'); + panel.appendChild(title); + panel.appendChild(precision); + panel.appendChild(step); + panel.appendChild(close); + document.body.appendChild(panel); + }; + + return { + init : init, + show : show + }; + + })(); + + /** + * Tool Manager + */ + var Tool = (function Tool() { + var preview_area; + var dropdown_unit_options = [ + { '' : '--', '%' : '%'}, + { 'px' : 'px', '%' : '%', 'em' : 'em'}, + { 'px' : 'px', 'em' : 'em'}, + ]; + + var border_slice = []; + var border_width = []; + var border_outset = []; + + var border_slice_values = []; + var border_width_values = []; + var border_outset_values = []; + + var border_slice_units = ['', '', '', '']; + var border_width_units = ['px', 'px', 'px', 'px']; + var border_outset_units = ['px', 'px', 'px', 'px']; + + var border_fill = false; + var border_repeat = ['round', 'round']; + var CSS_code = { + 'source' : null, + 'slice' : null, + 'width' : null, + 'outset' : null, + 'repeat' : null + }; + + var setBorderSlice = function setBorderSlice(positionID, value) { + border_slice[positionID] = value + border_slice_units[positionID]; + updateBorderSlice(); + }; + + var updateBorderSlice = function updateBorderSlice() { + var value = border_slice.join(' '); + if (border_fill === true) + value += ' fill'; + + preview.style.borderImageSlice = value; + setOutputCSS('slice', value); + }; + + var setBorderFill = function setBorderFill(value) { + border_fill = value; + var bimgslice = border_slice.join(' ');; + if (value === true) + bimgslice += ' fill'; + + preview.style.borderImageSlice = bimgslice; + }; + + var updateBorderWidth = function updateBorderWidth() { + var value = border_width.join(' '); + preview.style.borderImageWidth = value; + setOutputCSS('width', value); + }; + + var updateBorderOutset = function updateBorderOutset() { + var value = border_outset.join(' '); + preview.style.borderImageOutset = border_outset.join(' '); + setOutputCSS('outset', value); + }; + + var setBorderRepeat = function setBorderRepeat(obj) { + border_repeat[obj.value] = obj.name; + var value = border_repeat.join(' '); + preview.style.borderImageRepeat = value; + setOutputCSS('repeat', value); + }; + + var setOutputCSS = function setOutputCSS(topic, value) { + CSS_code[topic].textContent = value + ';'; + }; + + var setPreviewFontSize = function setPreviewFontSize(value) { + preview.style.fontSize = value + 'px'; + }; + + var setPreviewWidth = function setPreviewWidth(value) { + preview.style.width = value + 'px'; + }; + + var setPreviewHeight = function setPreviewHeight(value) { + preview.style.height = value + 'px'; + }; + + var setPreviewAreaHeight = function setPreviewAreaHeight(value) { + preview_area.style.height = value + 'px'; + }; + + var updateDragOption = function updateDragOption(value) { + if (value === true) + subject.setAttribute('data-draggable', 'true'); + else + subject.removeAttribute('data-draggable'); + }; + + var createProperty = function createProperty(topic, labelID, optionsID) { + + var slider = InputSliderManager.createSlider(topic, positions[labelID]); + var dropdown = DropDownManager.createDropDown(topic, dropdown_unit_options[optionsID]); + + InputSliderManager.setSensitivity(topic, 3); + InputSliderManager.setPrecision(topic, 1); + + var property = document.createElement('div'); + var config = document.createElement('div'); + + property.className = 'property'; + config.className = 'config'; + config.setAttribute('data-topic', topic); + config.addEventListener('click', UnitPanel.show); + + property.appendChild(slider); + property.appendChild(dropdown); + property.appendChild(config); + + return property; + }; + + var initBorderSliceControls = function initBorderSliceControls() { + var container = getElemById('border-slice-control'); + + var listenForChanges = function listenForChanges(topic, id) { + InputSliderManager.subscribe(topic, function(value) { + border_slice_values[id] = value; + border_slice[id] = value + border_slice_units[id]; + updateBorderSlice(); + }); + + DropDownManager.subscribe(topic, function(obj) { + guidelines[topic].setUnit(obj.value); + border_slice_units[id] = obj.value; + border_slice[id] = border_slice_values[id] + obj.value; + updateBorderSlice(); + }); + }; + + for (var i = 0; i < positions.length; i++) { + var topic = 'slice-' + positions[i]; + var property = createProperty(topic, i, 0); + listenForChanges(topic, i); + + container.appendChild(property); + } + + container.appendChild(container.children[1]); + + }; + + var initBorderWidthControls = function initBorderWidthControls() { + var container = getElemById('border-width-control'); + + var listenForChanges = function listenForChanges(topic, id) { + InputSliderManager.subscribe(topic, function(value) { + border_width_values[id] = value; + border_width[id] = value + border_width_units[id]; + updateBorderWidth(); + }); + + DropDownManager.subscribe(topic, function(obj) { + if (obj.value === '%') + InputSliderManager.setMax(topic, 100); + else + InputSliderManager.setMax(topic, 1000); + + border_width_units[id] = obj.value; + border_width[id] = border_width_values[id] + obj.value; + updateBorderWidth(); + }); + }; + + for (var i = 0; i < positions.length; i++) { + var topic = 'width-' + positions[i]; + var property = createProperty(topic, i, 1); + InputSliderManager.setMax(topic, 1000); + listenForChanges(topic, i); + + container.appendChild(property); + } + }; + + var initBorderOutsetControls = function initBorderOutsetControls() { + + var container = getElemById('border-outset-control'); + + var listenForChanges = function listenForChanges(topic, id) { + InputSliderManager.subscribe(topic, function(value) { + border_outset_values[id] = value; + border_outset[id] = value + border_outset_units[id]; + updateBorderOutset(); + }); + + DropDownManager.subscribe(topic, function(obj) { + border_outset_units[id] = obj.value; + border_outset[id] = border_outset_values[id] + obj.value; + updateBorderOutset(); + }); + }; + + for (var i = 0; i < positions.length; i++) { + var topic = 'outset-' + positions[i]; + var property = createProperty(topic, i, 2); + InputSliderManager.setMax(topic, 1000); + listenForChanges(topic, i); + + container.appendChild(property); + } + }; + + var init = function init() { + + var gallery = + subject = getElemById('subject'); + preview = getElemById("preview"); + preview_area = getElemById("preview_section"); + + CSS_code['source'] = getElemById("out-border-source"); + CSS_code['slice'] = getElemById("out-border-slice"); + CSS_code['width'] = getElemById("out-border-width"); + CSS_code['outset'] = getElemById("out-border-outset"); + CSS_code['repeat'] = getElemById("out-border-repeat"); + + initBorderSliceControls(); + initBorderWidthControls(); + initBorderOutsetControls(); + + var elem = document.querySelectorAll('.guideline'); + var size = elem.length; + for (var i = 0; i < size; i++) + new GuideLine(elem[i]); + + PreviewControl.init(); + + ButtonManager.subscribe('slice-fill',setBorderFill); + ButtonManager.subscribe('drag-subject', updateDragOption); + ButtonManager.setValue('drag-subject', false); + + DropDownManager.subscribe('image-repeat-X', setBorderRepeat); + DropDownManager.subscribe('image-repeat-Y', setBorderRepeat); + + InputSliderManager.subscribe('preview-area-height', setPreviewAreaHeight); + InputSliderManager.subscribe('preview-width', setPreviewWidth); + InputSliderManager.subscribe('preview-height', setPreviewHeight); + InputSliderManager.subscribe('font-size', setPreviewFontSize); + InputSliderManager.setValue('preview-width', 300); + InputSliderManager.setValue('preview-height', 200); + }; + + return { + init: init, + setOutputCSS: setOutputCSS, + setBorderSlice: setBorderSlice + }; + + })(); + + /** + * Init Tool + */ + var init = function init() { + InputSliderManager.init(); + DropDownManager.init(); + ButtonManager.init(); + UnitPanel.init(); + Tool.init(); + ImageControl.init(); + }; + + return { + init : init + }; + +})(); diff --git a/tools/border-image-generator/styles.css b/tools/border-image-generator/styles.css new file mode 100644 index 00000000..b9b2f233 --- /dev/null +++ b/tools/border-image-generator/styles.css @@ -0,0 +1,1047 @@ +/* GRID OF TWELVE + * ========================================================================== */ + +.span_12 { + width: 100%; +} + +.span_11 { + width: 91.46%; +} + +.span_10 { + width: 83%; +} + +.span_9 { + width: 74.54%; +} + +.span_8 { + width: 66.08%; +} + +.span_7 { + width: 57.62%; +} + +.span_6 { + width: 49.16%; +} + +.span_5 { + width: 40.7%; +} + +.span_4 { + width: 32.24%; +} + +.span_3 { + width: 23.78%; +} + +.span_2 { + width: 15.32%; +} + +.span_1 { + width: 6.86%; +} + +/* SECTIONS + * ========================================================================== */ + +.section { + clear: both; + padding: 0px; + margin: 0px; +} + +/* GROUPING + * ========================================================================== */ + +.group:before, .group:after { + content: ""; + display: table; +} + +.group:after { + clear:both; +} + +.group { + zoom: 1; /* For IE 6/7 (trigger hasLayout) */ +} + +/* GRID COLUMN SETUP + * ========================================================================== */ + +.col { + display: block; + float:left; + margin: 1% 0 1% 1.6%; +} + +.col:first-child { + margin-left: 0; +} /* all browsers except IE6 and lower */ + +/* + * UI Component + */ + +.ui-input-slider { + height: 20px; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + -moz-user-select: none; + user-select: none; +} + +.ui-input-slider * { + float: left; + height: 100%; + line-height: 100%; +} + +/* Input Slider */ + +.ui-input-slider > input { + margin: 0; + padding: 0; + width: 50px; + text-align: center; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.ui-input-slider-info { + width: 90px; + padding: 0px 10px 0px 0px; + text-align: right; + text-transform: lowercase; +} + +.ui-input-slider-left, .ui-input-slider-right { + width: 16px; + cursor: pointer; + background: url("arrows.png") center left no-repeat; +} + +.ui-input-slider-right { + background: url("arrows.png") center right no-repeat; +} + +.ui-input-slider-name { + width: 90px; + padding: 0 10px 0 0; + text-align: right; + text-transform: lowercase; +} + +.ui-input-slider-btn-set { + width: 25px; + background-color: #2C9FC9; + border-radius: 5px; + color: #FFF; + font-weight: bold; + line-height: 14px; + text-align: center; +} + +.ui-input-slider-btn-set:hover { + background-color: #379B4A; + cursor: pointer; +} + +/*************************************************************************************/ +/*************************************************************************************/ + +/* + * UI DropDown + */ + +/* Dropdown */ + +.ui-dropdown { + height: 2em; + width: 120px; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + font-size: 12px; + + background-image: url("drop_arrow_icon.png"); + background-position: right center; + background-repeat: no-repeat; + background-color: #359740; + + position: relative; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.ui-dropdown:hover { + cursor: pointer; + background-color: #208B20; +} + +/* Dropdown Select Button */ + +.ui-dropdown-select { + height: inherit; + padding: 0 0.75em; + color: #FFF; + line-height: 2em; +} + +/* Dropdown List */ + +.ui-dropdown-list { + width: 100%; + height: 150px; + max-height: 150px; + margin: 0; + padding: 0 0.3em; + + border: 3px solid #3490D2; + border-color: #208B20; + background: #666; + background-color: #EEF1F5; + color: #000; + + position: absolute; + top: 2em; + left: 0; + z-index: 100; + + overflow: hidden; + transition: all 0.3s; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.ui-dropdown-list:hover { + overflow: auto; +} + +.ui-dropdown-list[data-hidden='true'] { + height: 0 !important; + opacity: 0; + visibility: hidden; +} + +.ui-dropdown[data-position='left'] .ui-dropdown-list { + left: -100%; + top: 0; +} + +.ui-dropdown[data-position='right'] .ui-dropdown-list { + left: 100%; + top: 0; +} + +.ui-dropdown-list > div { + width: 100%; + height: 1.6em; + margin: 0.3em 0; + padding: 0.3em; + line-height: 1em; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.ui-dropdown-list > div:hover { + background: #3490D2; + color:#FFF; + border-radius: 2px; + cursor: pointer; +} + +/*************************************************************************************/ +/*************************************************************************************/ + +/* + * UI Button + */ + +/* Checkbox */ + +.ui-checkbox { + text-align: center; + font-size: 16px; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + line-height: 1.5em; + color: #FFF; + + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.ui-checkbox > input { + display: none; +} + +.ui-checkbox > label { + font-size: 12px; + padding: 0.333em 1.666em 0.5em; + height: 1em; + line-height: 1em; + + background-color: #888; + background-image: url("disabled.png"); + background-position: center center; + background-repeat: no-repeat; + + color: #FFF; + border-radius: 2px; + font-weight: bold; + float: left; +} + +.ui-checkbox .text { + padding-left: 34px; + background-position: center left 10px; +} + +.ui-checkbox .left { + padding-right: 34px; + padding-left: 1.666em; + background-position: center right 10px; +} + +.ui-checkbox > label:hover { + cursor: pointer; +} + +.ui-checkbox > input:checked + label { + background-image: url("checked.png"); + background-color: #379B4A; +} + +/*************************************************************************************/ +/*************************************************************************************/ + +/* + * BORDER IMAGE GENERATOR TOOL + */ + +body { + width: 100%; + margin: 0 auto; + padding: 0 0 20px 0; + + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + + /*background: url("grain.png");*/ + border: 1px solid #EEE; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +body[data-move='X'] { + cursor: w-resize !important; +} + +body[data-move='Y'] { + cursor: s-resize !important; +} + +#container { + width: 100%; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +[data-draggable='true']:hover { + cursor: move; +} + +[data-draggable='true']:hover > * { + cursor: default; +} + +/******************************************************************************/ +/******************************************************************************/ + +/* + * Border Image Picker + */ + +#gallery { + box-shadow: 0 0 3px 0 #BABABA; +} + +#image-gallery { + width: 600px; + height: 100px; + margin: 0 auto; + transition: margin 0.4s; +} + +#image-gallery .image { + height: 80px; + float: left; + margin: 10px; + opacity: 0.5; + background-color: #FFF; + box-shadow: 0px 0px 3px 1px #BABABA; +} + +#image-gallery .image[selected="true"] { + box-shadow: 0px 0px 3px 1px #3BBA52; + opacity: 1; +} + +#image-gallery .image:hover { + cursor: pointer; + box-shadow: 0px 0px 3px 1px #30ACE5; + opacity: 1; +} + +#image-gallery[data-collapsed='true'] { + margin-top: -100px; +} + +/* Load Menu */ + +#load-actions { + margin: 10px 0; +} + +#toggle-gallery { + width: 30px; + height: 25px; + margin: 10px; + color: #FFF; + + background-image: url('arrow-up-white.png'); + background-repeat: no-repeat; + background-position: top 4px center; + background-color: #888888 !important; + + border-radius: 2px; + float: left; +} + +#toggle-gallery:hover { + cursor: pointer; +} + +#toggle-gallery[data-action='show'] { + background-image: url('arrow-down-white.png'); + background-color: #888888 !important; +} + +#toggle-gallery[data-action='hide'] { + background-image: url('arrow-up-white.png'); +} + +.button { + width: 100px; + height: 25px; + margin: 10px; + color: #FFF; + text-align: center; + font-size: 12px; + line-height: 25px; + background-color: #379B4A; + border-radius: 2px; + float: left; +} + +.button:hover { + cursor: pointer; + background-color: #3380C4; +} + +#load-image { + float: left; +} + +#load-remote { + width: 30px; + background-image: url('arrow-right-white.png'); + background-repeat: no-repeat; + background-position: center center; +} + +#remote-url { + width: 200px; + height: 23px; + margin: 10px; + padding: 0 5px; + border: 1px solid #379B4A; + border-radius: 2px; + float: left; + + transition: width 0.5s; +} + +#remote-url:focus { + box-shadow: 0px 0px 3px -1px #379B4A; /*#68ACE8; */ + border-color: rgba(55, 155, 74, 0.5); + width: 450px; +} + +/* + * Visible Area + */ + +#preview_section { + position: relative; + min-height: 400px; +} + +/* Image Control */ + +#subject { + width: 300px; + height: 300px; + background-repeat: no-repeat; + background-size: 100%; + background-color: #FFF; + border: 1px solid #CCC; + + position: absolute; + z-index: 10; + top: 15%; + left: 10%; + + box-shadow: 0 0 3px 0 #BABABA; + transition-property: width, height; + transition-duration: 0.1s; +} + +#subject .guideline { + background-color: rgba(255, 255, 255, 0.7); + border: 1px solid rgba(0, 0, 0, 0.3); + position: absolute; +} + +#subject .guideline:hover { + background-color: #F00; +} + +#subject .guideline[data-active] { + background-color: #F00; + z-index: 10; +} + +#subject .guideline[data-axis='X'] { + width: 1px; + height: 100%; + top: -1px; +} + +#subject .guideline[data-axis='Y'] { + width: 100%; + height: 1px; + left: -1px; +} + +#subject .guideline[data-axis='X']:hover { + cursor: w-resize; +} + +#subject .guideline[data-axis='Y']:hover { + cursor: s-resize; +} + +#subject .relative { + position: relative; + font-size: 12px; +} + +#subject .tooltip, #subject .tooltip2 { + width: 40px; + height: 20px; + line-height: 20px; + font-size: 12px; + text-align: center; + + position: absolute; + opacity: 0.5; + transition: opacity 0.25s; +} + +#subject .tooltip { + background: #EEE; + border-radius: 2px; + border: 1px solid #CCC; +} + +#subject .tooltip2{ + color: #555; +} + +#subject [data-active] > * { + opacity: 1; +} + +#subject .tooltip[data-info='top'] { + top: -10px; + right: -50px; +} + +#subject .tooltip[data-info='right'] { + bottom: -30px; + right: -20px; +} + +#subject .tooltip[data-info='bottom'] { + top: -10px; + left: -50px; +} + +#subject .tooltip[data-info='left'] { + top: -30px; + right: -20px; +} + +#subject .tooltip2[data-info='top'] { + top: -10px; + left: -50px; +} + +#subject .tooltip2[data-info='right'] { + top: -30px; + right: -20px; +} + +#subject .tooltip2[data-info='bottom'] { + top: -10px; + right: -50px; +} + +#subject .tooltip2[data-info='left'] { + bottom: -30px; + right: -20px; +} + +/* Preview */ + +#preview { + width: 30%; + height: 50%; + background-color: #FFF; + text-align: center; + overflow: hidden; + position: absolute; + z-index: 10; + + left: 60%; + top: 15%; + + border-radius: 2px; + border-image-width: 20px; + border-image-repeat: round; + border-style: solid; + box-shadow: 0 0 3px 0 #BABABA; +} + +#preview .resize-handle { + width: 10px; + height: 10px; + background: url("resize.png") center center no-repeat; + position: absolute; + bottom: 0; + right: 0; +} + +#preview .resize-handle:hover { + cursor: nw-resize; +} + +/* + * General controls MENU + */ + +#general-controls { + padding: 10px 30px; + background-color: #FFF; + opacity: 0.95; + color: #888; + /*border-radius: 2px;*/ + box-shadow: 0 0 3px 0 #BABABA; +} + +#general-controls .property { + width: 130px; + float: left; +} + +#general-controls .name { + height: 20px; + margin: 0 10px 0 0; + line-height: 100%; + text-align: right; + float: left; +} + +#general-controls .right { + width: 200px; + float: right; +} + +#general-controls .ui-checkbox label { + height: 10px; +} + +#general-controls .separator { + height: 40px; + width: 1px; + margin: -10px 15px; + background-color: #EEE; + float: left; +} + +/* + * Controls + */ + +#controls { + color: #444; + margin: 10px 0 0 0; +} + +#controls .category { + height: 190px; + min-width: 260px; + margin: 10px; + padding: 10px; + border: 1px solid #CCC; + border-radius: 3px; + float: left; + + box-shadow: 0 0 3px 0 #BABABA; + transition: all 0.25s; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +@media (min-width: 880px) { + #controls .category { + width: 30%; + margin-left: 1.66%; + margin-right: 1.66%; + } +} + +@media (max-width: 879px) { + #controls .category { + width: 37%; + margin-left: 6.5%; + margin-right: 6.5%; + } +} + +#controls .category .title { + width: 100%; + height: 30px; + margin: 0 0 10px 0; + line-height: 25px; + + text-align: center; + color: #AAA; +} + +#controls .category:hover .title { + color: #777; +} + +#controls .category > .group { + border: 1px solid #CCC; + border-radius: 2px; +} + +/* property */ + +#controls .property { + width: 250px; + height: 20px; + margin: 5px auto; +} + +#controls .property .ui-input-slider { + margin: 0; + float: left; +} + +#controls .property .ui-input-slider-info { + width: 60px; +} + +#controls .property .ui-input-slider-left { + transition: opacity 0.15s; + opacity: 0; +} + +#controls .property .ui-input-slider-right { + transition: opacity 0.15s; + opacity: 0; +} + +#controls .property .name { + width: 60px; + height: 20px; + padding: 0px 10px 0px 0px; + text-align: right; + line-height: 100%; + float: left; +} + +#controls .property .config { + width: 20px; + height: 20px; + float: left; + background: url("config.png") center center no-repeat; + opacity: 0.5; +} + +#controls .property .config:hover { + cursor: pointer; + opacity: 1; +} + +#controls .ui-input-slider:hover .ui-input-slider-right { + opacity: 1; +} + +#controls .ui-input-slider:hover .ui-input-slider-left { + opacity: 1; +} + +#controls .property .ui-dropdown { + margin: 0 10px; + float: left; +} + +#controls .property .ui-checkbox { + margin: 0 0 0 16px; + float: left; +} + +#controls .property .ui-checkbox label { + height: 0.85em; + width: 10px; +} + +/* dropdowns */ +#controls .ui-dropdown { + width: 50px; + height: 1.7em; + border-radius: 2px; +} + +#controls .ui-dropdown-select { + line-height: 1.6em; +} + +#controls .ui-dropdown-list { + top: 20px; +} + +#controls .ui-dropdown-list { + border-width: 1px; + text-align: center; +} + +#controls .ui-dropdown-list:hover { + overflow: hidden; +} + +#controls .border-repeat { + margin: 0 0 0 16px !important; + width: 80px; +} + +#controls .border-repeat .ui-dropdown-list { + height: 6.2em; + border-width: 1px; + text-align: center; +} + +/* border-image-slice */ + +#border-slice-control .ui-dropdown-list { + height: 4.3em; +} + +/* border-image-width */ + +#border-width-control .ui-dropdown-list { + height: 6.2em; +} + +/* border-image-outset */ + +#border-outset-control .ui-dropdown-list { + height: 4.3em; +} + +#additional-properties .property { + width: 200px; +} + +#additional-properties .ui-input-slider > input { + width: 80px !important; +} + +/* unit settings panel */ + +#unit-settings { + padding: 10px; + position: absolute; + + background: #FFF; + + font-size: 12px; + border-radius: 3px; + border: 1px solid #CCC; + text-align: center; + color: #555; + + position: absolute; + z-index: 1000; + + box-shadow: 0 0 3px 0 #BABABA; + transition: all 0.25s; +} + +#unit-settings .title { + width: 100%; + margin: -5px auto 0; + + color: #666; + font-size: 14px; + font-weight: bold; + line-height: 25px; + border-bottom: 1px solid #E5E5E5; +} + +#unit-settings .ui-input-slider { + margin: 10px 0 0 0; +} + +#unit-settings .ui-input-slider-info { + width: 50px; + line-height: 1.5em; +} + +#unit-settings input { + font-size: 12px; + width: 40px !important; +} + +#unit-settings .close { + width: 16px; + height: 16px; + background: url('close.png') no-repeat center center; + background-size: 75%; + + position: absolute; + top: 4px; + right: 4px; + opacity: 0.5; +} + +#unit-settings .close:hover { + cursor: pointer; + opacity: 1; +} + +#unit-settings[data-active='true'] { + opacity: 1; +} + +#unit-settings[data-active='false'] { + opacity: 0; + top: -100px !important; +} + +/* + * CSS Output Code + */ + +#output { + padding: 10px; + border: 2px dashed #888 !important; + box-shadow: none !important; + border-radius: 3px; + overflow: hidden; + + -moz-user-select: text; + -webkit-user-select: text; + -ms-user-select: text; + user-select: text; +} + +@media (min-width: 880px) { + #output { + width: 63.33% !important; + } +} + +@media (max-width: 879px) { + #output { + width: 87% !important; + } +} + +#output .title { + width: 100%; + height: 30px; + margin: 0 0 10px 0; + line-height: 25px; + + text-align: center; + color: #AAA; +} + +#output .css-property { + width: 100%; + margin: 0; + color: #555; + font-size: 14px; + line-height: 18px; + float: left; +} + +#output .css-property .name { + width: 30%; + font-weight: bold; + text-align: right; + float: left; +} + +#output .css-property .value { + width: 65%; + padding: 0 2.5%; + word-break: break-all; + float: left; +} From 382a70d2477e4d123260523a953cf53ae6bb9f61 Mon Sep 17 00:00:00 2001 From: Will Bamberg Date: Wed, 11 Aug 2021 11:16:26 -0700 Subject: [PATCH 2/2] Add the other CSS tools --- README.md | 2 + tools/border-image-generator/index.html | 2 +- tools/border-radius-generator/arrows.png | Bin 0 -> 372 bytes tools/border-radius-generator/checked.png | Bin 0 -> 275 bytes tools/border-radius-generator/disabled.png | Bin 0 -> 344 bytes tools/border-radius-generator/dropdown.png | Bin 0 -> 330 bytes tools/border-radius-generator/index.html | 103 + .../border-radius-generator/resize-handle.png | Bin 0 -> 239 bytes tools/border-radius-generator/script.js | 769 ++++++ tools/border-radius-generator/styles.css | 701 ++++++ tools/box-shadow-generator/add-black.png | Bin 0 -> 140 bytes tools/box-shadow-generator/add-white.png | Bin 0 -> 150 bytes tools/box-shadow-generator/alpha.png | Bin 0 -> 105 bytes tools/box-shadow-generator/alpha_mask.png | Bin 0 -> 1186 bytes tools/box-shadow-generator/checked.png | Bin 0 -> 275 bytes tools/box-shadow-generator/delete-white.png | Bin 0 -> 182 bytes tools/box-shadow-generator/delete-yellow.png | Bin 0 -> 182 bytes tools/box-shadow-generator/disabled.png | Bin 0 -> 344 bytes tools/box-shadow-generator/down-black.png | Bin 0 -> 158 bytes tools/box-shadow-generator/down-white.png | Bin 0 -> 172 bytes tools/box-shadow-generator/hue.png | Bin 0 -> 610 bytes tools/box-shadow-generator/index.html | 214 ++ .../box-shadow-generator/picker_mask_200.png | Bin 0 -> 12816 bytes tools/box-shadow-generator/script.js | 1692 +++++++++++++ tools/box-shadow-generator/styles.css | 938 +++++++ tools/box-shadow-generator/up-black.png | Bin 0 -> 158 bytes tools/box-shadow-generator/up-white.png | Bin 0 -> 175 bytes tools/color-picker/alpha.png | Bin 0 -> 105 bytes tools/color-picker/alpha_mask.png | Bin 0 -> 1152 bytes tools/color-picker/arrow.png | Bin 0 -> 226 bytes tools/color-picker/arrows.png | Bin 0 -> 372 bytes tools/color-picker/canvas-controls.png | Bin 0 -> 384 bytes tools/color-picker/close.png | Bin 0 -> 372 bytes tools/color-picker/color-wheel.png | Bin 0 -> 1985 bytes tools/color-picker/copy.png | Bin 0 -> 2215 bytes tools/color-picker/drop.png | Bin 0 -> 226 bytes tools/color-picker/grain.png | Bin 0 -> 4716 bytes tools/color-picker/hue.png | Bin 0 -> 610 bytes tools/color-picker/index.html | 40 + tools/color-picker/lock.png | Bin 0 -> 1979 bytes tools/color-picker/pick.png | Bin 0 -> 288 bytes tools/color-picker/picker.png | Bin 0 -> 1659 bytes tools/color-picker/picker_mask_200.png | Bin 0 -> 12816 bytes tools/color-picker/resize.png | Bin 0 -> 158 bytes tools/color-picker/script.js | 2157 +++++++++++++++++ tools/color-picker/styles.css | 996 ++++++++ tools/color-picker/trash-can.png | Bin 0 -> 443 bytes tools/color-picker/void.png | Bin 0 -> 1707 bytes 48 files changed, 7613 insertions(+), 1 deletion(-) create mode 100644 tools/border-radius-generator/arrows.png create mode 100644 tools/border-radius-generator/checked.png create mode 100644 tools/border-radius-generator/disabled.png create mode 100644 tools/border-radius-generator/dropdown.png create mode 100644 tools/border-radius-generator/index.html create mode 100644 tools/border-radius-generator/resize-handle.png create mode 100644 tools/border-radius-generator/script.js create mode 100644 tools/border-radius-generator/styles.css create mode 100644 tools/box-shadow-generator/add-black.png create mode 100644 tools/box-shadow-generator/add-white.png create mode 100644 tools/box-shadow-generator/alpha.png create mode 100644 tools/box-shadow-generator/alpha_mask.png create mode 100644 tools/box-shadow-generator/checked.png create mode 100644 tools/box-shadow-generator/delete-white.png create mode 100644 tools/box-shadow-generator/delete-yellow.png create mode 100644 tools/box-shadow-generator/disabled.png create mode 100644 tools/box-shadow-generator/down-black.png create mode 100644 tools/box-shadow-generator/down-white.png create mode 100644 tools/box-shadow-generator/hue.png create mode 100644 tools/box-shadow-generator/index.html create mode 100644 tools/box-shadow-generator/picker_mask_200.png create mode 100644 tools/box-shadow-generator/script.js create mode 100644 tools/box-shadow-generator/styles.css create mode 100644 tools/box-shadow-generator/up-black.png create mode 100644 tools/box-shadow-generator/up-white.png create mode 100644 tools/color-picker/alpha.png create mode 100644 tools/color-picker/alpha_mask.png create mode 100644 tools/color-picker/arrow.png create mode 100644 tools/color-picker/arrows.png create mode 100644 tools/color-picker/canvas-controls.png create mode 100644 tools/color-picker/close.png create mode 100644 tools/color-picker/color-wheel.png create mode 100644 tools/color-picker/copy.png create mode 100644 tools/color-picker/drop.png create mode 100644 tools/color-picker/grain.png create mode 100644 tools/color-picker/hue.png create mode 100644 tools/color-picker/index.html create mode 100644 tools/color-picker/lock.png create mode 100644 tools/color-picker/pick.png create mode 100644 tools/color-picker/picker.png create mode 100644 tools/color-picker/picker_mask_200.png create mode 100644 tools/color-picker/resize.png create mode 100644 tools/color-picker/script.js create mode 100644 tools/color-picker/styles.css create mode 100644 tools/color-picker/trash-can.png create mode 100644 tools/color-picker/void.png diff --git a/README.md b/README.md index a691ed70..6c994e91 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,5 @@ The "object-fit-basics" directory contains a simple page demonstrating typical u The "object-fit-gallery" directory contains a fun image gallery that uses object-fit to display the images more nicely, both in thumbnail and full size view. [Run the example live](http://mdn.github.io/css-examples/object-fit-gallery/). The "overscroll-behavior" directory contains a simple page demonstrating typical usage of different overscroll-behavior values. [Run example live](http://mdn.github.io/css-examples/overscroll-behavior/). + +The "tools" directory contains various tools for working with CSS, including a [color picker](http://mdn.github.io/css-examples/tools/color-picker/) and a [box shadow generator](http://mdn.github.io/css-examples/tools/box-shadow-generator/). diff --git a/tools/border-image-generator/index.html b/tools/border-image-generator/index.html index 65d3451e..5d7d2847 100644 --- a/tools/border-image-generator/index.html +++ b/tools/border-image-generator/index.html @@ -3,7 +3,7 @@ - Border image generator + Border-image generator diff --git a/tools/border-radius-generator/arrows.png b/tools/border-radius-generator/arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..30d630fdaf96be7baa2d7da9de6cda337a5ab769 GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^3P3Et!3-oF?)7E^DVB6cUq=Rpjs4tz5?O(K#^NA% zCx&(BWL^R}2?0JKuI>ds_4V~NH8qbOJ*udvxOM9mko*7t|MvEFhhKoOt9UUD&Ms00v8)Hrk&@Q=>AirRS zE!#K+*|}KG9yrLmP57Xs2$RsoJ;%72xespTIeO{Vt&kF+$_`H##}JM4y%XKV4k&Q2 zn(h_9EPdzyG*2;>+e+*9ojcLoF0kMKPT{+x>GF@S1;5+=aYN;%$5Sthp7|JyUG&S<>H zX285rQkCrt`y+b?8K*wR;(y8q{1y0)q%j!tot^wYxvBI8+Y087ye0Nbh5BM=Z#T~1 zy~!Y|P{%a&55tjT0UyhBX7Mu^s#i(KI0SzYJA2-sKqAt36JwFXpAYtR1w0*g03~Ot$DHFw2y=Y!%A_>zh7n2 RWq@vF@O1TaS?83{1ON%TT}uD} literal 0 HcmV?d00001 diff --git a/tools/border-radius-generator/disabled.png b/tools/border-radius-generator/disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..1dd2c4c20a188993d385c72d92c3520685039a03 GIT binary patch literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstUx|vage(c z!@6@aFM*t>0G|+7_X3~)v;pxKV@?5Wku3@G3uX}I6T6icbmcf3`)6sn{PP!1f62Y^ zGd+WcSK!C>fVc0S0~Ho~x;TbNT<$&ZDb%3A!*ZabK|$-???3-%M=4jCZGRb})p=t5 zr(>-Tdg_bU9_$Kzb-yy~RMr;N#2vF;)i(7@aPWCMZY*fw)LOpAB2M5`*95mU0nbd5 z3f_qv5I7~a`0h5=3+JO&J}REEZvW-k>)!7^_P_cIll(&VU&sFcPykxb;OXk;vd$@? F2>=;FyV(E$ literal 0 HcmV?d00001 diff --git a/tools/border-radius-generator/dropdown.png b/tools/border-radius-generator/dropdown.png new file mode 100644 index 0000000000000000000000000000000000000000..eb1fb00dd695651cb5627b7baac8256e26aed140 GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k&H|6fVg?31We{epSZZGe6qGD+ zjVKAuPb(=;EJ|f?Ovz75Rq)JBOiv9;O-!jQJeg_(RCL|b#WAGfR_{fBt|kW&wt{pq zLC1EF4bm)eE9{>MM!j&eaTeIILV8Ewo!x~mz1(BBNo6R%SZBAEbK@B?`-(l^ZQEu} z^tn8R<*-52qIc(9-Y>ow|7WX%n~iwR?RhSNOTt38w#J6XUgzcg$~IGUlkv&IIhxO7 z&VQbBaO-M~F0oeB?`L1<+-I=A=rp z^BVtpd+EyeTG2-CDeFIQ?mhZobJR3f+w;+Co<$9|S(3I!I}}<67f8;A7FHv_%M;OXk;vd$@?2>^A%f=d7Z literal 0 HcmV?d00001 diff --git a/tools/border-radius-generator/index.html b/tools/border-radius-generator/index.html new file mode 100644 index 00000000..90d87879 --- /dev/null +++ b/tools/border-radius-generator/index.html @@ -0,0 +1,103 @@ + + + + + + Border-radius generator + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
rounded corner
+
+
+
+
+
+ +
+
select border units
+
+
+
+
+ + + + + + diff --git a/tools/border-radius-generator/resize-handle.png b/tools/border-radius-generator/resize-handle.png new file mode 100644 index 0000000000000000000000000000000000000000..5d276da2390fad6cb6fc068bee946313393c7f5a GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^av;pa3?$v++zf#fOS+@4BLl<6e(pbstUx|vage(c z!@6@aFM%AM0G|-or%#`%s;X*eXt)>n-0|Kc1JYCyWt||9U+C%L7$R|b z>4c5E2NVRD_p*C0@jcEmQza~o--chUb3nC^6ff{=QsKfKeo{~ zI@U17C^GwC?c|)_Y|a@I4BI49eB{y$oNxBbTvqMV!gJ!Zh|bf`*Iz795?LjswQQBv gdP}JlC+`c#P1}DYQ{9T=5zul5Pgg&ebxsLQ0K2MCx&QzG literal 0 HcmV?d00001 diff --git a/tools/border-radius-generator/script.js b/tools/border-radius-generator/script.js new file mode 100644 index 00000000..a8d73b0f --- /dev/null +++ b/tools/border-radius-generator/script.js @@ -0,0 +1,769 @@ +'use strict'; + +/** + * UI-InputSliderManager + */ + +var InputSliderManager = (function InputSliderManager() { + + var subscribers = {}; + var sliders = []; + + var InputComponent = function InputComponent(obj) { + var input = document.createElement('input'); + input.setAttribute('type', 'text'); + + input.addEventListener('click', function(e) { + this.select(); + }); + + input.addEventListener('change', function(e) { + var value = parseInt(e.target.value); + + if (isNaN(value) === true) + setValue(obj.topic, obj.value); + else + setValue(obj.topic, value); + }); + + subscribe(obj.topic, function(value) { + input.value = value + obj.unit; + }); + + return input; + } + + var SliderComponent = function SliderComponent(obj, sign) { + var slider = document.createElement('div'); + var startX = null; + var start_value = 0; + + slider.addEventListener("click", function(e) { + setValue(obj.topic, obj.value + obj.step * sign); + }); + + slider.addEventListener("mousedown", function(e) { + startX = e.clientX; + start_value = obj.value; + document.body.style.cursor = "e-resize"; + document.addEventListener("mousemove", sliderMotion); + }); + + document.addEventListener("mouseup", function(e) { + document.removeEventListener("mousemove", sliderMotion); + document.body.style.cursor = "auto"; + slider.style.cursor = "pointer"; + }); + + var sliderMotion = function sliderMotion(e) { + slider.style.cursor = "e-resize"; + var delta = (e.clientX - startX) / obj.sensitivity | 0; + var value = delta * obj.step + start_value; + setValue(obj.topic, value); + } + + return slider; + } + + var InputSlider = function(node) { + var min = node.getAttribute('data-min') | 0; + var max = node.getAttribute('data-max') | 0; + var step = node.getAttribute('data-step') | 0; + var value = node.getAttribute('data-value') | 0; + var topic = node.getAttribute('data-topic'); + var unit = node.getAttribute('data-unit'); + var name = node.getAttribute('data-info'); + var sensitivity = node.getAttribute('data-sensitivity') | 0; + + this.min = min; + this.max = max > 0 ? max : 100; + this.step = step === 0 ? 1 : step; + this.topic = topic; + this.node = node; + this.unit = unit; + this.sensitivity = sensitivity > 0 ? sensitivity : 5; + + var input = new InputComponent(this); + var slider_left = new SliderComponent(this, -1); + var slider_right = new SliderComponent(this, 1); + + slider_left.className = 'ui-input-slider-left'; + slider_right.className = 'ui-input-slider-right'; + + if (name) { + var info = document.createElement('span'); + info.className = 'ui-input-slider-info'; + info.textContent = name; + node.appendChild(info); + } + + node.appendChild(slider_left); + node.appendChild(input); + node.appendChild(slider_right); + node.className = 'ui-input-slider ui-input-slider-container'; + + this.input = input; + sliders[topic] = this; + setValue(topic, value); + } + + var setValue = function setValue(topic, value, send_notify) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + if (value > slider.max) value = slider.max; + if (value < slider.min) value = slider.min; + + slider.value = value; + slider.node.setAttribute('data-value', value); + + if (send_notify !== undefined && send_notify === false) { + slider.input.value = value + slider.unit; + return; + } + + notify.call(slider); + } + + var setMax = function setMax(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.max = value; + setValue(topic, slider.value); + } + + var setMin = function setMin(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.min = value; + setValue(topic, slider.value); + } + + var setUnit = function setUnit(topic, unit) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.unit = unit; + setValue(topic, slider.value); + } + + var getNode = function getNode(topic) { + return sliders[topic].node; + } + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + subscribers[topic].push(callback); + } + + var unsubscribe = function unsubscribe(topic, callback) { + subscribers[topic].indexOf(callback); + subscribers[topic].splice(index, 1); + } + + var notify = function notify() { + for (var i in subscribers[this.topic]) { + subscribers[this.topic][i](this.value); + } + } + + var init = function init() { + var elem = document.querySelectorAll('.ui-input-slider'); + var size = elem.length; + for (var i = 0; i < size; i++) + new InputSlider(elem[i]); + } + + return { + init : init, + setMax : setMax, + setMin : setMin, + setUnit : setUnit, + getNode : getNode, + setValue : setValue, + subscribe : subscribe, + unsubscribe : unsubscribe + } + +})(); + +/** + * UI-ButtonManager + */ + +var ButtonManager = (function CheckBoxManager() { + + var subscribers = []; + var buttons = []; + + var CheckBox = function CheckBox(node) { + var topic = node.getAttribute('data-topic'); + var state = node.getAttribute('data-state'); + var name = node.getAttribute('data-label'); + var align = node.getAttribute('data-text-on'); + + state = (state === "true"); + + var checkbox = document.createElement("input"); + var label = document.createElement("label"); + + var id = 'checkbox-' + topic; + checkbox.id = id; + checkbox.setAttribute('type', 'checkbox'); + checkbox.checked = state; + + label.setAttribute('for', id); + if (name) { + label.className = 'text'; + if (align) + label.className += ' ' + align; + label.textContent = name; + } + + node.appendChild(checkbox); + node.appendChild(label); + + this.node = node; + this.topic = topic; + this.checkbox = checkbox; + + checkbox.addEventListener('change', function(e) { + notify.call(this); + }.bind(this)); + + buttons[topic] = this; + } + + var getNode = function getNode(topic) { + return buttons[topic].node; + } + + var setValue = function setValue(topic, value) { + try { + buttons[topic].checkbox.checked = value; + } + catch(error) { + console.log(error); + } + } + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + + subscribers[topic].push(callback); + } + + var unsubscribe = function unsubscribe(topic, callback) { + subscribers[topic].indexOf(callback); + subscribers[topic].splice(index, 1); + } + + var notify = function notify() { + for (var i = 0; i < subscribers[this.topic].length; i++) + subscribers[this.topic][i](this.checkbox.checked); + } + + var init = function init() { + var elem = document.querySelectorAll('.ui-checkbox'); + var size = elem.length; + for (var i = 0; i < size; i++) + new CheckBox(elem[i]); + } + + return { + init : init, + setValue : setValue, + subscribe : subscribe, + unsubscribe : unsubscribe + } + +})(); + +window.addEventListener("load", function() { + BorderRadius.init(); +}); + +var BorderRadius = (function BorderRadius() { + + function getElemById(id) { + return document.getElementById(id); + } + + /** + * Shadow dragging + */ + var PreviewMouseTracking = (function Drag() { + var active = false; + var lastX = 0; + var lastY = 0; + var subscribers = []; + + var init = function init(id) { + var elem = getElemById(id); + elem.addEventListener('mousedown', dragStart, false); + document.addEventListener('mouseup', dragEnd, false); + } + + var dragStart = function dragStart(e) { + if (e.button !== 0) + return; + + active = true; + lastX = e.clientX; + lastY = e.clientY; + document.addEventListener('mousemove', mouseDrag, false); + } + + var dragEnd = function dragEnd(e) { + if (e.button !== 0) + return; + + if (active === true) { + active = false; + document.removeEventListener('mousemove', mouseDrag, false); + } + } + + var mouseDrag = function mouseDrag(e) { + notify(e.clientX - lastX, e.clientY - lastY); + lastX = e.clientX; + lastY = e.clientY; + } + + var subscribe = function subscribe(callback) { + subscribers.push(callback); + } + + var unsubscribe = function unsubscribe(callback) { + var index = subscribers.indexOf(callback); + subscribers.splice(index, 1); + } + + var notify = function notify(deltaX, deltaY) { + for (var i in subscribers) + subscribers[i](deltaX, deltaY); + } + + return { + init : init, + subscribe : subscribe, + unsubscribe : unsubscribe + } + + })(); + + var subject; + var units = ['px', '%']; + var output = null; + + var UnitSelector = function UnitSelector(topic) { + + this.container = document.createElement("div"); + this.select = document.createElement("select"); + for (var i in units) { + var option = document.createElement("option"); + option.value = i; + option.textContent = units[i]; + this.select.appendChild(option); + } + + this.container.className = 'dropdown ' + 'unit-' + topic; + this.container.appendChild(this.select); + } + + UnitSelector.prototype.setValue = function setValue(value) { + this.select.value = value; + } + + var RadiusContainer = function RadiusContainer(node) { + var radius = document.createElement('div'); + var handle = document.createElement('div'); + var x = node.getAttribute('data-x'); + var y = node.getAttribute('data-y'); + var active = false; + + this.id = node.id; + this.node = node; + this.radius = radius; + this.handle = handle; + this.width = 100; + this.height = 50; + this.size = 0; + this.rounded = false; + + this.unitX = 0; + this.unitY = 0; + this.unitR = 0; + + this.maxW = 100; + this.maxH = 100; + this.maxR = 100; + + this.topic = y + '-' + x; + + var sliderW = InputSliderManager.getNode(this.topic + '-w'); + var sliderH = InputSliderManager.getNode(this.topic + '-h'); + var sliderR = InputSliderManager.getNode(this.topic); + + this.setUnitX(this.unitX); + this.setUnitY(this.unitY); + this.setUnitR(this.unitR); + + this.updateWidth(); + this.updateHeight(); + this.updateRadius(); + + if (x === 'left') this.resizeX = 1; + if (x === 'right') this.resizeX = -1; + if (y === 'top') this.resizeY = 1; + if (y === 'bottom') this.resizeY = -1; + + radius.className = 'radius'; + + var unit_selector = document.getElementById("unit-selection"); + var unitW = new UnitSelector(this.topic + '-w'); + var unitH = new UnitSelector(this.topic + '-h'); + var unitR = new UnitSelector(this.topic); + + unit_selector.appendChild(unitW.container); + unit_selector.appendChild(unitH.container); + unit_selector.appendChild(unitR.container); + node.appendChild(radius); + subject.appendChild(handle); + + unitW.select.addEventListener('change', function(e) { + this.setUnitX(e.target.value | 0); + }.bind(this)); + + unitH.select.addEventListener('change', function(e) { + this.setUnitY(e.target.value | 0); + }.bind(this)); + + unitR.select.addEventListener('change', function(e) { + this.setUnitR(e.target.value | 0); + }.bind(this)); + + if (x === 'left' && y == 'top') handle.className = 'handle handle-top-left' + if (x === 'right' && y == 'top') handle.className = 'handle handle-top-right'; + if (x === 'right' && y == 'bottom') handle.className = 'handle handle-bottom-right'; + if (x === 'left' && y == 'bottom') handle.className = 'handle handle-bottom-left'; + + handle.addEventListener("mousedown", function(e) { + active = true; + this.radius.style.display = 'block'; + PreviewMouseTracking.subscribe(this.updateContainer.bind(this)); + }.bind(this)); + + document.addEventListener("mouseup", function(e) { + this.radius.style.display = 'none'; + if (active === true) + PreviewMouseTracking.unsubscribe(this.updateContainer.bind(this)); + }.bind(this)); + + InputSliderManager.subscribe(this.topic + '-w', this.setWidth.bind(this)); + InputSliderManager.subscribe(this.topic + '-h', this.setHeight.bind(this)); + InputSliderManager.subscribe(this.topic, this.setRadius.bind(this)); + + ButtonManager.subscribe(this.topic, function(value) { + this.rounded = value; + if (value === true) { + unitW.container.style.display = 'none'; + unitH.container.style.display = 'none'; + unitR.container.style.display = 'block'; + sliderW.style.display = 'none'; + sliderH.style.display = 'none'; + sliderR.style.display = 'block'; + this.setUnitR(this.unitR); + this.updateRadius(); + } + + if (value === false) { + unitW.container.style.display = 'block'; + unitH.container.style.display = 'block'; + unitR.container.style.display = 'none'; + sliderW.style.display = 'block'; + sliderH.style.display = 'block'; + sliderR.style.display = 'none'; + this.setUnitX(this.unitX); + this.setUnitY(this.unitY); + this.updateWidth(); + this.updateHeight(); + } + + this.updateBorderRadius(); + + }.bind(this)); + + this.updateBorderRadius(); + } + + RadiusContainer.prototype.updateWidth = function updateWidth() { + this.node.style.width = this.width + units[this.unitX]; + var value = Math.round(this.width / 2); + InputSliderManager.setValue(this.topic + '-w', value, false); + } + + RadiusContainer.prototype.updateHeight = function updateHeight() { + this.node.style.height = this.height + units[this.unitY]; + var value = Math.round(this.height / 2); + InputSliderManager.setValue(this.topic + '-h', value, false); + } + + RadiusContainer.prototype.updateRadius = function updateRadius() { + var value = Math.round(this.size / 2); + this.node.style.width = this.size + units[this.unitR]; + this.node.style.height = this.size + units[this.unitR]; + InputSliderManager.setValue(this.topic, value, false); + } + + RadiusContainer.prototype.setWidth = function setWidth(value) { + this.radius.style.display = 'block'; + this.width = 2 * value; + this.node.style.width = this.width + units[this.unitX]; + this.updateBorderRadius(); + } + + RadiusContainer.prototype.setHeight = function setHeight(value) { + this.radius.style.display = 'block'; + this.height = 2 * value; + this.node.style.height = this.height + units[this.unitY]; + this.updateBorderRadius(); + } + + RadiusContainer.prototype.setRadius = function setRadius(value) { + this.radius.style.display = 'block'; + this.size = 2 * value; + this.node.style.width = this.size + units[this.unitR]; + this.node.style.height = this.size + units[this.unitR]; + this.updateBorderRadius(); + } + + RadiusContainer.prototype.setUnitX = function setUnitX(value) { + this.unitX = value; + if (this.unitX === 0) this.maxW = 2 * subject.clientWidth; + if (this.unitX === 1) this.maxW = 200; + InputSliderManager.setUnit(this.topic + '-w', units[this.unitX]); + InputSliderManager.setMax(this.topic + '-w', this.maxW / 2); + } + + RadiusContainer.prototype.setUnitY = function setUnitY(value) { + this.unitY = value; + if (this.unitY === 0) this.maxH = 2 * subject.clientHeight; + if (this.unitY === 1) this.maxH = 200; + InputSliderManager.setUnit(this.topic + '-h', units[this.unitY]); + InputSliderManager.setMax(this.topic + '-h', this.maxH / 2); + } + + RadiusContainer.prototype.setUnitR = function setUnitR(value) { + this.unitR = value; + + if (this.unitR === 0) + this.maxR = 2 * Math.min(subject.clientHeight , subject.clientWidth); + + if (this.unitR === 1) + this.maxR = 200; + + InputSliderManager.setUnit(this.topic, units[this.unitR]); + InputSliderManager.setMax(this.topic, this.maxR / 2); + } + + RadiusContainer.prototype.updateUnits = function updateUnits(unit) { + if (this.rounded) { + this.setUnitR(this.unitR); + return; + } + + if (unit === 0) + this.setUnitX(this.unitX); + + if (unit === 1) + this.setUnitY(this.unitY); + } + + RadiusContainer.prototype.composeBorderRadius = function composeBorderRadius () { + + if (this.rounded === true) { + var unit = units[this.unitR]; + var value = Math.round(this.size / 2); + return value + unit; + } + + var unitX = units[this.unitX]; + var unitY = units[this.unitY]; + var valueX = Math.round(this.width / 2); + var valueY = Math.round(this.height / 2); + + if (valueX === valueY && this.unitX === this.unitY) + return valueX + unitX; + + return valueX + unitX + ' ' + valueY + unitY; + } + + RadiusContainer.prototype.updateBorderRadius = function updateBorderRadius () { + var radius = this.composeBorderRadius(); + var corner = 0; + + if (this.topic === 'top-left') { + subject.style.borderTopLeftRadius = radius; + corner = 0; + } + + if (this.topic === 'top-right') { + subject.style.borderTopRightRadius = radius; + corner = 1; + } + + if (this.topic === 'bottom-right') { + subject.style.borderBottomRightRadius = radius; + corner = 2; + } + + if (this.topic === 'bottom-left') { + subject.style.borderBottomLeftRadius = radius; + corner = 3; + } + + Tool.updateOutput(corner, radius); + } + + RadiusContainer.prototype.updateContainer = function updateContainer(deltaX, deltaY) { + + if (this.rounded === true) { + this.size += this.resizeX * deltaX + this.resizeY * deltaY; + if (this.size < 0) this.size = 0; + if (this.size > this.maxR) this.size = this.maxR; + this.updateRadius(); + this.updateBorderRadius(); + return; + } + + if (deltaX) { + this.width += this.resizeX * deltaX; + if (this.width < 0) this.width = 0; + if (this.width > this.maxW) this.width = this.maxW; + this.updateWidth(); + } + + if (deltaY) { + this.height += this.resizeY * deltaY; + if (this.height < 0) this.height = 0; + if (this.height > this.maxH) this.height = this.maxH; + this.updateHeight(); + } + + if (deltaX || deltaY) + this.updateBorderRadius(); + } + + /** + * Tool Manager + */ + var Tool = (function Tool() { + var preview; + var preview_ui; + var radius_containers = []; + var border_width = 3; + var borders1 = [null, null, null, null]; + var borders2 = [0, 0, 0, 0]; + + var updateUIWidth = function updateUIWidth(value) { + var pwidth = subject.parentElement.clientWidth; + var left = (pwidth - value) / 2; + subject.style.width = value + "px"; + + for (var i = 0; i < 4; i++) + radius_containers[i].updateUnits(0); + } + + var updateUIHeight = function updateUIHeight(value) { + var pheight = subject.parentElement.clientHeight; + var top = (pheight - value) / 2; + subject.style.height = value + "px"; + subject.style.top = top - border_width + "px"; + + for (var i = 0; i < 4; i++) + radius_containers[i].updateUnits(1); + } + + var updatePreviewUIWidth = function updatePreviewUIWidth() { + var p = subject.parentElement.clientWidth; + var v = preview_ui.clientWidth; + console.log(p, v, (p - v ) / 2); + preview_ui.style.left = (p - v) / 2 + "px" ; + } + + var updatePreviewUIHeight = function updatePreviewUIHeight() { + var p = subject.parentElement.clientHeight; + var v = preview_ui.clientHeight; + console.log(p, v, (p - v ) / 2); + preview_ui.style.top = (p - v) / 2 + "px" ; + } + + var updateOutput = function updateOutput(corner, radius) { + var values = radius.split(" "); + + borders1[corner] = values[0]; + borders2[corner] = values[0]; + + if (values.length === 2) + borders2[corner] = values[1]; + + var border_1_value = borders1.join(" "); + var border_2_value = borders2.join(" "); + var border_radius = 'border-radius: ' + border_1_value; + + if (border_2_value !== border_1_value) + border_radius += ' / ' + border_2_value; + + border_radius += ';'; + output.textContent = border_radius; + } + + var init = function init() { + preview = getElemById("preview"); + subject = getElemById("subject"); + output = getElemById("output"); + preview_ui = getElemById("radius-ui-sliders"); + + var elem = document.querySelectorAll('.radius-container'); + var size = elem.length; + for (var i = 0; i < size; i++) + radius_containers[i] = new RadiusContainer(elem[i]); + + InputSliderManager.subscribe("width", updateUIWidth); + InputSliderManager.subscribe("height", updateUIHeight); + + InputSliderManager.setValue("width", subject.clientWidth); + InputSliderManager.setValue("height", subject.clientHeight); + } + + return { + init : init, + updateOutput : updateOutput + } + + })(); + + /** + * Init Tool + */ + var init = function init() { + ButtonManager.init(); + InputSliderManager.init(); + PreviewMouseTracking.init("preview"); + Tool.init(); + } + + return { + init : init + } + +})(); diff --git a/tools/border-radius-generator/styles.css b/tools/border-radius-generator/styles.css new file mode 100644 index 00000000..9bdb4228 --- /dev/null +++ b/tools/border-radius-generator/styles.css @@ -0,0 +1,701 @@ +/* GRID OF TEN + * ========================================================================== */ + +.span_12 { + width: 100%; +} + +.span_11 { + width: 91.46%; +} + +.span_10 { + width: 83%; +} + +.span_9 { + width: 74.54%; +} + +.span_8 { + width: 66.08%; +} + +.span_7 { + width: 57.62%; +} + +.span_6 { + width: 49.16%; +} + +.span_5 { + width: 40.7%; +} + +.span_4 { + width: 32.24%; +} + +.span_3 { + width: 23.78%; +} + +.span_2 { + width: 15.32%; +} + +.span_1 { + width: 6.86%; +} + +/* SECTIONS + * ========================================================================== */ + +.section { + clear: both; + padding: 0px; + margin: 0px; +} + +/* GROUPING + * ========================================================================== */ + +.group:before, .group:after { + content: ""; + display: table; +} + +.group:after { + clear:both; +} + +.group { + zoom: 1; /* For IE 6/7 (trigger hasLayout) */ +} + +/* GRID COLUMN SETUP + * ========================================================================== */ + +.col { + display: block; + float:left; + margin: 1% 0 1% 1.6%; +} + +.col:first-child { + margin-left: 0; +} /* all browsers except IE6 and lower */ + +/* + * UI Component + */ + +.ui-input-slider-container { + height: 20px; + margin: 10px 0; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + -moz-user-select: none; + user-select: none; +} + +.ui-input-slider-container * { + float: left; + height: 100%; + line-height: 100%; +} + +/* Input Slider */ + +.ui-input-slider > input { + margin: 0; + padding: 0; + width: 50px; + text-align: center; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.ui-input-slider-info { + width: 90px; + padding: 0px 10px 0px 0px; + text-align: right; + text-transform: lowercase; +} + +.ui-input-slider-left, .ui-input-slider-right { + width: 16px; + cursor: pointer; + background: url("arrows.png") center left no-repeat; +} + +.ui-input-slider-right { + background: url("arrows.png") center right no-repeat; +} + +.ui-input-slider-name { + width: 90px; + padding: 0 10px 0 0; + text-align: right; + text-transform: lowercase; +} + +.ui-input-slider-btn-set { + width: 25px; + background-color: #2C9FC9; + border-radius: 5px; + color: #FFF; + font-weight: bold; + line-height: 14px; + text-align: center; +} + +.ui-input-slider-btn-set:hover { + background-color: #379B4A; + cursor: pointer; +} + +/* + * UI Component + */ + +/* Checkbox */ + +.ui-checkbox { + text-align: center; + font-size: 16px; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + line-height: 1.5em; + color: #FFF; + + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.ui-checkbox > input { + display: none; +} + +.ui-checkbox > label { + font-size: 12px; + padding: 0.333em 1.666em 0.5em; + height: 1em; + line-height: 1em; + + background-color: #888; + background-image: url("disabled.png"); + background-position: center center; + background-repeat: no-repeat; + + color: #FFF; + border-radius: 3px; + font-weight: bold; + float: left; +} + +.ui-checkbox .text { + padding-left: 34px; + background-position: center left 10px; +} + +.ui-checkbox .left { + padding-right: 34px; + padding-left: 1.666em; + background-position: center right 10px; +} + +.ui-checkbox > label:hover { + cursor: pointer; +} + +.ui-checkbox > input:checked + label { + background-image: url("checked.png"); + background-color: #379B4A; +} + +body { + max-width: 1000px; + margin: 0 auto; + + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +#container { + width: 100%; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +/******************************************************************************/ +/******************************************************************************/ +/* + * Preview Area + */ + +#preview { + height: 500px; + border: 1px solid #CCC; + border-radius: 3px; + text-align: center; + overflow: hidden; + position: relative; +} + +#preview .content { + width: 100%; + height: 100%; + display: block; +} + +#preview input { + color: #333; + border: 1px solid #CCC; + border-radius: 3px; +} + +#subject { + width: 400px; + height: 150px; + margin: 0 auto; + border: 3px solid #C60; + background: #FFF; + position: relative; +} + +.radius { + width: 50%; + height: 50%; + border: 1px solid #CCC; + display: none; + position: absolute; + z-index: 1; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.handle { + width: 16px; + height: 16px; + position: absolute; + z-index: 2; +} + +.handle-top-left { + top: -12px; + left: -12px; + cursor: se-resize; + background: url("resize-handle.png") top left no-repeat; +} + +.handle-top-right { + top: -12px; + right: -12px; + cursor: sw-resize; + background: url("resize-handle.png") top right no-repeat; +} + +.handle-bottom-right { + bottom: -12px; + right: -12px; + cursor: nw-resize; + background: url("resize-handle.png") bottom right no-repeat; +} + +.handle-bottom-left { + bottom: -12px; + left: -12px; + cursor: ne-resize; + background: url("resize-handle.png") bottom left no-repeat; +} + +.radius-container { + position: absolute; + display : block; + z-index: 1; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +/* TOP LEFT */ +#top-left { + top: 0; + left: 0; +} + +#top-left .radius { + border-top-left-radius: 100%; + top: 0; + left: 0; +} + +/* TOP RIGHT */ +#top-right { + top: 0; + right: 0; +} + +#top-right .radius { + border-top-right-radius: 100%; + top: 0; + right: 0; +} + +/* BOTTOM RIGHT */ +#bottom-right { + bottom: 0; + right: 0; +} + +#bottom-right .radius { + border-bottom-right-radius: 100%; + bottom: 0; + right: 0; +} + +/* BOTTOM lEFT */ +#bottom-left { + bottom: 0; + left: 0; +} + +#bottom-left .radius { + border-bottom-left-radius: 100%; + bottom: 0; +} + +/* INPUT SLIDERS */ + +#preview .ui-input-slider { + margin: 10px; + position: absolute; + z-index: 10; +} + +#radius-ui-sliders { + width: 100%; + height: 100%; + min-height: 75px; + min-width: 150px; + padding: 20px 50px; + top: -20px; + left: -50px; + position: relative; +} + +#tlr { + top: -30px; + left: -50px; + display: none; +} + +#tlw { + top: -30px; + left: 30px; +} + +#tlh { + top: 20px; + left: -50px; +} + +#trr { + top: -30px; + right: -50px; + display: none; +} + +#trw { + top: -30px; + right: 30px; +} + +#trh { + top: 20px; + right: -50px; +} + +#brr { + bottom: -30px; + right: -50px; + display: none; +} + +#brw { + bottom: -30px; + right: 30px; +} + +#brh { + bottom: 20px; + right: -50px; +} + +#blr { + bottom: -30px; + left: -50px; + display: none; +} + +#blw { + bottom: -30px; + left: 30px; +} + +#blh { + bottom: 20px; + left: -50px; +} + +#preview .ui-input-slider-left, #preview .ui-input-slider-right { + visibility: hidden; +} + +#preview .ui-input-slider-container:hover .ui-input-slider-left { + visibility: visible; +} + +#preview .ui-input-slider-container:hover .ui-input-slider-right { + visibility: visible; +} + +/* + * + */ + +#unit-selection { + width: 200px; + height: 75px; + margin: 30px 30px 0 0; + padding: 30px; + border: 3px solid #555; + border-radius: 10px; + position: relative; + float: right; +} + +#unit-selection .info { + height: 20%; + width: 100%; + line-height: 20%; + font-size: 20px; + text-align: center; + position: relative; + top: 40%; +} + +#unit-selection .dropdown { + width: 50px; + height: 20px; + margin: 10px; + padding: 0; + border-radius: 3px; + position: absolute; + overflow: hidden; +} + +#unit-selection select { + width: 50px; + height: 20px; + margin: 0; + padding: 0 0 0 10px; + background: #555; + border: 1px solid #555; + border: none; + color: #FFF; + float: left; +} + +#unit-selection select option { + background: #FFF; + color: #333; +} + +#unit-selection select:hover { + cursor: pointer; +} + +#unit-selection .dropdown:before { + content: ""; + width: 18px; + height: 20px; + display: block; + background-color: #555; + background-image: url("dropdown.png"); + background-position: center center; + background-repeat: no-repeat; + top: 0px; + right: 0px; + position: absolute; + z-index: 1; + pointer-events: none; +} + +#unit-selection .unit-top-left { + top: 0; + left: 0; + display: none; +} + +#unit-selection .unit-top-left-w { + top: -22px; + left: 30px; +} + +#unit-selection .unit-top-left-h { + top: 20px; + left: -37px; +} + +#unit-selection .unit-top-right { + top: 0; + right: 0; + display: none; +} + +#unit-selection .unit-top-right-w { + top: -22px; + right: 30px; +} + +#unit-selection .unit-top-right-h { + top: 20px; + right: -37px; +} + +#unit-selection .unit-bottom-right { + bottom: 0; + right: 0; + display: none; +} + +#unit-selection .unit-bottom-right-w { + bottom: -22px; + right: 30px; +} + +#unit-selection .unit-bottom-right-h { + bottom: 20px; + right: -37px; +} + +#unit-selection .unit-bottom-left { + bottom: 0; + left: 0; + display: none; +} + +#unit-selection .unit-bottom-left-w { + bottom: -22px; + left: 30px; +} + +#unit-selection .unit-bottom-left-h { + bottom: 20px; + left: -37px; +} + +/******************************************************************************/ +/******************************************************************************/ + +#radius-lock { + width: 200px; + height: 75px; + margin: 30px 0 0 30px; + padding: 30px; + border: 3px solid #555; + border-radius: 10px; + position: relative; + float: left; +} + +#radius-lock .ui-checkbox { + color: #FFF; + position: absolute; +} + +#radius-lock .ui-checkbox > label { + height: 20px; + width: 34px; + padding: 0; +} + +#radius-lock .info { + height: 20%; + width: 100%; + line-height: 20%; + font-size: 20px; + text-align: center; + position: relative; + top: 40%; +} + +#radius-lock [data-topic="top-left"] { + top: 10px; + left: 10px; +} + +#radius-lock [data-topic="top-right"] { + top: 10px; + right: 10px; +} + +#radius-lock [data-topic="bottom-right"] { + bottom: 10px; + right: 10px; +} + +#radius-lock [data-topic="bottom-left"] { + bottom: 10px; + left: 10px; +} + +/** + * Controls + */ + +#dimensions { + width: 200px; + color: #444; + float:left; +} + +#dimensions input { + background: #555; + color: #FFF; + border: none; + border-radius: 3px; +} + +#output { + width: 500px; + padding: 10px 0; + margin: 10px 0; + color: #555; + text-align: center; + border: 1px dashed #999; + border-radius: 3px; + -moz-user-select: text; + -webkit-user-select: text; + -ms-user-select: text; + user-select: text; + + float: right; +} diff --git a/tools/box-shadow-generator/add-black.png b/tools/box-shadow-generator/add-black.png new file mode 100644 index 0000000000000000000000000000000000000000..ed80eefb88a13eeee83097df5561427d01316095 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;OS+@4BLl<6e(pbstUx|vage(c z!@6@aFM%Ak0G|+7_W~avbG}wfAV|6-$S;_|;n|HeAV=KO#W95AdU65~*fli0`mZQ3 cON5!3!O?+t^4BNvAbS}+UHx3vIVCg!0KXL>umAu6 literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/add-white.png b/tools/box-shadow-generator/add-white.png new file mode 100644 index 0000000000000000000000000000000000000000..639ff706516fd33023543d3132c4b9b6691fad9b GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@5Lt z8c`CQpH@<#WAGfR`QSk|LvJoCFZMG rNtiY?Fg|H|m~tS)YQaQCmqdoT*)iw7eg4D^RLgTe~DWM4f&IK&c literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/alpha.png b/tools/box-shadow-generator/alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..a28b929a4adde81339fca7295d680bfc3e6cd6ff GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F5M?jcysy3fAP*B>_ y#WAGfR< literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/alpha_mask.png b/tools/box-shadow-generator/alpha_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..d159327b56526d2c58548c4a1d3a0f3888659b8e GIT binary patch literal 1186 zcmeAS@N?(olHy`uVBq!ia0vp^$ADOdg9%7(jR|)KQk(@Ik;M!QddeWoSh3W;jDdkA z#M8wwq~g}w8{dsDSOZuajP?qLa>S`hG8ZML^n3$+f|5sZ#@F z&RIMzSk=wlZp?T5>%QuDcHjTL{muU6-_zpr&p%i8%g?*c|Ni;S&u?#UfA{X)x^?T$ zojZ5-?AhMl-mhQ3Zr!@|+qZAqwr#t1?b@_y(~cfJ+S=Os^XE_d`hO;-rlw|QW+ogozKJ$_%!&p$tnU;g;=^0K=ByeChdq@#=de1_N_* zb6`+ix^(Hng@Ewz@Zex$BO|N&e>N^oH-O=Aevakh6)RROSioR7Yt}3kx3I8pPfku& z_nTu;_s4?eKzwE8&&$jGy*)i;EsI=&fh0+0*sx*4 zgb5RN?AS45hD1%{^=5YdPai%M6c-m47JmHn>5z8hW}uHZZQ2BMjc+lR##V-m-nokO6!sdB9okgJYLOL+PZu9?#-Jw@7=q1>(;MdUtb3X z)TV>0SFhIA);@juw70i6FzL*zIlFU#NGyL$EN z-rC<~Sy@>{MMXgCYHH@>l$Dm2hK63faN)v(2M-P$aHy}ZkBpSu`qW{jMcXn~R#sqo zOL^>QkjcIm=v+Dbx<4;2E(RJN)O$dW!^6|l6BuD$UQK#aqM8(dNlil4>eV0deC zDNLQxIt!T4fT@GUB`ZtoN=sA17hp8y<>dj>xt^Y0K<}l>=jUXrtAF3#o`3u1%|N|{ z90v>k{wf7}N5J!v;`dKaPm2gn;_giN2u!=;dNB$C3f(~~mM>op^z!1xi`TC8{n?xl z8X77pDw>*_s;a6w!Tpdz+XBndS5xN9k?Cw?F!&yC^<);T3K0RSL#P4)l) literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/checked.png b/tools/box-shadow-generator/checked.png new file mode 100644 index 0000000000000000000000000000000000000000..cd8e86540f89489d36d6cc9a5ab9033999a3b11e GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@5Lt z8c`CQpH@hp7|JyUG&S<>H zX285rQkCrt`y+b?8K*wR;(y8q{1y0)q%j!tot^wYxvBI8+Y087ye0Nbh5BM=Z#T~1 zy~!Y|P{%a&55tjT0UyhBX7Mu^s#i(KI0SzYJA2-sKqAt36JwFXpAYtR1w0*g03~Ot$DHFw2y=Y!%A_>zh7n2 RWq@vF@O1TaS?83{1ON%TT}uD} literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/delete-white.png b/tools/box-shadow-generator/delete-white.png new file mode 100644 index 0000000000000000000000000000000000000000..cac25afae6f2f2ed4bedb8b36b21822a53a2d820 GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9Ea{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaMM1AIbU|NsB*Uf=^HT^4P+2oz*03GxfBXSipwf)U8G^>lFz;kcg6!OGM& z;X*)Qo5sZnOL^kfI&w=kiB)YiYFTqZD3#-Cl;A0WS6c<#8g?XbZV=j#w83lxqrzf_ Yg)-vy!5dA&fd(;ny85}Sb4q9e0O5u>S^xk5 literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/delete-yellow.png b/tools/box-shadow-generator/delete-yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..6e186b7c5ad0925c64119603c1613762ec664403 GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9Ea{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaMM1AIbU|371JFYx*QoI$E`sVPv9sU*lRxSrvj$qGgw&(_n$F@)oKG6ySD z+k^`Nfo&QWCoJWOTkFUz*(6rA)u?671))@qt5Jfd1YT_waBJ9+z_~$aL(&Gb4U7tl Z85YWj+Xrtn2?rX);OXk;vd$@?2>_H)H7@`F literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/disabled.png b/tools/box-shadow-generator/disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..1dd2c4c20a188993d385c72d92c3520685039a03 GIT binary patch literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstUx|vage(c z!@6@aFM*t>0G|+7_X3~)v;pxKV@?5Wku3@G3uX}I6T6icbmcf3`)6sn{PP!1f62Y^ zGd+WcSK!C>fVc0S0~Ho~x;TbNT<$&ZDb%3A!*ZabK|$-???3-%M=4jCZGRb})p=t5 zr(>-Tdg_bU9_$Kzb-yy~RMr;N#2vF;)i(7@aPWCMZY*fw)LOpAB2M5`*95mU0nbd5 z3f_qv5I7~a`0h5=3+JO&J}REEZvW-k>)!7^_P_cIll(&VU&sFcPykxb;OXk;vd$@? F2>=;FyV(E$ literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/down-black.png b/tools/box-shadow-generator/down-black.png new file mode 100644 index 0000000000000000000000000000000000000000..d3c28c8549d18e8ec4bd4af0060105e7c53319fc GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9Ea{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaMM1AIbU-3xqxOdt@;=9~bP0l+XkK2Zbe9 literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/down-white.png b/tools/box-shadow-generator/down-white.png new file mode 100644 index 0000000000000000000000000000000000000000..ab65bddbafc306170dee6cefbc142137a4b04f32 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@5Lt z8c`CQpH@HoE|uM8idO zq0Sx;6(HdPBwUhwRE*SwW*^bpbn~d%?g=>{F(tuHFyZ2+WGE!rdCu-_{GR9bb98!C zH|m5Pn-w81o$Q^{ANw)zO}GD}0GZD9kAGXpsXq#t)5~3Gx$bCuq4m3?hbx56KT6%x zx4lyT|0(TC#ro69l?vrgr`?&by2$g~Y000?b(7~mk^bpqH@UgU;oB*>o0_*%Hs?$z z-4qpef_+njn1|TOph&&dDQjyqW~Z!vGvV&1jc=y=KiwcRHTl!xKU(Tfx6GN`UF5p% zwC_&k?@uS%Onv^Tf6v77D);;s@>PERF9q)|w=S8y?y~4EkLNE;<}QhU!EWW|{?ee< z>-Wp#TfWvA+PRDPGj-Q4db(wb*hU4h&buo z{D`1dZo{$%T2YiCO8E^M8pAe_?VGlA2{QSAiF%)!8U d@?YUUqeNvw_<^(EBY + + + + + Box-shadow generator + + + + + +
+
+
+
+
+
+
+
+
+
+ +
+
+
element
+
+ :before + +
+
+ :after + +
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+
Shadow properties
+
+
+
inset
+
+
+
+
Position x
+
+
+
+
+
+
+
Position y
+
+
+
+
+
+
+
Blur
+
+
+
+
+
+
+
Spread
+
+
+
+
+
+
+
+
+ +
+
Class element properties
+
+
+
border
+
+
+
+
z-index
+
+
+
+
+
+
+
top
+
+
+
+
+
+
+
left
+
+
+
+
+
+
+
Rotate
+
+
+
+
+
+
+
+
Width
+
+
+
+
+
+
+
+
Height
+
+
+
+
+
+
+
+
+ +
+ +
CSS Code
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + diff --git a/tools/box-shadow-generator/picker_mask_200.png b/tools/box-shadow-generator/picker_mask_200.png new file mode 100644 index 0000000000000000000000000000000000000000..77f55010c7806fc5b7cf63a7da2dfcef60e43796 GIT binary patch literal 12816 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 literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/script.js b/tools/box-shadow-generator/script.js new file mode 100644 index 00000000..cc1727eb --- /dev/null +++ b/tools/box-shadow-generator/script.js @@ -0,0 +1,1692 @@ +'use strict'; + +/** + * UI-SlidersManager + */ + +var SliderManager = (function SliderManager() { + + var subscribers = {}; + var sliders = []; + + var Slider = function(node) { + var min = node.getAttribute('data-min') | 0; + var max = node.getAttribute('data-max') | 0; + var step = node.getAttribute('data-step') | 0; + var value = node.getAttribute('data-value') | 0; + var snap = node.getAttribute('data-snap'); + var topic = node.getAttribute('data-topic'); + + this.min = min; + this.max = max > 0 ? max : 100; + this.step = step === 0 ? 1 : step; + this.value = value <= max && value >= min ? value : (min + max) / 2 | 0; + this.snap = snap === "true" ? true : false; + this.topic = topic; + this.node = node; + + var pointer = document.createElement('div'); + pointer.className = 'ui-slider-pointer'; + node.appendChild(pointer); + this.pointer = pointer; + + setMouseTracking(node, updateSlider.bind(this)); + + sliders[topic] = this; + setValue(topic, this.value); + } + + var setButtonComponent = function setButtonComponent(node) { + var type = node.getAttribute('data-type'); + var topic = node.getAttribute('data-topic'); + if (type === "sub") { + node.textContent = '-'; + node.addEventListener("click", function() { + decrement(topic); + }); + } + if (type === "add") { + node.textContent = '+'; + node.addEventListener("click", function() { + increment(topic); + }); + } + } + + var setInputComponent = function setInputComponent(node) { + var topic = node.getAttribute('data-topic'); + var unit_type = node.getAttribute('data-unit'); + + var input = document.createElement('input'); + var unit = document.createElement('span'); + unit.textContent = unit_type; + + input.setAttribute('type', 'text'); + node.appendChild(input); + node.appendChild(unit); + + input.addEventListener('click', function(e) { + this.select(); + }); + + input.addEventListener('change', function(e) { + setValue(topic, e.target.value | 0); + }); + + subscribe(topic, function(value) { + node.children[0].value = value; + }); + } + + var increment = function increment(topic) { + var slider = sliders[topic]; + if (slider === null || slider === undefined) + return; + + if (slider.value + slider.step <= slider.max) { + slider.value += slider.step; + setValue(slider.topic, slider.value) + notify.call(slider); + } + }; + + var decrement = function decrement(topic) { + var slider = sliders[topic]; + if (slider === null || slider === undefined) + return; + + if (slider.value - slider.step >= slider.min) { + slider.value -= slider.step; + setValue(topic, slider.value) + notify.call(slider); + } + } + + // this = Slider object + var updateSlider = function updateSlider(e) { + var node = this.node; + var pos = e.pageX - node.offsetLeft; + var width = node.clientWidth; + var delta = this.max - this.min; + var offset = this.pointer.clientWidth + 4; // border width * 2 + + if (pos < 0) pos = 0; + if (pos > width) pos = width; + + var value = pos * delta / width | 0; + var precision = value % this.step; + value = value - precision + this.min; + if (precision > this.step / 2) + value = value + this.step; + + if (this.snap) + pos = (value - this.min) * width / delta; + + this.pointer.style.left = pos - offset/2 + "px"; + this.value = value; + node.setAttribute('data-value', value); + notify.call(this); + } + + var setValue = function setValue(topic, value) { + var slider = sliders[topic]; + + if (value > slider.max || value < slider.min) + return; + + var delta = slider.max - slider.min; + var width = slider.node.clientWidth; + var offset = slider.pointer.clientWidth; + var pos = (value - slider.min) * width / delta; + slider.value = value; + slider.pointer.style.left = pos - offset / 2 + "px"; + slider.node.setAttribute('data-value', value); + notify.call(slider); + } + + var setMouseTracking = function setMouseTracking(elem, callback) { + elem.addEventListener("mousedown", function(e) { + callback(e); + document.addEventListener("mousemove", callback); + }); + + document.addEventListener("mouseup", function(e) { + document.removeEventListener("mousemove", callback); + }); + } + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + subscribers[topic].push(callback); + } + + var unsubscribe = function unsubscribe(topic, callback) { + subscribers[topic].indexOf(callback); + subscribers[topic].splice(index, 1); + } + + var notify = function notify() { + if (subscribers[this.topic] === undefined) + return; + + for (var i in subscribers[this.topic]) { + subscribers[this.topic][i](this.value); + } + } + + var init = function init() { + var elem, size; + + elem = document.querySelectorAll('.ui-slider-btn-set'); + size = elem.length; + for (var i = 0; i < size; i++) + setButtonComponent(elem[i]); + + elem = document.querySelectorAll('.ui-slider-input'); + size = elem.length; + for (var i = 0; i < size; i++) + setInputComponent(elem[i]); + + elem = document.querySelectorAll('.ui-slider'); + size = elem.length; + for (var i = 0; i < size; i++) + new Slider(elem[i]); + } + + return { + init : init, + setValue : setValue, + subscribe : subscribe, + unsubscribe : unsubscribe + } + +})(); + +/** + * UI-ButtonManager + */ + +var ButtonManager = (function CheckBoxManager() { + + var subscribers = []; + var buttons = []; + + var CheckBox = function CheckBox(node) { + var topic = node.getAttribute('data-topic'); + var state = node.getAttribute('data-state'); + var name = node.getAttribute('data-label'); + var align = node.getAttribute('data-text-on'); + + state = (state === "true"); + + var checkbox = document.createElement("input"); + var label = document.createElement("label"); + + var id = 'checkbox-' + topic; + checkbox.id = id; + checkbox.setAttribute('type', 'checkbox'); + checkbox.checked = state; + + label.setAttribute('for', id); + if (name) { + label.className = 'text'; + if (align) + label.className += ' ' + align; + label.textContent = name; + } + + node.appendChild(checkbox); + node.appendChild(label); + + this.node = node; + this.topic = topic; + this.checkbox = checkbox; + + checkbox.addEventListener('change', function(e) { + notify.call(this); + }.bind(this)); + + buttons[topic] = this; + } + + var getNode = function getNode(topic) { + return buttons[topic].node; + } + + var setValue = function setValue(topic, value) { + try { + buttons[topic].checkbox.checked = value; + notify.call(buttons[topic]); + } + catch(error) { + console.log(error, topic, value); + } + } + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + + subscribers[topic].push(callback); + } + + var unsubscribe = function unsubscribe(topic, callback) { + subscribers[topic].indexOf(callback); + subscribers[topic].splice(index, 1); + } + + var notify = function notify() { + if (subscribers[this.topic] === undefined) + return; + for (var i = 0; i < subscribers[this.topic].length; i++) + subscribers[this.topic][i](this.checkbox.checked); + } + + var init = function init() { + var elem = document.querySelectorAll('.ui-checkbox'); + var size = elem.length; + for (var i = 0; i < size; i++) + new CheckBox(elem[i]); + } + + return { + init : init, + setValue : setValue, + subscribe : subscribe, + unsubscribe : unsubscribe + } + +})(); + +window.addEventListener("load", function(){ + BoxShadow.init(); +}); + +var BoxShadow = (function BoxShadow() { + + function getElemById(id) { + return document.getElementById(id); + } + + /** + * RGBA Color class + */ + + function Color() { + this.r = 0; + this.g = 0; + this.b = 0; + this.a = 1; + this.hue = 0; + this.saturation = 0; + this.value = 0; + } + + Color.prototype.copy = function copy(obj) { + if(obj instanceof Color !== true) { + console.log("Typeof instance not Color"); + return; + } + + this.r = obj.r; + this.g = obj.g; + this.b = obj.b; + this.a = obj.a; + this.hue = obj.hue; + this.saturation = obj.saturation; + this.value = obj.value; + } + + Color.prototype.setRGBA = function setRGBA(red, green, blue, alpha) { + if (red != undefined) + this.r = red | 0; + if (green != undefined) + this.g = green | 0; + if (blue != undefined) + this.b = blue | 0; + if (alpha != undefined) + this.a = alpha | 0; + } + + /** + * HSV/HSB (hue, saturation, value / brightness) + * @param hue 0-360 + * @param saturation 0-100 + * @param value 0-100 + */ + Color.prototype.setHSV = function setHSV(hue, saturation, value) { + this.hue = hue; + this.saturation = saturation; + this.value = value; + this.updateRGB(); + } + + Color.prototype.updateRGB = function updateRGB() { + var sat = this.saturation / 100; + var value = this.value / 100; + var C = sat * value; + var H = this.hue / 60; + var X = C * (1 - Math.abs(H % 2 - 1)); + var m = value - C; + var precision = 255; + + C = (C + m) * precision; + X = (X + m) * precision; + m = m * precision; + + if (H >= 0 && H < 1) { this.setRGBA(C, X, m); return; } + if (H >= 1 && H < 2) { this.setRGBA(X, C, m); return; } + if (H >= 2 && H < 3) { this.setRGBA(m, C, X); return; } + if (H >= 3 && H < 4) { this.setRGBA(m, X, C); return; } + if (H >= 4 && H < 5) { this.setRGBA(X, m, C); return; } + if (H >= 5 && H < 6) { this.setRGBA(C, m, X); return; } + } + + Color.prototype.updateHSV = function updateHSV() { + var red = this.r / 255; + var green = this.g / 255; + var blue = this.b / 255; + + var cmax = Math.max(red, green, blue); + var cmin = Math.min(red, green, blue); + var delta = cmax - cmin; + var hue = 0; + var saturation = 0; + + if (delta) { + if (cmax === red ) { hue = ((green - blue) / delta); } + if (cmax === green ) { hue = 2 + (blue - red) / delta; } + if (cmax === blue ) { hue = 4 + (red - green) / delta; } + if (cmax) saturation = delta / cmax; + } + + this.hue = 60 * hue | 0; + if (this.hue < 0) this.hue += 360; + this.saturation = (saturation * 100) | 0; + this.value = (cmax * 100) | 0; + } + + Color.prototype.setHexa = function setHexa(value) { + var valid = /(^#{0,1}[0-9A-F]{6}$)|(^#{0,1}[0-9A-F]{3}$)/i.test(value) + if (valid !== true) + return; + + if (value[0] === '#') + value = value.slice(1, value.length); + + if (value.length === 3) + value = value.replace(/([0-9A-F])([0-9A-F])([0-9A-F])/i,"$1$1$2$2$3$3"); + + this.r = parseInt(value.substr(0, 2), 16); + this.g = parseInt(value.substr(2, 2), 16); + this.b = parseInt(value.substr(4, 2), 16); + + this.alpha = 1; + } + + Color.prototype.getHexa = function getHexa() { + var r = this.r.toString(16); + var g = this.g.toString(16); + var b = this.b.toString(16); + if (this.r < 16) r = '0' + r; + if (this.g < 16) g = '0' + g; + if (this.b < 16) b = '0' + b; + var value = '#' + r + g + b; + return value.toUpperCase(); + } + + Color.prototype.getRGBA = function getRGBA() { + + var rgb = "(" + this.r + ", " + this.g + ", " + this.b; + var a = ''; + var v = ''; + if (this.a !== 1) { + a = 'a'; + v = ', ' + this.a; + } + + var value = "rgb" + a + rgb + v + ")"; + return value; + } + + Color.prototype.getColor = function getColor() { + if (this.a | 0 === 1) + return this.getHexa(); + return this.getRGBA(); + } + + /** + * Shadow Object + */ + function Shadow() { + this.inset = false; + this.posX = 5; + this.posY = -5; + this.blur = 5; + this.spread = 0; + this.color = new Color(); + + var hue = (Math.random() * 360) | 0; + var saturation = (Math.random() * 75) | 0; + var value = (Math.random() * 50 + 50) | 0; + this.color.setHSV(hue, saturation, value, 1); + } + + Shadow.prototype.computeCSS = function computeCSS() { + var value = ""; + if (this.inset === true) + value += "inset "; + value += this.posX + "px "; + value += this.posY + "px "; + value += this.blur + "px "; + value += this.spread + "px "; + value += this.color.getColor(); + + return value; + } + + Shadow.prototype.toggleInset = function toggleInset(value) { + if (value !== undefined || typeof value === "boolean") + this.inset = value; + else + this.inset = this.inset === true ? false : true; + } + + Shadow.prototype.copy = function copy(obj) { + if(obj instanceof Shadow !== true) { + console.log("Typeof instance not Shadow"); + return; + } + + this.inset = obj.inset; + this.posX = obj.posX; + this.posY = obj.posY; + this.blur = obj.blur; + this.spread = obj.spread; + this.color.copy(obj.color); + } + + /** + * Color Picker + */ + var ColoPicker = (function ColoPicker() { + + var colorpicker; + var hue_area; + var gradient_area; + var alpha_area; + var gradient_picker; + var hue_selector; + var alpha_selector; + var pick_object; + var info_rgb; + var info_hsv; + var info_hexa; + var output_color; + var color = new Color(); + var subscribers = []; + + var updateColor = function updateColor(e) { + var x = e.pageX - gradient_area.offsetLeft; + var y = e.pageY - gradient_area.offsetTop; + + // width and height should be the same + var size = gradient_area.clientWidth; + + if (x > size) + x = size; + if (y > size) + y = size; + + if (x < 0) x = 0; + if (y < 0) y = 0; + + var value = 100 - (y * 100 / size) | 0; + var saturation = x * 100 / size | 0; + + color.setHSV(color.hue, saturation, value); + // should update just + // color pointer location + updateUI(); + notify("color", color); + } + + var updateHue = function updateHue(e) { + var x = e.pageX - hue_area.offsetLeft; + var width = hue_area.clientWidth; + + if (x < 0) x = 0; + if (x > width) x = width; + + var hue = ((360 * x) / width) | 0; + if (hue === 360) hue = 359; + + color.setHSV(hue, color.saturation, color.value); + + // should update just + // hue pointer location + // picker area background + // alpha area background + updateUI(); + notify("color", color); + } + + var updateAlpha = function updateAlpha(e) { + var x = e.pageX - alpha_area.offsetLeft; + var width = alpha_area.clientWidth; + + if (x < 0) x = 0; + if (x > width) x = width; + + color.a = (x / width).toFixed(2); + + // should update just + // alpha pointer location + updateUI(); + notify("color", color); + } + + var setHueGfx = function setHueGfx(hue) { + var sat = color.saturation; + var val = color.value; + var alpha = color.a; + + color.setHSV(hue, 100, 100); + gradient_area.style.backgroundColor = color.getHexa(); + + color.a = 0; + var start = color.getRGBA(); + color.a = 1; + var end = color.getRGBA(); + color.a = alpha; + + var gradient = '-moz-linear-gradient(left, ' + start + '0%, ' + end + ' 100%)'; + alpha_area.style.background = gradient; + } + + var updateUI = function updateUI() { + var x, y; // coordinates + var size; // size of the area + var offset; // pointer graphic selector offset + + // Set color pointer location + size = gradient_area.clientWidth; + offset = gradient_picker.clientWidth / 2 + 2; + + x = (color.saturation * size / 100) | 0; + y = size - (color.value * size / 100) | 0; + + gradient_picker.style.left = x - offset + "px"; + gradient_picker.style.top = y - offset + "px"; + + // Set hue pointer location + size = hue_area.clientWidth; + offset = hue_selector.clientWidth/2; + x = (color.hue * size / 360 ) | 0; + hue_selector.style.left = x - offset + "px"; + + // Set alpha pointer location + size = alpha_area.clientWidth; + offset = alpha_selector.clientWidth/2; + x = (color.a * size) | 0; + alpha_selector.style.left = x - offset + "px"; + + // Set picker area background + var nc = new Color(); + nc.copy(color); + if (nc.hue === 360) nc.hue = 0; + nc.setHSV(nc.hue, 100, 100); + gradient_area.style.backgroundColor = nc.getHexa(); + + // Set alpha area background + nc.copy(color); + nc.a = 0; + var start = nc.getRGBA(); + nc.a = 1; + var end = nc.getRGBA(); + var gradient = '-moz-linear-gradient(left, ' + start + '0%, ' + end + ' 100%)'; + alpha_area.style.background = gradient; + + // Update color info + notify("color", color); + notify("hue", color.hue); + notify("saturation", color.saturation); + notify("value", color.value); + notify("r", color.r); + notify("g", color.g); + notify("b", color.b); + notify("a", color.a); + notify("hexa", color.getHexa()); + output_color.style.backgroundColor = color.getRGBA(); + } + + var setInputComponent = function setInputComponent(node) { + var topic = node.getAttribute('data-topic'); + var title = node.getAttribute('data-title'); + var action = node.getAttribute('data-action'); + title = title === null ? '' : title; + + var input = document.createElement('input'); + var info = document.createElement('span'); + info.textContent = title; + + input.setAttribute('type', 'text'); + input.setAttribute('data-action', 'set-' + action + '-' + topic); + node.appendChild(info); + node.appendChild(input); + + input.addEventListener('click', function(e) { + this.select(); + }); + + input.addEventListener('change', function(e) { + if (action === 'HSV') + inputChangeHSV(topic); + if (action === 'RGB') + inputChangeRGB(topic); + if (action === 'alpha') + inputChangeAlpha(topic); + if (action === 'hexa') + inputChangeHexa(topic); + }); + + subscribe(topic, function(value) { + node.children[1].value = value; + }); + } + + var inputChangeHSV = function actionHSV(topic) { + var selector = "[data-action='set-HSV-" + topic + "']"; + var node = document.querySelector("#colorpicker " + selector); + var value = parseInt(node.value); + + if (typeof value === 'number' && isNaN(value) === false && + value >= 0 && value < 360) + color[topic] = value; + + color.updateRGB(); + updateUI(); + } + + var inputChangeRGB = function inputChangeRGB(topic) { + var selector = "[data-action='set-RGB-" + topic + "']"; + var node = document.querySelector("#colorpicker " + selector); + var value = parseInt(node.value); + + if (typeof value === 'number' && isNaN(value) === false && + value >= 0 && value <= 255) + color[topic] = value; + + color.updateHSV(); + updateUI(); + } + + var inputChangeAlpha = function inputChangeAlpha(topic) { + var selector = "[data-action='set-alpha-" + topic + "']"; + var node = document.querySelector("#colorpicker " + selector); + var value = parseFloat(node.value); + + if (typeof value === 'number' && isNaN(value) === false && + value >= 0 && value <= 1) + color.a = value.toFixed(2); + + updateUI(); + } + + var inputChangeHexa = function inputChangeHexa(topic) { + var selector = "[data-action='set-hexa-" + topic + "']"; + var node = document.querySelector("#colorpicker " + selector); + var value = node.value; + color.setHexa(value); + color.updateHSV(); + updateUI(); + } + + var setMouseTracking = function setMouseTracking(elem, callback) { + + elem.addEventListener("mousedown", function(e) { + callback(e); + document.addEventListener("mousemove", callback); + }); + + document.addEventListener("mouseup", function(e) { + document.removeEventListener("mousemove", callback); + }); + } + + /* + * Observer + */ + var setColor = function setColor(obj) { + if(obj instanceof Color !== true) { + console.log("Typeof instance not Color"); + return; + } + color.copy(obj); + updateUI(); + } + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + + subscribers[topic].push(callback); + } + + var unsubscribe = function unsubscribe(callback) { + subscribers.indexOf(callback); + subscribers.splice(index, 1); + } + + var notify = function notify(topic, value) { + for (var i in subscribers[topic]) + subscribers[topic][i](value); + } + + var init = function init() { + colorpicker = getElemById("colorpicker"); + hue_area = getElemById("hue"); + gradient_area = getElemById("gradient"); + alpha_area = getElemById("alpha"); + gradient_picker = getElemById("gradient_picker"); + hue_selector = getElemById("hue_selector"); + alpha_selector = getElemById("alpha_selector"); + output_color = getElemById("output_color"); + + var elem = document.querySelectorAll('#colorpicker .input'); + var size = elem.length; + for (var i = 0; i < size; i++) + setInputComponent(elem[i]); + + setMouseTracking(gradient_area, updateColor); + setMouseTracking(hue_area, updateHue); + setMouseTracking(alpha_area, updateAlpha); + + } + + return { + init : init, + setColor : setColor, + subscribe : subscribe, + unsubscribe : unsubscribe + } + + })(); + + /** + * Shadow dragging + */ + var PreviewMouseTracking = (function Drag() { + var active = false; + var lastX = 0; + var lastY = 0; + var subscribers = []; + + var init = function init(id) { + var elem = getElemById(id); + elem.addEventListener('mousedown', dragStart, false); + document.addEventListener('mouseup', dragEnd, false); + } + + var dragStart = function dragStart(e) { + if (e.button !== 0) + return; + + active = true; + lastX = e.clientX; + lastY = e.clientY; + document.addEventListener('mousemove', mouseDrag, false); + } + + var dragEnd = function dragEnd(e) { + if (e.button !== 0) + return; + + if (active === true) { + active = false; + document.removeEventListener('mousemove', mouseDrag, false); + } + } + + var mouseDrag = function mouseDrag(e) { + notify(e.clientX - lastX, e.clientY - lastY); + lastX = e.clientX; + lastY = e.clientY; + } + + var subscribe = function subscribe(callback) { + subscribers.push(callback); + } + + var unsubscribe = function unsubscribe(callback) { + var index = subscribers.indexOf(callback); + subscribers.splice(index, 1); + } + + var notify = function notify(deltaX, deltaY) { + for (var i in subscribers) + subscribers[i](deltaX, deltaY); + } + + return { + init : init, + subscribe : subscribe, + unsubscribe : unsubscribe + } + + })(); + + /* + * Element Class + */ + var CssClass = function CssClass(id) { + this.left = 0; + this.top = 0; + this.rotate = 0; + this.width = 300; + this.height = 100; + this.display = true; + this.border = true; + this.zIndex = -1; + this.bgcolor = new Color(); + this.id = id; + this.node = getElemById('obj-' + id); + this.object = getElemById(id); + this.shadowID = null; + this.shadows = [] + this.render = []; + this.init(); + } + + CssClass.prototype.init = function init() { + this.left = ((this.node.parentNode.clientWidth - this.node.clientWidth) / 2) | 0; + this.top = ((this.node.parentNode.clientHeight - this.node.clientHeight) / 2) | 0; + + this.setTop(this.top); + this.setLeft(this.left); + this.setHeight(this.height); + this.setWidth(this.width); + this.bgcolor.setHSV(0, 0, 100); + this.updateBgColor(this.bgcolor); + } + + CssClass.prototype.updatePos = function updatePos(deltaX, deltaY) { + this.left += deltaX; + this.top += deltaY; + this.node.style.top = this.top + "px"; + this.node.style.left = this.left + "px"; + SliderManager.setValue("left", this.left); + SliderManager.setValue("top", this.top); + } + + CssClass.prototype.setLeft = function setLeft(value) { + this.left = value; + this.node.style.left = this.left + "px"; + OutputManager.updateProperty(this.id, 'left', this.left + 'px'); + } + + CssClass.prototype.setTop = function setTop(value) { + this.top = value; + this.node.style.top = this.top + 'px'; + OutputManager.updateProperty(this.id, 'top', this.top + 'px'); + } + + CssClass.prototype.setWidth = function setWidth(value) { + this.width = value; + this.node.style.width = this.width + 'px'; + OutputManager.updateProperty(this.id, 'width', this.width + 'px'); + } + + CssClass.prototype.setHeight = function setHeight(value) { + this.height = value; + this.node.style.height = this.height + 'px'; + OutputManager.updateProperty(this.id, 'height', this.height + 'px'); + } + + // Browser support + CssClass.prototype.setRotate = function setRotate(value) { + var cssvalue = 'rotate(' + value +'deg)'; + + this.node.style.transform = cssvalue; + this.node.style.webkitTransform = cssvalue; + this.node.style.msTransform = cssvalue; + + if (value !== 0) { + if (this.rotate === 0) { + OutputManager.toggleProperty(this.id, 'transform', true); + OutputManager.toggleProperty(this.id, '-webkit-transform', true); + OutputManager.toggleProperty(this.id, '-ms-transform', true); + } + } + else { + OutputManager.toggleProperty(this.id, 'transform', false); + OutputManager.toggleProperty(this.id, '-webkit-transform', false); + OutputManager.toggleProperty(this.id, '-ms-transform', false); + } + + OutputManager.updateProperty(this.id, 'transform', cssvalue); + OutputManager.updateProperty(this.id, '-webkit-transform', cssvalue); + OutputManager.updateProperty(this.id, '-ms-transform', cssvalue); + this.rotate = value; + } + + CssClass.prototype.setzIndex = function setzIndex(value) { + this.node.style.zIndex = value; + OutputManager.updateProperty(this.id, 'z-index', value); + this.zIndex = value; + } + + CssClass.prototype.toggleDisplay = function toggleDisplay(value) { + if (typeof value !== "boolean" || this.display === value) + return; + + this.display = value; + var display = this.display === true ? "block" : "none"; + this.node.style.display = display; + this.object.style.display = display; + } + + CssClass.prototype.toggleBorder = function toggleBorder(value) { + if (typeof value !== "boolean" || this.border === value) + return; + + this.border = value; + var border = this.border === true ? "1px solid #CCC" : "none"; + this.node.style.border = border; + } + + CssClass.prototype.updateBgColor = function updateBgColor(color) { + this.bgcolor.copy(color); + this.node.style.backgroundColor = color.getColor(); + OutputManager.updateProperty(this.id, 'background-color', color.getColor()); + } + + CssClass.prototype.updateShadows = function updateShadows() { + if (this.render.length === 0) + OutputManager.toggleProperty(this.id, 'box-shadow', false); + if (this.render.length === 1) + OutputManager.toggleProperty(this.id, 'box-shadow', true); + + this.node.style.boxShadow = this.render.join(", "); + OutputManager.updateProperty(this.id, 'box-shadow', this.render.join(", \n")); + + } + + /** + * Tool Manager + */ + var Tool = (function Tool() { + + var preview; + var classes = []; + var active = null; + var animate = false; + + /* + * Toll actions + */ + var addCssClass = function addCssClass(id) { + classes[id] = new CssClass(id); + } + + var setActiveClass = function setActiveClass(id) { + active = classes[id]; + active.shadowID = null; + ColoPicker.setColor(classes[id].bgcolor); + SliderManager.setValue("top", active.top); + SliderManager.setValue("left", active.left); + SliderManager.setValue("rotate", active.rotate); + SliderManager.setValue("z-index", active.zIndex); + SliderManager.setValue("width", active.width); + SliderManager.setValue("height", active.height); + ButtonManager.setValue("border-state", active.border); + active.updateShadows(); + } + + var disableClass = function disableClass(topic) { + classes[topic].toggleDisplay(false); + ButtonManager.setValue(topic, false); + } + + var addShadow = function addShadow(position) { + if (animate === true) + return -1; + + active.shadows.splice(position, 0, new Shadow()); + active.render.splice(position, 0, null); + } + + var swapShadow = function swapShadow(id1, id2) { + var x = active.shadows[id1]; + active.shadows[id1] = active.shadows[id2]; + active.shadows[id2] = x; + updateShadowCSS(id1); + updateShadowCSS(id2); + } + + var deleteShadow = function deleteShadow(position) { + active.shadows.splice(position, 1); + active.render.splice(position, 1); + active.updateShadows(); + } + + var setActiveShadow = function setActiveShadow(id, glow) { + active.shadowID = id; + ColoPicker.setColor(active.shadows[id].color); + ButtonManager.setValue("inset", active.shadows[id].inset); + SliderManager.setValue("blur", active.shadows[id].blur); + SliderManager.setValue("spread", active.shadows[id].spread); + SliderManager.setValue("posX", active.shadows[id].posX); + SliderManager.setValue("posY", active.shadows[id].posY); + if (glow === true) + addGlowEffect(id); + } + + var addGlowEffect = function addGlowEffect(id) { + if (animate === true) + return; + + animate = true; + var store = new Shadow(); + var shadow = active.shadows[id]; + + store.copy(shadow); + shadow.color.setRGBA(40, 125, 200, 1); + shadow.blur = 10; + shadow.spread = 10; + + active.node.style.transition = "box-shadow 0.2s"; + updateShadowCSS(id); + + setTimeout(function() { + shadow.copy(store); + updateShadowCSS(id); + setTimeout(function() { + active.node.style.removeProperty("transition"); + animate = false; + }, 100); + }, 200); + } + + var updateActivePos = function updateActivePos(deltaX, deltaY) { + if (active.shadowID === null) + active.updatePos(deltaX, deltaY); + else + updateShadowPos(deltaX, deltaY); + } + + /* + * Shadow properties + */ + var updateShadowCSS = function updateShadowCSS(id) { + active.render[id] = active.shadows[id].computeCSS(); + active.updateShadows(); + } + + var toggleShadowInset = function toggleShadowInset(value) { + if (active.shadowID === null) + return; + active.shadows[active.shadowID].toggleInset(value); + updateShadowCSS(active.shadowID); + } + + var updateShadowPos = function updateShadowPos(deltaX, deltaY) { + var shadow = active.shadows[active.shadowID]; + shadow.posX += deltaX; + shadow.posY += deltaY; + SliderManager.setValue("posX", shadow.posX); + SliderManager.setValue("posY", shadow.posY); + updateShadowCSS(active.shadowID); + } + + var setShadowPosX = function setShadowPosX(value) { + if (active.shadowID === null) + return; + active.shadows[active.shadowID].posX = value; + updateShadowCSS(active.shadowID); + } + + var setShadowPosY = function setShadowPosY(value) { + if (active.shadowID === null) + return; + active.shadows[active.shadowID].posY = value; + updateShadowCSS(active.shadowID); + } + + var setShadowBlur = function setShadowBlur(value) { + if (active.shadowID === null) + return; + active.shadows[active.shadowID].blur = value; + updateShadowCSS(active.shadowID); + } + + var setShadowSpread = function setShadowSpread(value) { + if (active.shadowID === null) + return; + active.shadows[active.shadowID].spread = value; + updateShadowCSS(active.shadowID); + } + + var updateShadowColor = function updateShadowColor(color) { + active.shadows[active.shadowID].color.copy(color); + updateShadowCSS(active.shadowID); + } + + /* + * Element Properties + */ + var updateColor = function updateColor(color) { + if (active.shadowID === null) + active.updateBgColor(color); + else + updateShadowColor(color); + } + + var init = function init() { + preview = getElemById("preview"); + + ColoPicker.subscribe("color", updateColor); + PreviewMouseTracking.subscribe(updateActivePos); + + // Affects shadows + ButtonManager.subscribe("inset", toggleShadowInset); + SliderManager.subscribe("posX", setShadowPosX); + SliderManager.subscribe("posY", setShadowPosY); + SliderManager.subscribe("blur", setShadowBlur); + SliderManager.subscribe("spread", setShadowSpread); + + // Affects element + SliderManager.subscribe("top", function(value){ + active.setTop(value); + }); + SliderManager.subscribe("left", function(value){ + active.setLeft(value); + }); + SliderManager.subscribe("rotate", function(value) { + if (active == classes["element"]) + return; + active.setRotate(value); + }); + + SliderManager.subscribe("z-index", function(value) { + if (active == classes["element"]) + return; + active.setzIndex(value); + }); + + SliderManager.subscribe("width", function(value) { + active.setWidth(value) + }); + + SliderManager.subscribe("height", function(value) { + active.setHeight(value) + }); + + // Actions + classes['before'].top = -30; + classes['before'].left = -30; + classes['after'].top = 30; + classes['after'].left = 30; + classes['before'].toggleDisplay(false); + classes['after'].toggleDisplay(false); + ButtonManager.setValue('before', false); + ButtonManager.setValue('after', false); + + ButtonManager.subscribe("before", classes['before'].toggleDisplay.bind(classes['before'])); + ButtonManager.subscribe("after", classes['after'].toggleDisplay.bind(classes['after'])); + + ButtonManager.subscribe("border-state", function(value) { + active.toggleBorder(value); + }); + + } + + return { + init : init, + addShadow : addShadow, + swapShadow : swapShadow, + addCssClass : addCssClass, + disableClass : disableClass, + deleteShadow : deleteShadow, + setActiveClass : setActiveClass, + setActiveShadow : setActiveShadow + } + + })(); + + /** + * Layer Manager + */ + var LayerManager = (function LayerManager() { + var stacks = []; + var active = { + node : null, + stack : null + } + var elements = {}; + + var mouseEvents = function mouseEvents(e) { + var node = e.target; + var type = node.getAttribute('data-type'); + + if (type === 'subject') + setActiveStack(stacks[node.id]); + + if (type === 'disable') { + Tool.disableClass(node.parentNode.id); + setActiveStack(stacks['element']); + } + + if (type === 'add') + active.stack.addLayer(); + + if (type === 'layer') + active.stack.setActiveLayer(node); + + if (type === 'delete') + active.stack.deleteLayer(node.parentNode); + + if (type === 'move-up') + active.stack.moveLayer(1); + + if (type === 'move-down') + active.stack.moveLayer(-1); + } + + var setActiveStack = function setActiveStack(stackObj) { + active.stack.hide(); + active.stack = stackObj; + active.stack.show(); + } + + /* + * Stack object + */ + var Stack = function Stack(subject) { + var S = document.createElement('div'); + var title = document.createElement('div'); + var stack = document.createElement('div'); + + S.className = 'container'; + stack.className = 'stack'; + title.className = 'title'; + title.textContent = subject.getAttribute('data-title'); + S.appendChild(title); + S.appendChild(stack); + + this.id = subject.id; + this.container = S; + this.stack = stack; + this.subject = subject; + this.order = []; + this.uid = 0; + this.count = 0; + this.layer = null; + this.layerID = 0; + } + + Stack.prototype.addLayer = function addLayer() { + if (Tool.addShadow(this.layerID) == -1) + return; + + var uid = this.getUID(); + var layer = this.createLayer(uid); + + if (this.layer === null && this.stack.children.length >= 1) + this.layer = this.stack.children[0]; + + this.stack.insertBefore(layer, this.layer); + this.order.splice(this.layerID, 0, uid); + this.count++; + this.setActiveLayer(layer); + } + + Stack.prototype.createLayer = function createLayer(uid) { + var layer = document.createElement('div'); + var del = document.createElement('span'); + + layer.className = 'node'; + layer.setAttribute('data-shid', uid); + layer.setAttribute('data-type', 'layer'); + layer.textContent = 'shadow ' + uid; + + del.className = 'delete'; + del.setAttribute('data-type', 'delete'); + + layer.appendChild(del); + return layer; + } + + Stack.prototype.getUID = function getUID() { + return this.uid++; + } + + // SOLVE IE BUG + Stack.prototype.moveLayer = function moveLayer(direction) { + if (this.count <= 1 || this.layer === null) + return; + if (direction === -1 && this.layerID === (this.count - 1) ) + return; + if (direction === 1 && this.layerID === 0 ) + return; + + if (direction === -1) { + var before = null; + Tool.swapShadow(this.layerID, this.layerID + 1); + this.swapOrder(this.layerID, this.layerID + 1); + this.layerID += 1; + + if (this.layerID + 1 !== this.count) + before = this.stack.children[this.layerID + 1]; + + this.stack.insertBefore(this.layer, before); + Tool.setActiveShadow(this.layerID, false); + } + + if (direction === 1) { + Tool.swapShadow(this.layerID, this.layerID - 1); + this.swapOrder(this.layerID, this.layerID - 1); + this.layerID -= 1; + this.stack.insertBefore(this.layer, this.stack.children[this.layerID]); + Tool.setActiveShadow(this.layerID, false); + } + } + + Stack.prototype.swapOrder = function swapOrder(pos1, pos2) { + var x = this.order[pos1]; + this.order[pos1] = this.order[pos2]; + this.order[pos2] = x; + } + + Stack.prototype.deleteLayer = function deleteLayer(node) { + var shadowID = node.getAttribute('data-shid') | 0; + var index = this.order.indexOf(shadowID); + this.stack.removeChild(this.stack.children[index]); + this.order.splice(index, 1); + this.count--; + + Tool.deleteShadow(index); + + if (index > this.layerID) + return; + + if (index == this.layerID) { + if (this.count >= 1) { + this.layerID = 0; + this.setActiveLayer(this.stack.children[0], true); + } + else { + this.layer = null; + this.show(); + } + } + + if (index < this.layerID) { + this.layerID--; + Tool.setActiveShadow(this.layerID, true); + } + + } + + Stack.prototype.setActiveLayer = function setActiveLayer(node) { + elements.shadow_properties.style.display = 'block'; + elements.element_properties.style.display = 'none'; + + if (this.layer) + this.layer.removeAttribute('data-active'); + + this.layer = node; + this.layer.setAttribute('data-active', 'layer'); + + var shadowID = node.getAttribute('data-shid') | 0; + this.layerID = this.order.indexOf(shadowID); + Tool.setActiveShadow(this.layerID, true); + } + + Stack.prototype.unsetActiveLayer = function unsetActiveLayer() { + if (this.layer) + this.layer.removeAttribute('data-active'); + + this.layer = null; + this.layerID = 0; + } + + Stack.prototype.hide = function hide() { + this.unsetActiveLayer(); + this.subject.removeAttribute('data-active'); + var style = this.container.style; + style.left = '100%'; + style.zIndex = '0'; + } + + Stack.prototype.show = function show() { + elements.shadow_properties.style.display = 'none'; + elements.element_properties.style.display = 'block'; + + if (this.id === 'element') { + elements.zIndex.style.display = 'none'; + elements.transform_rotate.style.display = 'none'; + } + else { + elements.zIndex.style.display = 'block'; + elements.transform_rotate.style.display = 'block'; + } + + this.subject.setAttribute('data-active', 'subject'); + var style = this.container.style; + style.left = '0'; + style.zIndex = '10'; + Tool.setActiveClass(this.id); + } + + function init() { + + var elem, size; + var layerManager = getElemById("layer_manager"); + var layerMenu = getElemById("layer_menu"); + var container = getElemById("stack_container"); + + elements.shadow_properties = getElemById('shadow_properties'); + elements.element_properties = getElemById('element_properties'); + elements.transform_rotate = getElemById('transform_rotate'); + elements.zIndex = getElemById('z-index'); + + elem = document.querySelectorAll('#layer_menu [data-type="subject"]'); + size = elem.length; + + for (var i = 0; i < size; i++) { + var S = new Stack(elem[i]); + stacks[elem[i].id] = S; + container.appendChild(S.container); + Tool.addCssClass(elem[i].id); + } + + active.stack = stacks['element']; + stacks['element'].show(); + + layerManager.addEventListener("click", mouseEvents); + layerMenu.addEventListener("click", mouseEvents); + + ButtonManager.subscribe("before", function(value) { + if (value === false && active.stack === stacks['before']) + setActiveStack(stacks['element']) + if (value === true && active.stack !== stacks['before']) + setActiveStack(stacks['before']) + }); + + ButtonManager.subscribe("after", function(value) { + if (value === false && active.stack === stacks['after']) + setActiveStack(stacks['element']) + if (value === true && active.stack !== stacks['after']) + setActiveStack(stacks['after']) + }); + } + + return { + init : init + } + })(); + + /* + * OutputManager + */ + var OutputManager = (function OutputManager() { + var classes = []; + var buttons = []; + var active = null; + var menu = null; + var button_offset = 0; + + var crateOutputNode = function(topic, property) { + + var prop = document.createElement('div'); + var name = document.createElement('span'); + var value = document.createElement('span'); + + var pmatch = property.match(/(^([a-z0-9\-]*)=\[([a-z0-9\-\"]*)\])|^([a-z0-9\-]*)/i); + + name.textContent = '\t' + pmatch[4]; + + if (pmatch[3] !== undefined) { + name.textContent = '\t' + pmatch[2]; + value.textContent = pmatch[3] + ';'; + } + + name.textContent += ': '; + prop.className = 'css-property'; + name.className = 'name'; + value.className = 'value'; + prop.appendChild(name); + prop.appendChild(value); + + classes[topic].node.appendChild(prop); + classes[topic].line[property] = prop; + classes[topic].prop[property] = value; + } + + var OutputClass = function OutputClass(node) { + var topic = node.getAttribute('data-topic'); + var prop = node.getAttribute('data-prop'); + var name = node.getAttribute('data-name'); + var properties = prop.split(' '); + + classes[topic] = {}; + classes[topic].node = node; + classes[topic].prop = []; + classes[topic].line = []; + classes[topic].button = new Button(topic); + + var open_decl = document.createElement('div'); + var end_decl = document.createElement('div'); + + open_decl.textContent = name + ' {'; + end_decl.textContent = '}'; + node.appendChild(open_decl); + + for (var i in properties) + crateOutputNode(topic, properties[i]); + + node.appendChild(end_decl); + } + + var Button = function Button(topic) { + var button = document.createElement('div'); + + button.className = 'button'; + button.textContent = topic; + button.style.left = button_offset + 'px'; + button_offset += 100; + + button.addEventListener("click", function() { + toggleDisplay(topic); + }) + + menu.appendChild(button); + return button; + } + + var toggleDisplay = function toggleDisplay(topic) { + active.button.removeAttribute('data-active'); + active.node.style.display = 'none'; + active = classes[topic]; + active.node.style.display = 'block'; + active.button.setAttribute('data-active', 'true'); + } + + var toggleButton = function toggleButton(topic, value) { + var display = (value === true) ? 'block' : 'none'; + classes[topic].button.style.display = display; + + if (value === true) + toggleDisplay(topic); + else + toggleDisplay('element'); + } + + var updateProperty = function updateProperty(topic, property, data) { + try { + classes[topic].prop[property].textContent = data + ';'; + } + catch(error) { + // console.log("ERROR undefined : ", topic, property, data); + } + } + + var toggleProperty = function toggleProperty(topic, property, value) { + var display = (value === true) ? 'block' : 'none'; + try { + classes[topic].line[property].style.display = display; + } + catch(error) { + // console.log("ERROR undefined : ",classes, topic, property, value); + } + } + + var init = function init() { + + menu = getElemById('menu'); + + var elem = document.querySelectorAll('#output .output'); + var size = elem.length; + for (var i = 0; i < size; i++) + OutputClass(elem[i]); + + active = classes['element']; + toggleDisplay('element'); + + ButtonManager.subscribe("before", function(value) { + toggleButton('before', value); + }); + + ButtonManager.subscribe("after", function(value) { + toggleButton('after', value); + }); + } + + return { + init : init, + updateProperty : updateProperty, + toggleProperty : toggleProperty + } + + })(); + + /** + * Init Tool + */ + var init = function init() { + ButtonManager.init(); + OutputManager.init(); + ColoPicker.init(); + SliderManager.init(); + LayerManager.init(); + PreviewMouseTracking.init("preview"); + Tool.init(); + } + + return { + init : init + } + +})(); diff --git a/tools/box-shadow-generator/styles.css b/tools/box-shadow-generator/styles.css new file mode 100644 index 00000000..07fd139e --- /dev/null +++ b/tools/box-shadow-generator/styles.css @@ -0,0 +1,938 @@ +/* GRID OF TWELVE + * ========================================================================== */ + +.span_12 { + width: 100%; +} + +.span_11 { + width: 91.46%; +} + +.span_10 { + width: 83%; +} + +.span_9 { + width: 74.54%; +} + +.span_8 { + width: 66.08%; +} + +.span_7 { + width: 57.62%; +} + +.span_6 { + width: 49.16%; +} + +.span_5 { + width: 40.7%; +} + +.span_4 { + width: 32.24%; +} + +.span_3 { + width: 23.78%; +} + +.span_2 { + width: 15.32%; +} + +.span_1 { + width: 6.86%; +} + +/* SECTIONS + * ========================================================================== */ + +.section { + clear: both; + padding: 0px; + margin: 0px; +} + +/* GROUPING + * ========================================================================== */ + +.group:before, .group:after { + content: ""; + display: table; +} + +.group:after { + clear:both; +} + +.group { + zoom: 1; /* For IE 6/7 (trigger hasLayout) */ +} + +/* GRID COLUMN SETUP + * ========================================================================== */ + +.col { + display: block; + float:left; + margin: 1% 0 1% 1.6%; +} + +.col:first-child { + margin-left: 0; +} /* all browsers except IE6 and lower */ + +/* + * UI Slider + */ + +.slidergroup { + height: 20px; + margin: 10px 0; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + -moz-user-select: none; + user-select: none; +} + +.slidergroup * { + float: left; + height: 100%; + line-height: 100%; +} + +/* Slider */ + +.ui-slider { + height: 10px; + width: 200px; + margin: 4px 10px; + display: block; + border: 1px solid #999; + border-radius: 3px; + background: #EEE; +} + +.ui-slider:hover { + cursor: pointer; +} + +.ui-slider-name { + width: 90px; + padding: 0 10px 0 0; + text-align: right; + text-transform: lowercase; +} + +.ui-slider-pointer { + width: 13px; + height: 13px; + background-color: #EEE; + border: 1px solid #2C9FC9; + border-radius: 3px; + position: relative; + top: -3px; + left: 0%; +} + +.ui-slider-btn-set { + width: 25px; + background-color: #2C9FC9; + border-radius: 3px; + color: #FFF; + font-weight: bold; + text-align: center; +} + +.ui-slider-btn-set:hover { + background-color: #379B4A; + cursor: pointer; +} + +.ui-slider-input > input { + margin: 0 10px; + padding: 0; + width: 50px; + text-align: center; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +/* + * UI Button + */ + +/* Checkbox */ + +.ui-checkbox { + text-align: center; + font-size: 16px; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + line-height: 1.5em; + color: #FFF; + + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.ui-checkbox > input { + display: none; +} + +.ui-checkbox > label { + font-size: 12px; + padding: 0.333em 1.666em 0.5em; + height: 1em; + line-height: 1em; + + background-color: #888; + background-image: url("disabled.png"); + background-position: center center; + background-repeat: no-repeat; + + color: #FFF; + border-radius: 3px; + font-weight: bold; + float: left; +} + +.ui-checkbox .text { + padding-left: 34px; + background-position: center left 10px; +} + +.ui-checkbox .left { + padding-right: 34px; + padding-left: 1.666em; + background-position: center right 10px; +} + +.ui-checkbox > label:hover { + cursor: pointer; +} + +.ui-checkbox > input:checked + label { + background-image: url("checked.png"); + background-color: #379B4A; +} + +/* + * BOX SHADOW GENERATOR TOOL + */ + +body { + max-width: 1000px; + height: 800px; + margin: 20px auto 0; + + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; +} + +#container { + width: 100%; + padding: 2px; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +/* container with shadows stacks */ +#stack_container { + height: 400px; + overflow: hidden; + position: relative; + border: 1px solid #CCC; + border-radius: 3px; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#stack_container .container { + height: 100%; + width: 100%; + position: absolute; + left: 100%; + transition-property: left; + transition-duration: 0.5s; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#stack_container .title { + text-align: center; + font-weight: bold; + line-height: 2em; + border-bottom: 1px solid #43A6E1; + color: #666; +} + +/* + * Stack of Layers for shadow + */ + +#layer_manager { + width: 17%; + background-color: #FEFEFE; + margin: 0 1% 0 0; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + float: left; +} + +#layer_manager .button { + width: 30%; + height: 25px; + margin:0 0 10px; + color: #333; + background-color: #EEE; + text-align: center; + font-size: 0.75em; + line-height: 1.5em; + border: 1px solid #CCC; + border-radius: 3px; + + display: block; + background-position: center center; + background-repeat: no-repeat; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + float: left; +} + +#layer_manager .button:hover { + background-color: #3380C4; + border: 1px solid #3380C4; + cursor: pointer; +} + +#layer_manager [data-type='add'] { + background-image: url("add-black.png"); +} + +#layer_manager [data-type='add']:hover { + background-image: url("add-white.png"); +} + +#layer_manager [data-type='move-up'] { + background-image: url("up-black.png"); + margin-left: 5%; + margin-right: 5%; +} + +#layer_manager [data-type='move-up']:hover { + background-image: url("up-white.png"); +} + +#layer_manager [data-type='move-down'] { + background-image: url("down-black.png"); +} + +#layer_manager [data-type='move-down']:hover { + background-image: url("down-white.png"); +} + +/* shadows classes */ + +#layer_manager .node { + width: 100%; + margin: 5px 0; + padding: 5px; + text-align: center; + background-color: #EEE; + border: 1px solid #DDD; + font-size: 0.75em; + line-height: 1.5em; + color: #333; + border-radius: 3px; + + position: relative; + display: block; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#layer_manager .node:hover { + color: #FFF; + background-color: #3380C4; + cursor: pointer; +} + +/* active element styling */ + +#layer_manager [data-active='layer'] { + color: #FFF; + border: none; + background-color: #379B4A; +} + +#layer_manager [data-active='subject'] { + color: #FFF; + background-color: #467FC9; +} + +/* delete button */ + +#layer_manager .delete { + width: 1.5em; + height: 100%; + float: right; + border-radius: 3px; + background-image: url("delete-white.png"); + background-position: center center; + background-repeat: no-repeat; + position: absolute; + top: 0; + right: 10px; + display: none; +} + +#layer_manager .delete:hover { + background-image: url("delete-yellow.png"); +} + +#layer_manager .node:hover .delete { + display: block; +} + +#layer_manager .stack { + padding: 0 5px; + max-height: 90%; + overflow: auto; + overflow-x: hidden; +} + +/* + * Layer Menu + */ + +#layer_menu { + margin: 0 0 10px 0; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#layer_menu .button { + width: 100px; + margin: 0 5px 0 0; + padding: 2.5px; + color: #333; + background-color: #EEE; + border: 1px solid #CCC; + border-radius: 3px; + text-align: center; + font-size: 0.75em; + line-height: 1.5em; + + position: relative; + display: block; + float: left; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#layer_menu .button:hover { + color: #FFF; + background-color: #3380C4; + border: 1px solid #3380C4; + cursor: pointer; +} + +#layer_menu .delete { + width: 1.5em; + height: 100%; + float: right; + border-radius: 3px; + background-image: url("delete-white.png"); + background-position: center center; + background-repeat: no-repeat; + position: absolute; + top: 0; + right: 5px; + display: none; +} + +#layer_menu .delete:hover { + background-image: url("delete-yellow.png"); +} + +#layer_menu .button:hover .delete { + display: block; +} + +/* + * active element styling + */ + +#layer_menu [data-active='subject'] { + color: #FFF; + background-color: #379B4A; + border: 1px solid #379B4A; +} + +/* Checkbox */ + +#layer_menu .ui-checkbox > label { + height: 15px; + line-height: 17px; + font-weight: normal; + width: 46px; + margin: 0 5px 0 0; +} + +#layer_menu .ui-checkbox > input:checked + label { + display: none; +} + +/******************************************************************************/ +/******************************************************************************/ +/* + * Preview Area + */ + +#preview_zone { + width: 82%; + float: left; + +} + +#preview { + width: 100%; + height: 400px; + border: 1px solid #CCC; + border-radius: 3px; + text-align: center; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + cursor: move; + float: left; +} + +#preview .content { + width: 100%; + height: 100%; + display: block; +} + +#obj-element { + width: 300px; + height: 100px; + border: 1px solid #CCC; + background: #FFF; + position: relative; +} + +#obj-before { + height: 100%; + width: 100%; + background: #999; + border: 1px solid #CCC; + text-align: left; + display : block; + position: absolute; + z-index: -1; +} + +#obj-after { + height: 100%; + width: 100%; + background: #DDD; + border: 1px solid #CCC; + text-align: right; + display : block; + position: absolute; + z-index: -1; +} + +/******************************************************************************/ +/******************************************************************************/ + +/** + * Controls + */ + +.wrap-left { + float: left; + overflow: hidden; +} + +.wrap-right { + float: right; + overflow: hidden; +} + +.wrap-left > * { + float: left; +} + +.wrap-right > * { + float: right; +} + +@media (min-width: 960px) { + + .wrap-left { + width: 45%; + } + + .wrap-right { + width: 55%; + } +} + +@media (max-width: 959px) { + + .wrap-left { + width: 30%; + } + + .wrap-right { + width: 70%; + } +} + +#controls { + color: #444; + margin: 10px 0 0 0; +} + +#controls .category { + width: 500px; + margin: 0 auto 20px; + padding: 0; + +} + +#controls .category .title { + width: 100%; + height: 1.5em; + line-height: 1.5em; + color: #AAA; + text-align: right; +} + +#controls .category > .group { + border: 1px solid #CCC; + border-radius: 3px; +} + +/** + * Color Picker + */ + +@media (min-width: 960px) { + #controls .colorpicker { + width: 420px; + } +} + +@media (max-width: 959px) { + #controls .colorpicker { + width: 210px; + } +} + +#colorpicker { + width: 100%; + margin: 0 auto; +} + +#colorpicker .gradient { + width: 200px; + height: 200px; + margin: 5px; + background: url("picker_mask_200.png"); + background: -moz-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%), + -moz-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%); + background: -webkit-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%), + -webkit-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%); + background-color: #F00; + float: left; +} + +#colorpicker .hue { + width: 200px; + height: 30px; + margin: 5px; + background: url("hue.png"); + background: -moz-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%, + #00F 66.66%, #F0F 83.33%, #F00 100%); + background: -webkit-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%, + #00F 66.66%, #F0F 83.33%, #F00 100%); + float: left; +} + +#colorpicker .alpha { + width: 200px; + height: 30px; + margin: 5px; + border: 1px solid #CCC; + float: left; + background: url("alpha.png"); + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#colorpicker #alpha { + width: 100%; + height: 100%; + background: url("alpha_mask.png"); + background: -moz-linear-gradient(left, rgba(255, 0, 0, 0) 0%, rgba(255, 0, 0, 1) 100%); +} + +#colorpicker #gradient_picker { + width: 0.5em; + height: 0.5em; + border-radius: 0.4em; + border: 2px solid #CCC; + position: relative; + top: 20%; + left: 20%; +} + +#colorpicker #hue_selector, +#colorpicker #alpha_selector { + width: 3px; + height: 100%; + border: 1px solid #777; + background-color: #FFF; + position: relative; + top: -1px; + left: 0%; +} + +/* input HSV and RGB */ +#colorpicker .info { + width: 200px; + margin: 5px; + float: left; +} + +#colorpicker .info * { + float: left; +} + +#colorpicker .info input { + margin: 0; + text-align: center; + width: 30px; + -moz-user-select: text; + -webkit-user-select: text; + -ms-user-select: text; +} + +#colorpicker .info span { + height: 20px; + width: 30px; + text-align: center; + line-height: 20px; + display: block; +} + +/* Preview color */ +#colorpicker .block { + width: 95px; + height: 54px; + float: left; + position: relative; +} + +#colorpicker .preview { + margin: 5px; + border: 1px solid #CCC; + background-image: url("alpha.png"); + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#colorpicker .preview:before { + height: 100%; + width: 50%; + left: 50%; + content: ""; + background: #FFF; + position: absolute; + z-index: 1; +} + +#colorpicker .preview > * { + width: 50%; + height: 100%; +} + +#colorpicker #output_color { + width: 100%; + height: 100%; + position: absolute; + z-index: 2; +} + +#colorpicker .block .input { + float: right; +} + +#colorpicker [data-topic="a"] > span { + width: 50px; +} + +#colorpicker [data-topic="hexa"] { + float: right; + margin: 10px 0 0 0; +} + +#colorpicker [data-topic="hexa"] > span { + display: none; +} + +#colorpicker [data-topic="hexa"] > input { + width: 85px; + padding: 2px 0; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +/* + * UI Components + */ + +/* Property */ + +.property { + height: 20px; + margin: 10px 0; +} + +.property * { + float: left; + height: 100%; + line-height: 100%; +} + +/* Slider */ + +#controls .ui-slider-name { + margin: 0 10px 0 0; +} + +/* + * Output code styling + */ + +#output { + position: relative; +} + +#output .menu { + max-width: 70%; + height: 20px; + position: absolute; + top: 2px; +} + +#output .button { + width: 90px; + height: 22px; + margin: 0 5px 0 0; + text-align: center; + line-height: 20px; + font-size: 14px; + color: #FFF; + background-color: #999; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + bottom: -5px; + float:left; +} + +#output .button:hover { + color: #FFF; + background-color: #666; + cursor: pointer; +} + +#output .menu [data-active="true"] { + color: #777; + background-color: #FFF; + border: 1px solid #CCC; + border-bottom: none; +} + +#output .menu [data-topic="before"] { + left: 100px; +} + +#output .menu [data-topic="after"] { + left: 200px; +} + +#output .output { + width: 480px; + margin: 10px; + padding: 10px; + overflow: hidden; + color: #555; + font-size: 14px; + border: 1px dashed #CCC; + border-radius: 3px; + display: none; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + -moz-user-select: text; + -webkit-user-select: text; + -ms-user-select: text; +} + +#output .css-property { + width: 100%; + float: left; + white-space: pre; +} + +#output .name { + width: 35%; + float: left; +} + +#output .value { + width: 65%; + float: left; +} diff --git a/tools/box-shadow-generator/up-black.png b/tools/box-shadow-generator/up-black.png new file mode 100644 index 0000000000000000000000000000000000000000..110826af6bec58b88b5abbde25390b3c0a385039 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9Ea{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaMM1AIbU-3xqxOdt@;=9~D%t978y+Cnq>C_wYG1 u< literal 0 HcmV?d00001 diff --git a/tools/box-shadow-generator/up-white.png b/tools/box-shadow-generator/up-white.png new file mode 100644 index 0000000000000000000000000000000000000000..74749e5c68bea4a040aab7973741571237deb092 GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@5Lt z8c`CQpH@W}Sq!2)3;ffV7`|WD^LWEt R9}6^x!PC{xWt~$(69Bk^H3|R# literal 0 HcmV?d00001 diff --git a/tools/color-picker/alpha.png b/tools/color-picker/alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..a28b929a4adde81339fca7295d680bfc3e6cd6ff GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F5M?jcysy3fAP*B>_ y#WAGfR< literal 0 HcmV?d00001 diff --git a/tools/color-picker/alpha_mask.png b/tools/color-picker/alpha_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8863bb615050eb500c0fcec570348453c71a52bc GIT binary patch literal 1152 zcmah}TWHfz7|s|@nVTpIZXz~BAF9}$=%=u4=~Y3hRTQS#s88TXJG@X4@%l z2;LqP@ok$o1O*WlLA)S3P!z<=oG60G2HvV{;KSw}oG05_eXtsmoD1Lg{g?A4`y1-l z78folBnYB7T*pW7co#p*<`m#};KZ z>oP!NSAA6KYL|R66{sRBlN=UM0TRii+M$_T(oaq4a(HfS(-b)cLG6BOI;oh@Kn9@! zNUzi5kX#HyvaFLS^Rg_nnsmDuH|@eV>tM<_FUz^h$(f77(G0nTi}1BGvGB@IwIZZ* zG@VE!oC%K;8gZKO`Fxg!+wH&zhndolm~?37@{9rxOvzAmq(F_d6vbxPiTo7Kbh-pp z&&q1%Oq+1S=%lFAjMHV6lmQCDzoDv{MVlxBe&_pFVKbW20UZG*>@*~Na4pNNP&yYh zfQXVZvNFg%<=ateHsEBoOBP6jpF5ip;U)EMLRA z-At$qcRl2(s43@bLqWc_%oFtbyul2Yhf=2sG?d}Wzqy{AT+0fojwAEHP__ZN)_^KG zRWhgK&c&5eZ-y)9&IOl{qYfG;Lt6*?$3bVduzRd&*0y+&H9pX=+YM~%lD+S(k76Rs z*F=*q#-4ASx63s@G}QKT!H*36J9TN(+*HY) z=jpe7r_a1I@1*N(#kRAbE{+eyY_qGDjY^40xMS?mmEnQQJG*aweH{3*`NzYZ2gcXF z{ zBEH9qdJm`9Uyz8Ci%z(DewGGLzxnoLw4}#A%U*P%`|hEYshbmA0l6-(F#r8=MqYP} g{vWk^_jMwl2;ExTX&!jxxBdy?P(6Qs&6Zui0I_G0uK)l5 literal 0 HcmV?d00001 diff --git a/tools/color-picker/arrow.png b/tools/color-picker/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..88d8479b120cd7d53f5ac22d98867c9ba3dd1292 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1OSkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?skg2l#}zx)=B?UAlDd-n}zt&Rnx*4UpWmYuDn%i-C-_Yu9evxN+ysoj~@i zS+jQU-o0+!Iv|^&_rW)yc7c*0zhH(bZoi9P`)&VKnBesJwM))9osxc_oS~<$wOpZnR#A8u`gtW%Y$H`9<93>7NaXlc$Q1+a0(sr4c QA3)6vp00i_>zopr0IrT!*Z=?k literal 0 HcmV?d00001 diff --git a/tools/color-picker/arrows.png b/tools/color-picker/arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..30d630fdaf96be7baa2d7da9de6cda337a5ab769 GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^3P3Et!3-oF?)7E^DVB6cUq=Rpjs4tz5?O(K#^NA% zCx&(BWL^R}2?0JKuI>ds_4V~NH8qbOJ*udvxOM9mko*7t|MvEFhhKoOt9UUD&Ms00v8)Hrk&@Q=>AirRS zE!#K+*|}KG9yrLmP57Xs2$RsoJ;%72xespTIeO{Vt&kF+$_`H##}JM4y%XKV4k&Q2 zn(h_9EPdzyG*2;>+e+*9ojcLoF0kMKPT{+x>GF@S1;5+=aYN;%$5StUB+Sy)5{JL;)i>KRNHR&Y@T5)2sH3(kgCJ?$yhWWd0DfuVJq(Mlep zW*@J2^$r?2CzSNN!;sC8u{m44r4QUcHc9=(X+s&r7zE%b))eIqb2r s!DDxhk!SVc$C+}kj*Av-3H;A$&GLn{KYH$pG@vyMp00i_>zopr0DE%P0ssI2 literal 0 HcmV?d00001 diff --git a/tools/color-picker/color-wheel.png b/tools/color-picker/color-wheel.png new file mode 100644 index 0000000000000000000000000000000000000000..49020d9ef3187ad6a4e9ffb92ae75f3de4dbb34b GIT binary patch literal 1985 zcmV;y2R`_TP)Px&08mU+MMrQ<7 ze}8oU|FwsPhlYoS#pg%=|FuyZEI1Zb?f7I_z@U1Le1D0B|NWxggM%6tMvIAxiHV6- zx0d@40=x+xdE-F;-FW~1u8N6?`ws{74hr822?qcV83rpW5JChkbrLjs{Yew{&}skp zsQ=%F|HoGxz+(KsDBhW|W#BQbb?*cAP6KfUlL zxZ^bc@O%IAbCu;HXU-jg(H#Htm;dgD_$_^DA6@o0kxRrIu1 z_5c6W@4(;F>`wpr?f>%a|NZp;|IhOKp8e+XFK?&*?e_op;QRiq|Ngx9&*=a1`1#%L z#OGZt#Lxfd=>OZ?N>!vUnyO|)o4Mdl|MJt-rO)j7a;4Zw{ri+RVATA?+T-+FDsI>y zd)fZR$p6{Ee9UGxq^D|2z5mU&iP)E0%DFItsXVWsN4S|@!-G=3jpMV}Ohv5q{DnnV z(i@1}8kO8pQOeu!PauN5AzGXrqS-8tsQ>E6;=JFm;$$YO$D!YJht+>X$Hi^UtpD!g z|Kr{MsHteiaynkIeL$9FOr|Gpw$<)%{-29AUc_8Z!;aBd|HHg|OSX_ovLw3I|L2iP zxUh51ka*Ld|Jcs|S&g=**;xGea5z7dcx9Vg4p522qtF&>mp%S~ga1TaUU;(lkHM95v6ipJx1!41&&JN= zsP?SV#ssI20SaecOQvewpC;|-!0RsjSHAVgm4B!3#VRt(cX4;?a z>qjK~CdApghB$q*#-`(IPo@0YF^=WXY~8Odn2vefPUf$CwDZaKTWyI+RBwL|xSRNWc`wbVX@z4VA9|5lRG(B7g3Dk#(D6GTE+6 zmt0E4RLEp_ygxf%c5`&DZ1&P6H&S__A<|E7WfevTuD;50crKe3^yZE0JgF4i3L;Uf zh+G|cZL%PnMqBjH;%%W)sYC*%U=5bYC@diZBO|X95PLA~-o@8zqosU_L=s(4P*|u| z7p{rK6J`DT+8b^YkQTIPM(sg?l+VXt;hu(uMzwl1o=EH9;5ANz_HhwzFo)C$8Q zA_N57MnI7$Jw4rern)L6xt4p5XnpwVc~^n$C1n@4_(_tON75C}*J zPNV7T8Z7RqN~y?-bEo5w>AgQesKh0|U;D1=H3DHJkU{~wosJ%7Hvy#!naI1*A&N)UH{ zLW@G7XpzbG?(Oftc=`M9zTNjz)2EP~yL38ThCA6At`Bg{2{KHzo;+E0@lYBDk2W>o z&Y;sBm`DB=ln3=|&1Q3JYgt)L%=Rx2rR9$|?>j1&%XgM`8w`eB2j))vk_*M$wUDx7 zG4X9}!}fZQy5?pRz|wA`(FkzP1f+4qdM;NFPOGg<8r$U2ksNC>$xE|OWo8-;Igd{E z!xJ2fUT-{>FE*8v>u?SS%JXz{;c@n+TYD;>6ai zTQZF~4?DCC@|cz*wur^?ZMR@-tj+c{z*2{T*cf@{G)F9kZyqM##^h03O%1^8ocXu+ zcHncT<2l&k*v9~Nbc`NWsQ_l@+{5_Sw0P**<*`IO>$~6Zp!x z%3)aTwB7mR8}jnheval``%&ly|e7SvHIOO9Is1W z{x0>7Gm=jA{OIGmv3&T!`)*S&(@_?S!SJCvIXO8yyLfted3m}x!wHqjV6a$pIzlIh z4=^g#2_t@f!NGT73HI{?4IHyDWD%kwosN|R3>BSSAh06};uWW#=;XcFhB%0uW@ppf Tyvl&M00000NkvXXu0mjf?++qu literal 0 HcmV?d00001 diff --git a/tools/color-picker/copy.png b/tools/color-picker/copy.png new file mode 100644 index 0000000000000000000000000000000000000000..1ffaad0830385700f650109fa2c25e2ad4b148a6 GIT binary patch literal 2215 zcmaJ@X;c$w7R|whMMa4W$kI76h=@Rv3J{VQz(5E>8`Ka4br32^1tKIBlEM^VkGQY| z5dfdFmo z@?T_PZGyw$76q*13b2ufeanpIV}JkB19Py!3h@g=f?+A50aXx=BY{N_F+dJRK>`Sr zB*ZmAY#eS5NhS<8LJT!YYX9PIh$>QvrZTr;`CUcRC$#Ceo+?jY7pi}C z35%wZNLd0d?^`TveMNt4IlR2e9qq$%R7j=RH0Z|u)+HP8b z3#r8_nG%t~3gVO^D1ze=PZE~tA0^0@GqMWxw`0N%jDmtn3P7e#l{5|H^Z!3oE}ucG z5drj{eE+AgT9}}OC;~_g$E(Cx6=EoW>q){C$TFFP#q^-kd|bIaz|YMO0Q_7T42F*nmErE; zPIY&q`ua|Dxv)514k?gnu4IPmN1c^BWd*qsi_C>ovYn8Gr-J3guO+i&v**H{Rqq>D zGHWhezgf8yEE&pFWB;qs(_5H(rlvEt#TGNhhZLCGRhX^cC$F-=;pW){a5+M>`{%HT z_1hqG@8POpUB};*=C@YFtaO|-&uh%F-?pD=Ux)L0y({v)))}am^wd4Ad${jC=(Q}u z;@Mqdee~14*6kx#^&_|@qOkL~)w`Xuas}JEX-Pf3Ni~T#kLz$wH?Do^JzVg-_xqZj zh}{K`Mhp9&sVZ&rOt$E>r&hJtHgc@WntPoB@B{3{n;UqlrKNrj0gkFID0%nb`%>PO zAKF&-Rv7kPe`OkOmzN0Aj-D?(apDA5)Ef5!7)%zh=nTdgx|>^a%BBO}s*m3G@ma4% z$_FB|z*4DY-inolLD%f@TJTrnb2uL({qrbuZRNh0FJ-y;D69SI2{aQ;&+;c4EJBqSLZieHQ`HfZca$(jg*d}~WnU<}u6G&VMNAu}@*-Dp7w3Gp1MIOG6$ zEZ$O@aVpx~BY9$;*W0AY<`|b7C%Q|;goA>+=yo{iPtG~`1^3uTbh-Wpey}w(^mjBoJiJ^WvaO!;SKVJK65k#@{OUlhOR8a? z*S@ZMnMXW6hFnQywsybH(Q=GA#3jpa1%kO9TAGTM>5RYoe0cmK@TRP^jx^g zM03q<2x!+T}0xKb>kn(`e%8c+6l`aT?#<;offJ*0sXkd*fMFY;t?av$GcG zh)cph2v^t-JyJ4kjZfdTlF~%O^Xm(mkMwr>6d6*79h?^*Rc@VqHsizSE{_EV+qeyvc$U`=EGt04hr?a`y_X$ZHrWZX zG8={2Z{EGD?%!Eu3EXFkI+MpgUcY*_QSzjvwRT+oUf0mna50Wx45XFWW-kZs9J9;0 zEh|Voe)&NxaPH+`Va<}Z?l*z4(os7+<(+_Sx?)aU#I633b~Io56%jfPQIQ+J<=DV}O*ZNBx(+ zG&F3hh<&>M`N9nm=WE3X;qo4vU!sf5<6po%`GqLOTYI>DbgcBUXcQo7F2n1x%(*d_X=r_n7P|8^MLk zf_+2FZL=dg(Vm{3S08fiohcMwHlZe^Eom?U4aPyK*8B5dHRb}Pn z24{tV^%+*J9?al9Twe9|{=5|df%e>y$%zFzaZIwHV{xs9pD_SEX+L98`S^!~(oH)U e=53P(3vt~JOJf@QCyq~D9RmDC8rI^tG literal 0 HcmV?d00001 diff --git a/tools/color-picker/drop.png b/tools/color-picker/drop.png new file mode 100644 index 0000000000000000000000000000000000000000..22136172c75523c6d8b974ea1d3f0f16a6a23861 GIT binary patch literal 226 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 u>|8zzz?VBuKM6s!_GYQm1#&MZhTHoE|uM8idO zq0Sx;6(HdPBwUhwRE*SwW*^bpbn~d%?g=>{F(tuHFyZ2+WGE!rdCu-_{GR9bb98!C zH|m5Pn-w81o$Q^{ANw)zO}GD}0GZD9kAGXpsXq#t)5~3Gx$bCuq4m3?hbx56KT6%x zx4lyT|0(TC#ro69l?vrgr`?&by2$g~Y000?b(7~mk^bpqH@UgU;oB*>o0_*%Hs?$z z-4qpef_+njn1|TOph&&dDQjyqW~Z!vGvV&1jc=y=KiwcRHTl!xKU(Tfx6GN`UF5p% zwC_&k?@uS%Onv^Tf6v77D);;s@>PERF9q)|w=S8y?y~4EkLNE;<}QhU!EWW|{?ee< z>-Wp#TfWvA+PRDPGj-Q4db(wb*hU4h&buo z{D`1dZo{$%T2YiCO8E^M8pAe_?VGlA2{QSAiF%)!8U d@?YUUqeNvw_<^(EBY + + + + + Color picker + + + + + +
+
+
+
+
CSS Color
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+ + + + + diff --git a/tools/color-picker/lock.png b/tools/color-picker/lock.png new file mode 100644 index 0000000000000000000000000000000000000000..9a5a5043aa1ef584709c12316e3e65b44ef23cb4 GIT binary patch literal 1979 zcmaJ?dstKDAK$nX5*UI*G_b?Gp|LAtuwzrk27)p!17T$#hwZQ($Jtrifn6jccrZ$M zxTYe7xiYMtfN>32!LojUQbIwb`~s{5N>s%A5A_=j-XkRW*5nu4(c`dQ6#v`P7B9@8kAuUW2$gvC<;3_`# z&!D8@ctD70VIY_uM3XUDEP%_UvpB(AE-MgVGg)i~lX$r_76%OGg6t6B@k1rNY2}%q zL=^eh7h&r|X00m{!4H@pwGD2AfSI5Hy`pjY9^STDNXdK?Lh$T10~* zm>RGvLK#>#&ZiQQ{+R-*c_ORUJuVYbFoprrFj#b^J*7pUSp4r$6n%o$;S%_-c>hsY zmt@qy3<<2mvb8dzahdDvt~8)f3qv@jO~SCO#VW=tF&xt=F%2M0D{AaYR12#E ze{1yO6)`>b<&P`EK-znoe18%ioiw=`^X+f1P|4O7eh3;UBi$oQ|iZ z9+^_4$LEiB?0A-3`uXM2mI+dEql4AuC*fAgio%>5o$e+Z`Re_`$YXc%CT4S2srLE^ zH-ZfbM{et;SC>rl!qPtTdCE;VJwkamYW?u_(#~&FdO~_u^)yA!|H1h^i@OU1!I&3j zuUu*Uy5{VqD3$8dxyBYR&C0pFF8$Gx!ja_n{`2(R4btYe>pyzUlC2J}cs!gj_V9X& z`*Yjoe^i|o^st_}QknxiaGpPZX6)1tXGV=}10@BfWY34nF+)VkE{s(7lhfpv1&933 zTFv>_nz&70e>d&xnN>ZCo_Oz6+jAb8s75#~!B+ZGZ`jlK*VkMMg$^4doEes@$76F9 zep#pOR=2Y+bhS-f;&bdMUd<{?N)m=Uq0*-0N8fWxIyo{)URER3D`N&)9<`r{gX@erwmJT{o%r zD!6T&&`_xkL(vk^2MOYFi^W1I?MO$-_T&U1s3 z)~0Q&9#v)`o7yYxeOR7Zv8ODAoCCO5&sZb3e&)I3-D#E3&yt*y^4cHy>wVlZI&k55 z_=)(7x9;WA18pMJke_SemXLMjeI8@jmbjRh!1GMbZiC|+ulwbM`qt0I#>Fw9Wy>|{ zWdD!I&DneR?K4Lls5w^_TNka@x9=`LX1!;XoIlXreK4f5zietM^F}^$v+U8bM00mv zz=}?IDkJ!0RAFgpsh9haAk-o){!p@6Xid61JY2OoZD0m!eJ~W(>NO-xv?_;$C&PU{ zoj+H#Zb;Z{H?KCVxpjEKV4IYK@|%PHHnwS|Dt$E{?~~v3K)o8?=%4X76Ki8b@!FlX dnt?~IOj5;-`j9SNTe1Cj8XXZUst-@k|33hXAISg! literal 0 HcmV?d00001 diff --git a/tools/color-picker/pick.png b/tools/color-picker/pick.png new file mode 100644 index 0000000000000000000000000000000000000000..c928de26a83befe4c34fc7cd7cfb9ff87da595ee GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k&H|6fVg?31We{epSZZGe6qGD+ zjVKAuPb(=;EJ|f?Ovz75Rq)JBOiv9;O-!jQJeg_(RJ7L9#WAGfR`QSk|LvK@_V9Lu zCr)-2-@y9lro$hhj`@x^)pnRXVg4Aa@Q(3Of&yRTrhJA%nO$trE0QK;hB??UcPw|h zIWIsucY<>8Kkz*j6*Ya#UVnEVbZ`ghCw$cifW%R@S@P3UNH8#X?hfgWfo6Jc<(( dE_6}lWoU7K(GV-VBoOFu22WQ%mvv4FO#r5?UHkw5 literal 0 HcmV?d00001 diff --git a/tools/color-picker/picker.png b/tools/color-picker/picker.png new file mode 100644 index 0000000000000000000000000000000000000000..0ab3a5f598977664df985dacec932c3162ffc917 GIT binary patch literal 1659 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 literal 0 HcmV?d00001 diff --git a/tools/color-picker/resize.png b/tools/color-picker/resize.png new file mode 100644 index 0000000000000000000000000000000000000000..b46653175e10bae147cb7978da3cdb9a3dd14db9 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^93afX3?$7I7w-U4Ea{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaOi1AIbU-3xsF|Np;g)vEL7&p&_ue4@?nJ0Nu>L4Lsu4$p3+0XYhuE{-7_ z*OL= 0 && value <= 255); + }; + + Color.prototype.setRGBA = function setRGBA(red, green, blue, alpha) { + if (this.isValidRGBValue(red) === false || + this.isValidRGBValue(green) === false || + this.isValidRGBValue(blue) === false) + return; + + this.r = red | 0; + this.g = green | 0; + this.b = blue | 0; + + if (this.isValidRGBValue(alpha) === true) + this.a = alpha | 0; + }; + + Color.prototype.setByName = function setByName(name, value) { + if (name === 'r' || name === 'g' || name === 'b') { + if(this.isValidRGBValue(value) === false) + return; + + this[name] = value; + this.updateHSX(); + } + }; + + Color.prototype.setHSV = function setHSV(hue, saturation, value) { + this.hue = hue; + this.saturation = saturation; + this.value = value; + this.HSVtoRGB(); + }; + + Color.prototype.setHSL = function setHSL(hue, saturation, lightness) { + this.hue = hue; + this.saturation = saturation; + this.lightness = lightness; + this.HSLtoRGB(); + }; + + Color.prototype.setHue = function setHue(value) { + if (typeof(value) !== 'number' || isNaN(value) === true || + value < 0 || value > 359) + return; + this.hue = value; + this.updateRGB(); + }; + + Color.prototype.setSaturation = function setSaturation(value) { + if (typeof(value) !== 'number' || isNaN(value) === true || + value < 0 || value > 100) + return; + this.saturation = value; + this.updateRGB(); + }; + + Color.prototype.setValue = function setValue(value) { + if (typeof(value) !== 'number' || isNaN(value) === true || + value < 0 || value > 100) + return; + this.value = value; + this.HSVtoRGB(); + }; + + Color.prototype.setLightness = function setLightness(value) { + if (typeof(value) !== 'number' || isNaN(value) === true || + value < 0 || value > 100) + return; + this.lightness = value; + this.HSLtoRGB(); + }; + + Color.prototype.setHexa = function setHexa(value) { + var valid = /(^#{0,1}[0-9A-F]{6}$)|(^#{0,1}[0-9A-F]{3}$)/i.test(value); + + if (valid !== true) + return; + + if (value[0] === '#') + value = value.slice(1, value.length); + + if (value.length === 3) + value = value.replace(/([0-9A-F])([0-9A-F])([0-9A-F])/i,'$1$1$2$2$3$3'); + + this.r = parseInt(value.substr(0, 2), 16); + this.g = parseInt(value.substr(2, 2), 16); + this.b = parseInt(value.substr(4, 2), 16); + + this.alpha = 1; + this.RGBtoHSV(); + }; + + /*========== Conversion Methods ==========*/ + + Color.prototype.convertToHSL = function convertToHSL() { + if (this.format === 'HSL') + return; + + this.setFormat('HSL'); + this.RGBtoHSL(); + }; + + Color.prototype.convertToHSV = function convertToHSV() { + if (this.format === 'HSV') + return; + + this.setFormat('HSV'); + this.RGBtoHSV(); + }; + + /*========== Update Methods ==========*/ + + Color.prototype.updateRGB = function updateRGB() { + if (this.format === 'HSV') { + this.HSVtoRGB(); + return; + } + + if (this.format === 'HSL') { + this.HSLtoRGB(); + return; + } + }; + + Color.prototype.updateHSX = function updateHSX() { + if (this.format === 'HSV') { + this.RGBtoHSV(); + return; + } + + if (this.format === 'HSL') { + this.RGBtoHSL(); + return; + } + }; + + Color.prototype.HSVtoRGB = function HSVtoRGB() { + var sat = this.saturation / 100; + var value = this.value / 100; + var C = sat * value; + var H = this.hue / 60; + var X = C * (1 - Math.abs(H % 2 - 1)); + var m = value - C; + var precision = 255; + + C = (C + m) * precision | 0; + X = (X + m) * precision | 0; + m = m * precision | 0; + + if (H >= 0 && H < 1) { this.setRGBA(C, X, m); return; } + if (H >= 1 && H < 2) { this.setRGBA(X, C, m); return; } + if (H >= 2 && H < 3) { this.setRGBA(m, C, X); return; } + if (H >= 3 && H < 4) { this.setRGBA(m, X, C); return; } + if (H >= 4 && H < 5) { this.setRGBA(X, m, C); return; } + if (H >= 5 && H < 6) { this.setRGBA(C, m, X); return; } + }; + + Color.prototype.HSLtoRGB = function HSLtoRGB() { + var sat = this.saturation / 100; + var light = this.lightness / 100; + var C = sat * (1 - Math.abs(2 * light - 1)); + var H = this.hue / 60; + var X = C * (1 - Math.abs(H % 2 - 1)); + var m = light - C/2; + var precision = 255; + + C = (C + m) * precision | 0; + X = (X + m) * precision | 0; + m = m * precision | 0; + + if (H >= 0 && H < 1) { this.setRGBA(C, X, m); return; } + if (H >= 1 && H < 2) { this.setRGBA(X, C, m); return; } + if (H >= 2 && H < 3) { this.setRGBA(m, C, X); return; } + if (H >= 3 && H < 4) { this.setRGBA(m, X, C); return; } + if (H >= 4 && H < 5) { this.setRGBA(X, m, C); return; } + if (H >= 5 && H < 6) { this.setRGBA(C, m, X); return; } + }; + + Color.prototype.RGBtoHSV = function RGBtoHSV() { + var red = this.r / 255; + var green = this.g / 255; + var blue = this.b / 255; + + var cmax = Math.max(red, green, blue); + var cmin = Math.min(red, green, blue); + var delta = cmax - cmin; + var hue = 0; + var saturation = 0; + + if (delta) { + if (cmax === red ) { hue = ((green - blue) / delta); } + if (cmax === green ) { hue = 2 + (blue - red) / delta; } + if (cmax === blue ) { hue = 4 + (red - green) / delta; } + if (cmax) saturation = delta / cmax; + } + + this.hue = 60 * hue | 0; + if (this.hue < 0) this.hue += 360; + this.saturation = (saturation * 100) | 0; + this.value = (cmax * 100) | 0; + }; + + Color.prototype.RGBtoHSL = function RGBtoHSL() { + var red = this.r / 255; + var green = this.g / 255; + var blue = this.b / 255; + + var cmax = Math.max(red, green, blue); + var cmin = Math.min(red, green, blue); + var delta = cmax - cmin; + var hue = 0; + var saturation = 0; + var lightness = (cmax + cmin) / 2; + var X = (1 - Math.abs(2 * lightness - 1)); + + if (delta) { + if (cmax === red ) { hue = ((green - blue) / delta); } + if (cmax === green ) { hue = 2 + (blue - red) / delta; } + if (cmax === blue ) { hue = 4 + (red - green) / delta; } + if (cmax) saturation = delta / X; + } + + this.hue = 60 * hue | 0; + if (this.hue < 0) this.hue += 360; + this.saturation = (saturation * 100) | 0; + this.lightness = (lightness * 100) | 0; + }; + + /*========== Get Methods ==========*/ + + Color.prototype.getHexa = function getHexa() { + var r = this.r.toString(16); + var g = this.g.toString(16); + var b = this.b.toString(16); + if (this.r < 16) r = '0' + r; + if (this.g < 16) g = '0' + g; + if (this.b < 16) b = '0' + b; + var value = '#' + r + g + b; + return value.toUpperCase(); + }; + + Color.prototype.getRGBA = function getRGBA() { + + var rgb = '(' + this.r + ', ' + this.g + ', ' + this.b; + var a = ''; + var v = ''; + var x = parseFloat(this.a); + if (x !== 1) { + a = 'a'; + v = ', ' + x; + } + + var value = 'rgb' + a + rgb + v + ')'; + return value; + }; + + Color.prototype.getHSLA = function getHSLA() { + if (this.format === 'HSV') { + var color = new Color(this); + color.setFormat('HSL'); + color.updateHSX(); + return color.getHSLA(); + } + + var a = ''; + var v = ''; + var hsl = '(' + this.hue + ', ' + this.saturation + '%, ' + this.lightness +'%'; + var x = parseFloat(this.a); + if (x !== 1) { + a = 'a'; + v = ', ' + x; + } + + var value = 'hsl' + a + hsl + v + ')'; + return value; + }; + + Color.prototype.getColor = function getColor() { + if (this.a | 0 === 1) + return this.getHexa(); + return this.getRGBA(); + }; + + /*=======================================================================*/ + /*=======================================================================*/ + + /*========== Capture Mouse Movement ==========*/ + + var setMouseTracking = function setMouseTracking(elem, callback) { + elem.addEventListener('mousedown', function(e) { + callback(e); + document.addEventListener('mousemove', callback); + }); + + document.addEventListener('mouseup', function(e) { + document.removeEventListener('mousemove', callback); + }); + }; + + /*====================*/ + // Color Picker Class + /*====================*/ + + function ColorPicker(node) { + this.color = new Color(); + this.node = node; + this.subscribers = []; + + var type = this.node.getAttribute('data-mode'); + var topic = this.node.getAttribute('data-topic'); + + this.topic = topic; + this.picker_mode = (type === 'HSL') ? 'HSL' : 'HSV'; + this.color.setFormat(this.picker_mode); + + this.createPickingArea(); + this.createHueArea(); + + this.newInputComponent('H', 'hue', this.inputChangeHue.bind(this)); + this.newInputComponent('S', 'saturation', this.inputChangeSaturation.bind(this)); + this.newInputComponent('V', 'value', this.inputChangeValue.bind(this)); + this.newInputComponent('L', 'lightness', this.inputChangeLightness.bind(this)); + + this.createAlphaArea(); + + this.newInputComponent('R', 'red', this.inputChangeRed.bind(this)); + this.newInputComponent('G', 'green', this.inputChangeGreen.bind(this)); + this.newInputComponent('B', 'blue', this.inputChangeBlue.bind(this)); + + this.createPreviewBox(); + this.createChangeModeButton(); + + this.newInputComponent('alpha', 'alpha', this.inputChangeAlpha.bind(this)); + this.newInputComponent('hexa', 'hexa', this.inputChangeHexa.bind(this)); + + this.setColor(this.color); + pickers[topic] = this; + } + + /*************************************************************************/ + // Function for generating the color-picker + /*************************************************************************/ + + ColorPicker.prototype.createPickingArea = function createPickingArea() { + var area = document.createElement('div'); + var picker = document.createElement('div'); + + area.className = 'picking-area'; + picker.className = 'picker'; + + this.picking_area = area; + this.color_picker = picker; + setMouseTracking(area, this.updateColor.bind(this)); + + area.appendChild(picker); + this.node.appendChild(area); + }; + + ColorPicker.prototype.createHueArea = function createHueArea() { + var area = document.createElement('div'); + var picker = document.createElement('div'); + + area.className = 'hue'; + picker.className ='slider-picker'; + + this.hue_area = area; + this.hue_picker = picker; + setMouseTracking(area, this.updateHueSlider.bind(this)); + + area.appendChild(picker); + this.node.appendChild(area); + }; + + ColorPicker.prototype.createAlphaArea = function createAlphaArea() { + var area = document.createElement('div'); + var mask = document.createElement('div'); + var picker = document.createElement('div'); + + area.className = 'alpha'; + mask.className = 'alpha-mask'; + picker.className = 'slider-picker'; + + this.alpha_area = area; + this.alpha_mask = mask; + this.alpha_picker = picker; + setMouseTracking(area, this.updateAlphaSlider.bind(this)); + + area.appendChild(mask); + mask.appendChild(picker); + this.node.appendChild(area); + }; + + ColorPicker.prototype.createPreviewBox = function createPreviewBox(e) { + var preview_box = document.createElement('div'); + var preview_color = document.createElement('div'); + + preview_box.className = 'preview'; + preview_color.className = 'preview-color'; + + this.preview_color = preview_color; + + preview_box.appendChild(preview_color); + this.node.appendChild(preview_box); + }; + + ColorPicker.prototype.newInputComponent = function newInputComponent(title, topic, onChangeFunc) { + var wrapper = document.createElement('div'); + var input = document.createElement('input'); + var info = document.createElement('span'); + + wrapper.className = 'input'; + wrapper.setAttribute('data-topic', topic); + info.textContent = title; + info.className = 'name'; + input.setAttribute('type', 'text'); + + wrapper.appendChild(info); + wrapper.appendChild(input); + this.node.appendChild(wrapper); + + input.addEventListener('change', onChangeFunc); + input.addEventListener('click', function() { + this.select(); + }); + + this.subscribe(topic, function(value) { + input.value = value; + }); + }; + + ColorPicker.prototype.createChangeModeButton = function createChangeModeButton() { + + var button = document.createElement('div'); + button.className = 'switch_mode'; + button.addEventListener('click', function() { + if (this.picker_mode === 'HSV') + this.setPickerMode('HSL'); + else + this.setPickerMode('HSV'); + + }.bind(this)); + + this.node.appendChild(button); + }; + + /*************************************************************************/ + // Updates properties of UI elements + /*************************************************************************/ + + ColorPicker.prototype.updateColor = function updateColor(e) { + var x = e.pageX - this.picking_area.offsetLeft; + var y = e.pageY - this.picking_area.offsetTop; + var picker_offset = 5; + + // width and height should be the same + var size = this.picking_area.clientWidth; + + if (x > size) x = size; + if (y > size) y = size; + if (x < 0) x = 0; + if (y < 0) y = 0; + + var value = 100 - (y * 100 / size) | 0; + var saturation = x * 100 / size | 0; + + if (this.picker_mode === 'HSV') + this.color.setHSV(this.color.hue, saturation, value); + if (this.picker_mode === 'HSL') + this.color.setHSL(this.color.hue, saturation, value); + + this.color_picker.style.left = x - picker_offset + 'px'; + this.color_picker.style.top = y - picker_offset + 'px'; + + this.updateAlphaGradient(); + this.updatePreviewColor(); + + this.notify('value', value); + this.notify('lightness', value); + this.notify('saturation', saturation); + + this.notify('red', this.color.r); + this.notify('green', this.color.g); + this.notify('blue', this.color.b); + this.notify('hexa', this.color.getHexa()); + + notify(this.topic, this.color); + }; + + ColorPicker.prototype.updateHueSlider = function updateHueSlider(e) { + var x = e.pageX - this.hue_area.offsetLeft; + var width = this.hue_area.clientWidth; + + if (x < 0) x = 0; + if (x > width) x = width; + + // TODO 360 => 359 + var hue = ((359 * x) / width) | 0; + // if (hue === 360) hue = 359; + + this.updateSliderPosition(this.hue_picker, x); + this.setHue(hue); + }; + + ColorPicker.prototype.updateAlphaSlider = function updateAlphaSlider(e) { + var x = e.pageX - this.alpha_area.offsetLeft; + var width = this.alpha_area.clientWidth; + + if (x < 0) x = 0; + if (x > width) x = width; + + this.color.a = (x / width).toFixed(2); + + this.updateSliderPosition(this.alpha_picker, x); + this.updatePreviewColor(); + + this.notify('alpha', this.color.a); + notify(this.topic, this.color); + }; + + ColorPicker.prototype.setHue = function setHue(value) { + this.color.setHue(value); + + this.updatePickerBackground(); + this.updateAlphaGradient(); + this.updatePreviewColor(); + + this.notify('red', this.color.r); + this.notify('green', this.color.g); + this.notify('blue', this.color.b); + this.notify('hexa', this.color.getHexa()); + this.notify('hue', this.color.hue); + + notify(this.topic, this.color); + }; + + // Updates when one of Saturation/Value/Lightness changes + ColorPicker.prototype.updateSLV = function updateSLV() { + this.updatePickerPosition(); + this.updateAlphaGradient(); + this.updatePreviewColor(); + + this.notify('red', this.color.r); + this.notify('green', this.color.g); + this.notify('blue', this.color.b); + this.notify('hexa', this.color.getHexa()); + + notify(this.topic, this.color); + }; + + /*************************************************************************/ + // Update positions of various UI elements + /*************************************************************************/ + + ColorPicker.prototype.updatePickerPosition = function updatePickerPosition() { + var size = this.picking_area.clientWidth; + var value = 0; + var offset = 5; + + if (this.picker_mode === 'HSV') + value = this.color.value; + if (this.picker_mode === 'HSL') + value = this.color.lightness; + + var x = (this.color.saturation * size / 100) | 0; + var y = size - (value * size / 100) | 0; + + this.color_picker.style.left = x - offset + 'px'; + this.color_picker.style.top = y - offset + 'px'; + }; + + ColorPicker.prototype.updateSliderPosition = function updateSliderPosition(elem, pos) { + elem.style.left = Math.max(pos - 3, -2) + 'px'; + }; + + ColorPicker.prototype.updateHuePicker = function updateHuePicker() { + var size = this.hue_area.clientWidth; + var offset = 1; + var pos = (this.color.hue * size / 360 ) | 0; + this.hue_picker.style.left = pos - offset + 'px'; + }; + + ColorPicker.prototype.updateAlphaPicker = function updateAlphaPicker() { + var size = this.alpha_area.clientWidth; + var offset = 1; + var pos = (this.color.a * size) | 0; + this.alpha_picker.style.left = pos - offset + 'px'; + }; + + /*************************************************************************/ + // Update background colors + /*************************************************************************/ + + ColorPicker.prototype.updatePickerBackground = function updatePickerBackground() { + var nc = new Color(this.color); + nc.setHSV(nc.hue, 100, 100); + this.picking_area.style.backgroundColor = nc.getHexa(); + }; + + ColorPicker.prototype.updateAlphaGradient = function updateAlphaGradient() { + this.alpha_mask.style.backgroundColor = this.color.getHexa(); + }; + + ColorPicker.prototype.updatePreviewColor = function updatePreviewColor() { + this.preview_color.style.backgroundColor = this.color.getColor(); + }; + + /*************************************************************************/ + // Update input elements + /*************************************************************************/ + + ColorPicker.prototype.inputChangeHue = function inputChangeHue(e) { + var value = parseInt(e.target.value); + this.setHue(value); + this.updateHuePicker(); + }; + + ColorPicker.prototype.inputChangeSaturation = function inputChangeSaturation(e) { + var value = parseInt(e.target.value); + this.color.setSaturation(value); + e.target.value = this.color.saturation; + this.updateSLV(); + }; + + ColorPicker.prototype.inputChangeValue = function inputChangeValue(e) { + var value = parseInt(e.target.value); + this.color.setValue(value); + e.target.value = this.color.value; + this.updateSLV(); + }; + + ColorPicker.prototype.inputChangeLightness = function inputChangeLightness(e) { + var value = parseInt(e.target.value); + this.color.setLightness(value); + e.target.value = this.color.lightness; + this.updateSLV(); + }; + + ColorPicker.prototype.inputChangeRed = function inputChangeRed(e) { + var value = parseInt(e.target.value); + this.color.setByName('r', value); + e.target.value = this.color.r; + this.setColor(this.color); + }; + + ColorPicker.prototype.inputChangeGreen = function inputChangeGreen(e) { + var value = parseInt(e.target.value); + this.color.setByName('g', value); + e.target.value = this.color.g; + this.setColor(this.color); + }; + + ColorPicker.prototype.inputChangeBlue = function inputChangeBlue(e) { + var value = parseInt(e.target.value); + this.color.setByName('b', value); + e.target.value = this.color.b; + this.setColor(this.color); + }; + + ColorPicker.prototype.inputChangeAlpha = function inputChangeAlpha(e) { + var value = parseFloat(e.target.value); + + if (typeof value === 'number' && isNaN(value) === false && + value >= 0 && value <= 1) + this.color.a = value.toFixed(2); + + e.target.value = this.color.a; + this.updateAlphaPicker(); + }; + + ColorPicker.prototype.inputChangeHexa = function inputChangeHexa(e) { + var value = e.target.value; + this.color.setHexa(value); + this.setColor(this.color); + }; + + /*************************************************************************/ + // Internal Pub/Sub + /*************************************************************************/ + + ColorPicker.prototype.subscribe = function subscribe(topic, callback) { + this.subscribers[topic] = callback; + }; + + ColorPicker.prototype.notify = function notify(topic, value) { + if (this.subscribers[topic]) + this.subscribers[topic](value); + }; + + /*************************************************************************/ + // Set Picker Properties + /*************************************************************************/ + + ColorPicker.prototype.setColor = function setColor(color) { + if(color instanceof Color !== true) { + console.log('Typeof parameter not Color'); + return; + } + + if (color.format !== this.picker_mode) { + color.setFormat(this.picker_mode); + color.updateHSX(); + } + + this.color.copy(color); + this.updateHuePicker(); + this.updatePickerPosition(); + this.updatePickerBackground(); + this.updateAlphaPicker(); + this.updateAlphaGradient(); + this.updatePreviewColor(); + + this.notify('red', this.color.r); + this.notify('green', this.color.g); + this.notify('blue', this.color.b); + + this.notify('hue', this.color.hue); + this.notify('saturation', this.color.saturation); + this.notify('value', this.color.value); + this.notify('lightness', this.color.lightness); + + this.notify('alpha', this.color.a); + this.notify('hexa', this.color.getHexa()); + notify(this.topic, this.color); + }; + + ColorPicker.prototype.setPickerMode = function setPickerMode(mode) { + if (mode !== 'HSV' && mode !== 'HSL') + return; + + this.picker_mode = mode; + this.node.setAttribute('data-mode', this.picker_mode); + this.setColor(this.color); + }; + + /*************************************************************************/ + // UNUSED + /*************************************************************************/ + + var setPickerMode = function setPickerMode(topic, mode) { + if (pickers[topic]) + pickers[topic].setPickerMode(mode); + }; + + var setColor = function setColor(topic, color) { + if (pickers[topic]) + pickers[topic].setColor(color); + }; + + var getColor = function getColor(topic) { + if (pickers[topic]) + return new Color(pickers[topic].color); + }; + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + + subscribers[topic].push(callback); + }; + + var unsubscribe = function unsubscribe(callback) { + subscribers.indexOf(callback); + subscribers.splice(index, 1); + }; + + var notify = function notify(topic, value) { + if (subscribers[topic] === undefined || subscribers[topic].length === 0) + return; + + var color = new Color(value); + for (var i in subscribers[topic]) + subscribers[topic][i](color); + }; + + var init = function init() { + var elem = document.querySelectorAll('.ui-color-picker'); + var size = elem.length; + for (var i = 0; i < size; i++) + new ColorPicker(elem[i]); + }; + + return { + init : init, + Color : Color, + RGBColor : RGBColor, + RGBAColor : RGBAColor, + HSVColor : HSVColor, + HSVAColor : HSVAColor, + HSLColor : HSLColor, + HSLAColor : HSLAColor, + setColor : setColor, + getColor : getColor, + subscribe : subscribe, + unsubscribe : unsubscribe, + setPickerMode : setPickerMode + }; + +})(); + +/** + * UI-SlidersManager + */ + +var InputSliderManager = (function InputSliderManager() { + + var subscribers = {}; + var sliders = []; + + var InputComponent = function InputComponent(obj) { + var input = document.createElement('input'); + input.setAttribute('type', 'text'); + input.style.width = 50 + obj.precision * 10 + 'px'; + + input.addEventListener('click', function(e) { + this.select(); + }); + + input.addEventListener('change', function(e) { + var value = parseFloat(e.target.value); + + if (isNaN(value) === true) + setValue(obj.topic, obj.value); + else + setValue(obj.topic, value); + }); + + return input; + }; + + var SliderComponent = function SliderComponent(obj, sign) { + var slider = document.createElement('div'); + var startX = null; + var start_value = 0; + + slider.addEventListener("click", function(e) { + document.removeEventListener("mousemove", sliderMotion); + setValue(obj.topic, obj.value + obj.step * sign); + }); + + slider.addEventListener("mousedown", function(e) { + startX = e.clientX; + start_value = obj.value; + document.body.style.cursor = "e-resize"; + + document.addEventListener("mouseup", slideEnd); + document.addEventListener("mousemove", sliderMotion); + }); + + var slideEnd = function slideEnd(e) { + document.removeEventListener("mousemove", sliderMotion); + document.body.style.cursor = "auto"; + slider.style.cursor = "pointer"; + }; + + var sliderMotion = function sliderMotion(e) { + slider.style.cursor = "e-resize"; + var delta = (e.clientX - startX) / obj.sensitivity | 0; + var value = delta * obj.step + start_value; + setValue(obj.topic, value); + }; + + return slider; + }; + + var InputSlider = function(node) { + var min = parseFloat(node.getAttribute('data-min')); + var max = parseFloat(node.getAttribute('data-max')); + var step = parseFloat(node.getAttribute('data-step')); + var value = parseFloat(node.getAttribute('data-value')); + var topic = node.getAttribute('data-topic'); + var unit = node.getAttribute('data-unit'); + var name = node.getAttribute('data-info'); + var sensitivity = node.getAttribute('data-sensitivity') | 0; + var precision = node.getAttribute('data-precision') | 0; + + this.min = isNaN(min) ? 0 : min; + this.max = isNaN(max) ? 100 : max; + this.precision = precision >= 0 ? precision : 0; + this.step = step < 0 || isNaN(step) ? 1 : step.toFixed(precision); + this.topic = topic; + this.node = node; + this.unit = unit === null ? '' : unit; + this.sensitivity = sensitivity > 0 ? sensitivity : 5; + value = isNaN(value) ? this.min : value; + + var input = new InputComponent(this); + var slider_left = new SliderComponent(this, -1); + var slider_right = new SliderComponent(this, 1); + + slider_left.className = 'ui-input-slider-left'; + slider_right.className = 'ui-input-slider-right'; + + if (name) { + var info = document.createElement('span'); + info.className = 'ui-input-slider-info'; + info.textContent = name; + node.appendChild(info); + } + + node.appendChild(slider_left); + node.appendChild(input); + node.appendChild(slider_right); + + this.input = input; + sliders[topic] = this; + setValue(topic, value); + }; + + InputSlider.prototype.setInputValue = function setInputValue() { + this.input.value = this.value.toFixed(this.precision) + this.unit; + }; + + var setValue = function setValue(topic, value, send_notify) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + value = parseFloat(value.toFixed(slider.precision)); + + if (value > slider.max) value = slider.max; + if (value < slider.min) value = slider.min; + + slider.value = value; + slider.node.setAttribute('data-value', value); + + slider.setInputValue(); + + if (send_notify === false) + return; + + notify.call(slider); + }; + + var setMax = function setMax(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.max = value; + setValue(topic, slider.value); + }; + + var setMin = function setMin(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.min = value; + setValue(topic, slider.value); + }; + + var setUnit = function setUnit(topic, unit) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.unit = unit; + setValue(topic, slider.value); + }; + + var setStep = function setStep(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.step = parseFloat(value); + setValue(topic, slider.value); + }; + + var setPrecision = function setPrecision(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + value = value | 0; + slider.precision = value; + + var step = parseFloat(slider.step.toFixed(value)); + if (step === 0) + slider.step = 1 / Math.pow(10, value); + + setValue(topic, slider.value); + }; + + var setSensitivity = function setSensitivity(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + value = value | 0; + + slider.sensitivity = value > 0 ? value : 5; + }; + + var getNode = function getNode(topic) { + return sliders[topic].node; + }; + + var getPrecision = function getPrecision(topic) { + return sliders[topic].precision; + }; + + var getStep = function getStep(topic) { + return sliders[topic].step; + }; + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + subscribers[topic].push(callback); + }; + + var unsubscribe = function unsubscribe(topic, callback) { + subscribers[topic].indexOf(callback); + subscribers[topic].splice(index, 1); + }; + + var notify = function notify() { + if (subscribers[this.topic] === undefined) + return; + for (var i = 0; i < subscribers[this.topic].length; i++) + subscribers[this.topic][i](this.value); + }; + + var createSlider = function createSlider(topic, label) { + var slider = document.createElement('div'); + slider.className = 'ui-input-slider'; + slider.setAttribute('data-topic', topic); + + if (label !== undefined) + slider.setAttribute('data-info', label); + + new InputSlider(slider); + return slider; + }; + + var init = function init() { + var elem = document.querySelectorAll('.ui-input-slider'); + var size = elem.length; + for (var i = 0; i < size; i++) + new InputSlider(elem[i]); + }; + + return { + init : init, + setMax : setMax, + setMin : setMin, + setUnit : setUnit, + setStep : setStep, + getNode : getNode, + getStep : getStep, + setValue : setValue, + subscribe : subscribe, + unsubscribe : unsubscribe, + setPrecision : setPrecision, + setSensitivity : setSensitivity, + getPrecision : getPrecision, + createSlider : createSlider, + }; + +})(); + +'use strict'; + +window.addEventListener("load", function() { + ColorPickerTool.init(); +}); + +var ColorPickerTool = (function ColorPickerTool() { + + /*========== Get DOM Element By ID ==========*/ + + function getElemById(id) { + return document.getElementById(id); + } + + function allowDropEvent(e) { + e.preventDefault(); + } + + /*========== Make an element resizable relative to it's parent ==========*/ + + var UIComponent = (function UIComponent() { + + function makeResizable(elem, axis) { + var valueX = 0; + var valueY = 0; + var action = 0; + + var resizeStart = function resizeStart(e) { + e.stopPropagation(); + e.preventDefault(); + if (e.button !== 0) + return; + + valueX = e.clientX - elem.clientWidth; + valueY = e.clientY - elem.clientHeight; + + document.body.setAttribute('data-resize', axis); + document.addEventListener('mousemove', mouseMove); + document.addEventListener('mouseup', resizeEnd); + }; + + var mouseMove = function mouseMove(e) { + if (action >= 0) + elem.style.width = e.clientX - valueX + 'px'; + if (action <= 0) + elem.style.height = e.clientY - valueY + 'px'; + }; + + var resizeEnd = function resizeEnd(e) { + if (e.button !== 0) + return; + + document.body.removeAttribute('data-resize', axis); + document.removeEventListener('mousemove', mouseMove); + document.removeEventListener('mouseup', resizeEnd); + }; + + var handle = document.createElement('div'); + handle.className = 'resize-handle'; + + if (axis === 'width') action = 1; + else if (axis === 'height') action = -1; + else axis = 'both'; + + handle.className = 'resize-handle'; + handle.setAttribute('data-resize', axis); + handle.addEventListener('mousedown', resizeStart); + elem.appendChild(handle); + }; + + /*========== Make an element draggable relative to it's parent ==========*/ + + var makeDraggable = function makeDraggable(elem, endFunction) { + + var offsetTop; + var offsetLeft; + + elem.setAttribute('data-draggable', 'true'); + + var dragStart = function dragStart(e) { + e.preventDefault(); + e.stopPropagation(); + + if (e.target.getAttribute('data-draggable') !== 'true' || + e.target !== elem || e.button !== 0) + return; + + offsetLeft = e.clientX - elem.offsetLeft; + offsetTop = e.clientY - elem.offsetTop; + + document.addEventListener('mousemove', mouseDrag); + document.addEventListener('mouseup', dragEnd); + }; + + var dragEnd = function dragEnd(e) { + if (e.button !== 0) + return; + + document.removeEventListener('mousemove', mouseDrag); + document.removeEventListener('mouseup', dragEnd); + }; + + var mouseDrag = function mouseDrag(e) { + elem.style.left = e.clientX - offsetLeft + 'px'; + elem.style.top = e.clientY - offsetTop + 'px'; + }; + + elem.addEventListener('mousedown', dragStart, false); + }; + + return { + makeResizable : makeResizable, + makeDraggable : makeDraggable + }; + + })(); + + /*========== Color Class ==========*/ + + var Color = UIColorPicker.Color; + var HSLColor = UIColorPicker.HSLColor; + + /** + * ColorPalette + */ + var ColorPalette = (function ColorPalette() { + + var samples = []; + var color_palette; + var complementary; + + var hideNode = function(node) { + node.setAttribute('data-hidden', 'true'); + }; + + var ColorSample = function ColorSample(id) { + var node = document.createElement('div'); + node.className = 'sample'; + + this.uid = samples.length; + this.node = node; + this.color = new Color(); + + node.setAttribute('sample-id', this.uid); + node.setAttribute('draggable', 'true'); + node.addEventListener('dragstart', this.dragStart.bind(this)); + node.addEventListener('click', this.pickColor.bind(this)); + + samples.push(this); + }; + + ColorSample.prototype.updateBgColor = function updateBgColor() { + this.node.style.backgroundColor = this.color.getColor(); + }; + + ColorSample.prototype.updateColor = function updateColor(color) { + this.color.copy(color); + this.updateBgColor(); + }; + + ColorSample.prototype.updateHue = function updateHue(color, degree, steps) { + this.color.copy(color); + var hue = (steps * degree + this.color.hue) % 360; + if (hue < 0) hue += 360; + this.color.setHue(hue); + this.updateBgColor(); + }; + + ColorSample.prototype.updateSaturation = function updateSaturation(color, value, steps) { + var saturation = color.saturation + value * steps; + if (saturation <= 0) { + this.node.setAttribute('data-hidden', 'true'); + return; + } + + this.node.removeAttribute('data-hidden'); + this.color.copy(color); + this.color.setSaturation(saturation); + this.updateBgColor(); + }; + + ColorSample.prototype.updateLightness = function updateLightness(color, value, steps) { + var lightness = color.lightness + value * steps; + if (lightness <= 0) { + this.node.setAttribute('data-hidden', 'true'); + return; + } + this.node.removeAttribute('data-hidden'); + this.color.copy(color); + this.color.setLightness(lightness); + this.updateBgColor(); + }; + + ColorSample.prototype.updateBrightness = function updateBrightness(color, value, steps) { + var brightness = color.value + value * steps; + if (brightness <= 0) { + this.node.setAttribute('data-hidden', 'true'); + return; + } + this.node.removeAttribute('data-hidden'); + this.color.copy(color); + this.color.setValue(brightness); + this.updateBgColor(); + }; + + ColorSample.prototype.updateAlpha = function updateAlpha(color, value, steps) { + var alpha = parseFloat(color.a) + value * steps; + if (alpha <= 0) { + this.node.setAttribute('data-hidden', 'true'); + return; + } + this.node.removeAttribute('data-hidden'); + this.color.copy(color); + this.color.a = parseFloat(alpha.toFixed(2)); + this.updateBgColor(); + }; + + ColorSample.prototype.pickColor = function pickColor() { + UIColorPicker.setColor('picker', this.color); + }; + + ColorSample.prototype.dragStart = function dragStart(e) { + e.dataTransfer.setData('sampleID', this.uid); + e.dataTransfer.setData('location', 'palette-samples'); + }; + + var Palette = function Palette(text, size) { + this.samples = []; + this.locked = false; + + var palette = document.createElement('div'); + var title = document.createElement('div'); + var controls = document.createElement('div'); + var container = document.createElement('div'); + var lock = document.createElement('div'); + + container.className = 'container'; + title.className = 'title'; + palette.className = 'palette'; + controls.className = 'controls'; + lock.className = 'lock'; + title.textContent = text; + + controls.appendChild(lock); + container.appendChild(title); + container.appendChild(controls); + container.appendChild(palette); + + lock.addEventListener('click', function () { + this.locked = !this.locked; + lock.setAttribute('locked-state', this.locked); + }.bind(this)); + + for(var i = 0; i < size; i++) { + var sample = new ColorSample(); + this.samples.push(sample); + palette.appendChild(sample.node); + } + + this.container = container; + this.title = title; + }; + + var createHuePalette = function createHuePalette() { + var palette = new Palette('Hue', 12); + + UIColorPicker.subscribe('picker', function(color) { + if (palette.locked === true) + return; + + for(var i = 0; i < 12; i++) { + palette.samples[i].updateHue(color, 30, i); + } + }); + + color_palette.appendChild(palette.container); + }; + + var createSaturationPalette = function createSaturationPalette() { + var palette = new Palette('Saturation', 11); + + UIColorPicker.subscribe('picker', function(color) { + if (palette.locked === true) + return; + + for(var i = 0; i < 11; i++) { + palette.samples[i].updateSaturation(color, -10, i); + } + }); + + color_palette.appendChild(palette.container); + }; + + /* Brightness or Lightness - depends on the picker mode */ + var createVLPalette = function createSaturationPalette() { + var palette = new Palette('Lightness', 11); + + UIColorPicker.subscribe('picker', function(color) { + if (palette.locked === true) + return; + + if(color.format === 'HSL') { + palette.title.textContent = 'Lightness'; + for(var i = 0; i < 11; i++) + palette.samples[i].updateLightness(color, -10, i); + } + else { + palette.title.textContent = 'Value'; + for(var i = 0; i < 11; i++) + palette.samples[i].updateBrightness(color, -10, i); + } + }); + + color_palette.appendChild(palette.container); + }; + + var isBlankPalette = function isBlankPalette(container, value) { + if (value === 0) { + container.setAttribute('data-collapsed', 'true'); + return true; + } + + container.removeAttribute('data-collapsed'); + return false; + }; + + var createAlphaPalette = function createAlphaPalette() { + var palette = new Palette('Alpha', 10); + + UIColorPicker.subscribe('picker', function(color) { + if (palette.locked === true) + return; + + for(var i = 0; i < 10; i++) { + palette.samples[i].updateAlpha(color, -0.1, i); + } + }); + + color_palette.appendChild(palette.container); + }; + + var getSampleColor = function getSampleColor(id) { + if (samples[id] !== undefined && samples[id]!== null) + return new Color(samples[id].color); + }; + + var init = function init() { + color_palette = getElemById('color-palette'); + + createHuePalette(); + createSaturationPalette(); + createVLPalette(); + createAlphaPalette(); + + }; + + return { + init : init, + getSampleColor : getSampleColor + }; + + })(); + + /** + * ColorInfo + */ + var ColorInfo = (function ColorInfo() { + + var info_box; + var select; + var RGBA; + var HEXA; + var HSLA; + + var updateInfo = function updateInfo(color) { + if (color.a | 0 === 1) { + RGBA.info.textContent = 'RGB'; + HSLA.info.textContent = 'HSL'; + } + else { + RGBA.info.textContent = 'RGBA'; + HSLA.info.textContent = 'HSLA'; + } + + RGBA.value.value = color.getRGBA(); + HSLA.value.value = color.getHSLA(); + HEXA.value.value = color.getHexa(); + }; + + var InfoProperty = function InfoProperty(info) { + + var node = document.createElement('div'); + var title = document.createElement('div'); + var value = document.createElement('input'); + var copy = document.createElement('div'); + + node.className = 'property'; + title.className = 'type'; + value.className = 'value'; + copy.className = 'copy'; + + title.textContent = info; + value.setAttribute('type', 'text'); + + copy.addEventListener('click', function() { + value.select(); + }); + + node.appendChild(title); + node.appendChild(value); + node.appendChild(copy); + + this.node = node; + this.value = value; + this.info = title; + + info_box.appendChild(node); + }; + + var init = function init() { + + info_box = getElemById('color-info'); + + RGBA = new InfoProperty('RGBA'); + HSLA = new InfoProperty('HSLA'); + HEXA = new InfoProperty('HEXA'); + + UIColorPicker.subscribe('picker', updateInfo); + + }; + + return { + init: init + }; + + })(); + + /** + * ColorPicker Samples + */ + var ColorPickerSamples = (function ColorPickerSamples() { + + var samples = []; + var nr_samples = 0; + var active = null; + var container = null; + var samples_per_line = 10; + var trash_can = null; + var base_color = new HSLColor(0, 50, 100); + var add_btn; + var add_btn_pos; + + var ColorSample = function ColorSample() { + var node = document.createElement('div'); + node.className = 'sample'; + + this.uid = samples.length; + this.index = nr_samples++; + this.node = node; + this.color = new Color(base_color); + + node.setAttribute('sample-id', this.uid); + node.setAttribute('draggable', 'true'); + + node.addEventListener('dragstart', this.dragStart.bind(this)); + node.addEventListener('dragover' , allowDropEvent); + node.addEventListener('drop' , this.dragDrop.bind(this)); + + this.updatePosition(this.index); + this.updateBgColor(); + samples.push(this); + }; + + ColorSample.prototype.updateBgColor = function updateBgColor() { + this.node.style.backgroundColor = this.color.getColor(); + }; + + ColorSample.prototype.updatePosition = function updatePosition(index) { + this.index = index; + this.posY = 5 + ((index / samples_per_line) | 0) * 52; + this.posX = 5 + ((index % samples_per_line) | 0) * 52; + this.node.style.top = this.posY + 'px'; + this.node.style.left = this.posX + 'px'; + }; + + ColorSample.prototype.updateColor = function updateColor(color) { + this.color.copy(color); + this.updateBgColor(); + }; + + ColorSample.prototype.activate = function activate() { + UIColorPicker.setColor('picker', this.color); + this.node.setAttribute('data-active', 'true'); + }; + + ColorSample.prototype.deactivate = function deactivate() { + this.node.removeAttribute('data-active'); + }; + + ColorSample.prototype.dragStart = function dragStart(e) { + e.dataTransfer.setData('sampleID', this.uid); + e.dataTransfer.setData('location', 'picker-samples'); + }; + + ColorSample.prototype.dragDrop = function dragDrop(e) { + e.stopPropagation(); + this.color = Tool.getSampleColorFrom(e); + this.updateBgColor(); + }; + + ColorSample.prototype.deleteSample = function deleteSample() { + container.removeChild(this.node); + samples[this.uid] = null; + nr_samples--; + }; + + var updateUI = function updateUI() { + updateContainerProp(); + + var index = 0; + var nr = samples.length; + for (var i=0; i < nr; i++) + if (samples[i] !== null) { + samples[i].updatePosition(index); + index++; + } + + AddSampleButton.updatePosition(index); + }; + + var deleteSample = function deleteSample(e) { + trash_can.parentElement.setAttribute('drag-state', 'none'); + + var location = e.dataTransfer.getData('location'); + if (location !== 'picker-samples') + return; + + var sampleID = e.dataTransfer.getData('sampleID'); + samples[sampleID].deleteSample(); + console.log(samples); + + updateUI(); + }; + + var createDropSample = function createDropSample() { + var sample = document.createElement('div'); + sample.id = 'drop-effect-sample'; + sample.className = 'sample'; + container.appendChild(sample); + }; + + var setActivateSample = function setActivateSample(e) { + if (e.target.className !== 'sample') + return; + + unsetActiveSample(active); + Tool.unsetVoidSample(); + CanvasSamples.unsetActiveSample(); + active = samples[e.target.getAttribute('sample-id')]; + active.activate(); + }; + + var unsetActiveSample = function unsetActiveSample() { + if (active) + active.deactivate(); + active = null; + }; + + var getSampleColor = function getSampleColor(id) { + if (samples[id] !== undefined && samples[id]!== null) + return new Color(samples[id].color); + }; + + var updateContainerProp = function updateContainerProp() { + samples_per_line = ((container.clientWidth - 5) / 52) | 0; + var height = 52 * (1 + (nr_samples / samples_per_line) | 0); + container.style.height = height + 10 + 'px'; + }; + + var AddSampleButton = (function AddSampleButton() { + var node; + var _index = 0; + var _posX; + var _posY; + + var updatePosition = function updatePosition(index) { + _index = index; + _posY = 5 + ((index / samples_per_line) | 0) * 52; + _posX = 5 + ((index % samples_per_line) | 0) * 52; + + node.style.top = _posY + 'px'; + node.style.left = _posX + 'px'; + }; + + var addButtonClick = function addButtonClick() { + var sample = new ColorSample(); + container.appendChild(sample.node); + updatePosition(_index + 1); + updateUI(); + }; + + var init = function init() { + node = document.createElement('div'); + var icon = document.createElement('div'); + + node.className = 'sample'; + icon.id = 'add-icon'; + node.appendChild(icon); + node.addEventListener('click', addButtonClick); + + updatePosition(0); + container.appendChild(node); + }; + + return { + init : init, + updatePosition : updatePosition + }; + })(); + + var init = function init() { + container = getElemById('picker-samples'); + trash_can = getElemById('trash-can'); + + AddSampleButton.init(); + + for (var i=0; i<16; i++) { + var sample = new ColorSample(); + container.appendChild(sample.node); + } + + AddSampleButton.updatePosition(samples.length); + updateUI(); + + active = samples[0]; + active.activate(); + + container.addEventListener('click', setActivateSample); + + trash_can.addEventListener('dragover', allowDropEvent); + trash_can.addEventListener('dragenter', function() { + this.parentElement.setAttribute('drag-state', 'enter'); + }); + trash_can.addEventListener('dragleave', function(e) { + this.parentElement.setAttribute('drag-state', 'none'); + }); + trash_can.addEventListener('drop', deleteSample); + + UIColorPicker.subscribe('picker', function(color) { + if (active) + active.updateColor(color); + }); + + }; + + return { + init : init, + getSampleColor : getSampleColor, + unsetActiveSample : unsetActiveSample + }; + + })(); + + /** + * Canvas Samples + */ + var CanvasSamples = (function CanvasSamples() { + + var active = null; + var canvas = null; + var samples = []; + var zindex = null; + var tutorial = true; + + var CanvasSample = function CanvasSample(color, posX, posY) { + + var node = document.createElement('div'); + var pick = document.createElement('div'); + var delete_btn = document.createElement('div'); + node.className = 'sample'; + pick.className = 'pick'; + delete_btn.className = 'delete'; + + this.uid = samples.length; + this.node = node; + this.color = color; + this.updateBgColor(); + this.zIndex = 1; + + node.style.top = posY - 50 + 'px'; + node.style.left = posX - 50 + 'px'; + node.setAttribute('sample-id', this.uid); + + node.appendChild(pick); + node.appendChild(delete_btn); + + var activate = function activate() { + setActiveSample(this); + }.bind(this); + + node.addEventListener('dblclick', activate); + pick.addEventListener('click', activate); + delete_btn.addEventListener('click', this.deleteSample.bind(this)); + + UIComponent.makeDraggable(node); + UIComponent.makeResizable(node); + + samples.push(this); + canvas.appendChild(node); + return this; + }; + + CanvasSample.prototype.updateBgColor = function updateBgColor() { + this.node.style.backgroundColor = this.color.getColor(); + }; + + CanvasSample.prototype.updateColor = function updateColor(color) { + this.color.copy(color); + this.updateBgColor(); + }; + + CanvasSample.prototype.updateZIndex = function updateZIndex(value) { + this.zIndex = value; + this.node.style.zIndex = value; + }; + + CanvasSample.prototype.activate = function activate() { + this.node.setAttribute('data-active', 'true'); + zindex.setAttribute('data-active', 'true'); + + UIColorPicker.setColor('picker', this.color); + InputSliderManager.setValue('z-index', this.zIndex); + }; + + CanvasSample.prototype.deactivate = function deactivate() { + this.node.removeAttribute('data-active'); + zindex.removeAttribute('data-active'); + }; + + CanvasSample.prototype.deleteSample = function deleteSample() { + if (active === this) + unsetActiveSample(); + canvas.removeChild(this.node); + samples[this.uid] = null; + }; + + CanvasSample.prototype.updatePosition = function updatePosition(posX, posY) { + this.node.style.top = posY - this.startY + 'px'; + this.node.style.left = posX - this.startX + 'px'; + }; + + var canvasDropEvent = function canvasDropEvent(e) { + var color = Tool.getSampleColorFrom(e); + + if (color) { + var offsetX = e.pageX - canvas.offsetLeft; + var offsetY = e.pageY - canvas.offsetTop; + var sample = new CanvasSample(color, offsetX, offsetY); + if (tutorial) { + tutorial = false; + canvas.removeAttribute('data-tutorial'); + var info = new CanvasSample(new Color(), 100, 100); + info.node.setAttribute('data-tutorial', 'dblclick'); + } + } + + }; + + var setActiveSample = function setActiveSample(sample) { + ColorPickerSamples.unsetActiveSample(); + Tool.unsetVoidSample(); + unsetActiveSample(); + active = sample; + active.activate(); + }; + + var unsetActiveSample = function unsetActiveSample() { + if (active) + active.deactivate(); + active = null; + }; + + var createToggleBgButton = function createToggleBgButton() { + var button = document.createElement('div'); + var state = false; + button.className = 'toggle-bg'; + canvas.appendChild(button); + + button.addEventListener('click', function() { + console.log(state); + state = !state; + canvas.setAttribute('data-bg', state); + }); + }; + + var init = function init() { + canvas = getElemById('canvas'); + zindex = getElemById('zindex'); + + canvas.addEventListener('dragover', allowDropEvent); + canvas.addEventListener('drop', canvasDropEvent); + + createToggleBgButton(); + + UIColorPicker.subscribe('picker', function(color) { + if (active) active.updateColor(color); + }); + + InputSliderManager.subscribe('z-index', function (value) { + if (active) active.updateZIndex(value); + }); + + UIComponent.makeResizable(canvas, 'height'); + }; + + return { + init : init, + unsetActiveSample : unsetActiveSample + }; + + })(); + + var StateButton = function StateButton(node, state) { + this.state = false; + this.callback = null; + + node.addEventListener('click', function() { + this.state = !this.state; + if (typeof this.callback === "function") + this.callback(this.state); + }.bind(this)); + }; + + StateButton.prototype.set = function set() { + this.state = true; + if (typeof this.callback === "function") + this.callback(this.state); + }; + + StateButton.prototype.unset = function unset() { + this.state = false; + if (typeof this.callback === "function") + this.callback(this.state); + }; + + StateButton.prototype.subscribe = function subscribe(func) { + this.callback = func; + }; + + /** + * Tool + */ + var Tool = (function Tool() { + + var samples = []; + var controls = null; + var void_sw; + + var createPickerModeSwitch = function createPickerModeSwitch() { + var parent = getElemById('controls'); + var icon = document.createElement('div'); + var button = document.createElement('div'); + var hsv = document.createElement('div'); + var hsl = document.createElement('div'); + var active = null; + + icon.className = 'icon picker-icon'; + button.className = 'switch'; + button.appendChild(hsv); + button.appendChild(hsl); + + hsv.textContent = 'HSV'; + hsl.textContent = 'HSL'; + + active = hsl; + active.setAttribute('data-active', 'true'); + + function switchPickingModeTo(elem) { + active.removeAttribute('data-active'); + active = elem; + active.setAttribute('data-active', 'true'); + UIColorPicker.setPickerMode('picker', active.textContent); + }; + + var picker_sw = new StateButton(icon); + picker_sw.subscribe(function() { + if (active === hsv) + switchPickingModeTo(hsl); + else + switchPickingModeTo(hsv); + }); + + hsv.addEventListener('click', function() { + switchPickingModeTo(hsv); + }); + hsl.addEventListener('click', function() { + switchPickingModeTo(hsl); + }); + + parent.appendChild(icon); + parent.appendChild(button); + }; + + var setPickerDragAndDrop = function setPickerDragAndDrop() { + var preview = document.querySelector('#picker .preview-color'); + var picking_area = document.querySelector('#picker .picking-area'); + + preview.setAttribute('draggable', 'true'); + preview.addEventListener('drop', drop); + preview.addEventListener('dragstart', dragStart); + preview.addEventListener('dragover', allowDropEvent); + + picking_area.addEventListener('drop', drop); + picking_area.addEventListener('dragover', allowDropEvent); + + function drop(e) { + var color = getSampleColorFrom(e); + UIColorPicker.setColor('picker', color); + }; + + function dragStart(e) { + e.dataTransfer.setData('sampleID', 'picker'); + e.dataTransfer.setData('location', 'picker'); + }; + }; + + var getSampleColorFrom = function getSampleColorFrom(e) { + var sampleID = e.dataTransfer.getData('sampleID'); + var location = e.dataTransfer.getData('location'); + + if (location === 'picker') + return UIColorPicker.getColor(sampleID); + if (location === 'picker-samples') + return ColorPickerSamples.getSampleColor(sampleID); + if (location === 'palette-samples') + return ColorPalette.getSampleColor(sampleID); + }; + + var setVoidSwitch = function setVoidSwitch() { + var void_sample = getElemById('void-sample'); + void_sw = new StateButton(void_sample); + void_sw.subscribe( function (state) { + void_sample.setAttribute('data-active', state); + if (state === true) { + ColorPickerSamples.unsetActiveSample(); + CanvasSamples.unsetActiveSample(); + } + }); + }; + + var unsetVoidSample = function unsetVoidSample() { + void_sw.unset(); + }; + + var init = function init() { + controls = getElemById('controls'); + + var color = new Color(); + color.setHSL(0, 51, 51); + UIColorPicker.setColor('picker', color); + + setPickerDragAndDrop(); + createPickerModeSwitch(); + setVoidSwitch(); + }; + + return { + init : init, + unsetVoidSample : unsetVoidSample, + getSampleColorFrom : getSampleColorFrom + }; + + })(); + + var init = function init() { + UIColorPicker.init(); + InputSliderManager.init(); + ColorInfo.init(); + ColorPalette.init(); + ColorPickerSamples.init(); + CanvasSamples.init(); + Tool.init(); + }; + + return { + init : init + }; + +})(); diff --git a/tools/color-picker/styles.css b/tools/color-picker/styles.css new file mode 100644 index 00000000..050dcc99 --- /dev/null +++ b/tools/color-picker/styles.css @@ -0,0 +1,996 @@ +/* + * COLOR PICKER TOOL + */ + +.ui-color-picker { + width: 420px; + margin: 0; + border: 1px solid #DDD; + background-color: #FFF; + display: table; + + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.ui-color-picker .picking-area { + width: 198px; + height: 198px; + margin: 5px; + border: 1px solid #DDD; + position: relative; + float: left; + display: table; +} + +.ui-color-picker .picking-area:hover { + cursor: default; +} + +/* HSV format - Hue-Saturation-Value(Brightness) */ +.ui-color-picker .picking-area { + background: url('picker_mask_200.png') center center; + + background: -moz-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%), + -moz-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%); + background: -webkit-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%), + -webkit-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%); + background: -ms-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%), + -ms-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%); + background: -o-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%), + -o-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%); + + background-color: #F00; +} + +/* HSL format - Hue-Saturation-Lightness */ +.ui-color-picker[data-mode='HSL'] .picking-area { + background: -moz-linear-gradient(top, hsl(0, 0%, 100%) 0%, hsla(0, 0%, 100%, 0) 50%, + hsla(0, 0%, 0%, 0) 50%, hsl(0, 0%, 0%) 100%), + -moz-linear-gradient(left, hsl(0, 0%, 50%) 0%, hsla(0, 0%, 50%, 0) 100%); + background: -webkit-linear-gradient(top, hsl(0, 0%, 100%) 0%, hsla(0, 0%, 100%, 0) 50%, + hsla(0, 0%, 0%, 0) 50%, hsl(0, 0%, 0%) 100%), + -webkit-linear-gradient(left, hsl(0, 0%, 50%) 0%, hsla(0, 0%, 50%, 0) 100%); + background: -ms-linear-gradient(top, hsl(0, 0%, 100%) 0%, hsla(0, 0%, 100%, 0) 50%, + hsla(0, 0%, 0%, 0) 50%, hsl(0, 0%, 0%) 100%), + -ms-linear-gradient(left, hsl(0, 0%, 50%) 0%, hsla(0, 0%, 50%, 0) 100%); + background: -o-linear-gradient(top, hsl(0, 0%, 100%) 0%, hsla(0, 0%, 100%, 0) 50%, + hsla(0, 0%, 0%, 0) 50%, hsl(0, 0%, 0%) 100%), + -o-linear-gradient(left, hsl(0, 0%, 50%) 0%, hsla(0, 0%, 50%, 0) 100%); + background-color: #F00; +} + +.ui-color-picker .picker { + width: 10px; + height: 10px; + border-radius: 50%; + border: 1px solid #FFF; + position: absolute; + top: 45%; + left: 45%; +} + +.ui-color-picker .picker:before { + width: 8px; + height: 8px; + content: ""; + position: absolute; + border: 1px solid #999; + border-radius: 50%; +} + +.ui-color-picker .hue, +.ui-color-picker .alpha { + width: 198px; + height: 28px; + margin: 5px; + border: 1px solid #FFF; + float: left; +} + +.ui-color-picker .hue { + background: url("hue.png") center; + background: -moz-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%, + #00F 66.66%, #F0F 83.33%, #F00 100%); + background: -webkit-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%, + #00F 66.66%, #F0F 83.33%, #F00 100%); + background: -ms-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%, + #00F 66.66%, #F0F 83.33%, #F00 100%); + background: -o-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%, + #00F 66.66%, #F0F 83.33%, #F00 100%); +} + +.ui-color-picker .alpha { + border: 1px solid #CCC; + background: url("alpha.png"); +} + +.ui-color-picker .alpha-mask { + width: 100%; + height: 100%; + background: url("alpha_mask.png"); +} + +.ui-color-picker .slider-picker { + width: 2px; + height: 100%; + border: 1px solid #777; + background-color: #FFF; + position: relative; + top: -1px; +} + +/* input HSV and RGB */ + +.ui-color-picker .info { + width: 200px; + margin: 5px; + float: left; +} + +.ui-color-picker .info * { + float: left; +} + +.ui-color-picker .input { + width: 64px; + margin: 5px 2px; + float: left; +} + +.ui-color-picker .input .name { + height: 20px; + width: 30px; + text-align: center; + font-size: 14px; + line-height: 18px; + float: left; +} + +.ui-color-picker .input input { + width: 30px; + height: 18px; + margin: 0; + padding: 0; + border: 1px solid #DDD; + text-align: center; + float: right; + + -moz-user-select: text; + -webkit-user-select: text; + -ms-user-select: text; +} + +.ui-color-picker .input[data-topic="lightness"] { + display: none; +} + +.ui-color-picker[data-mode='HSL'] .input[data-topic="value"] { + display: none; +} + +.ui-color-picker[data-mode='HSL'] .input[data-topic="lightness"] { + display: block; +} + +.ui-color-picker .input[data-topic="alpha"] { + margin-top: 10px; + width: 93px; +} + +.ui-color-picker .input[data-topic="alpha"] > .name { + width: 60px; +} + +.ui-color-picker .input[data-topic="alpha"] > input { + float: right; +} + +.ui-color-picker .input[data-topic="hexa"] { + width: auto; + float: right; + margin: 6px 8px 0 0; +} + +.ui-color-picker .input[data-topic="hexa"] > .name { + display: none; +} + +.ui-color-picker .input[data-topic="hexa"] > input { + width: 90px; + height: 24px; + padding: 2px 0; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +/* Preview color */ +.ui-color-picker .preview { + width: 95px; + height: 53px; + margin: 5px; + margin-top: 10px; + border: 1px solid #DDD; + background-image: url("alpha.png"); + float: left; + position: relative; +} + +.ui-color-picker .preview:before { + height: 100%; + width: 50%; + left: 50%; + top: 0; + content: ""; + background: #FFF; + position: absolute; + z-index: 1; +} + +.ui-color-picker .preview-color { + width: 100%; + height: 100%; + background-color: rgba(255, 0, 0, 0.5); + position: absolute; + z-index: 1; +} + +.ui-color-picker .switch_mode { + width: 10px; + height: 20px; + position: relative; + border-radius: 5px 0 0 5px; + border: 1px solid #DDD; + background-color: #EEE; + left: -12px; + top: -1px; + z-index: 1; + transition: all 0.5s; +} + +.ui-color-picker .switch_mode:hover { + background-color: #CCC; + cursor: pointer; +} + +/* + * UI Component + */ + +.ui-input-slider { + height: 20px; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + -moz-user-select: none; + user-select: none; +} + +.ui-input-slider * { + float: left; + height: 100%; + line-height: 100%; +} + +/* Input Slider */ + +.ui-input-slider > input { + margin: 0; + padding: 0; + width: 50px; + text-align: center; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.ui-input-slider-info { + width: 90px; + padding: 0px 10px 0px 0px; + text-align: right; + text-transform: lowercase; +} + +.ui-input-slider-left, .ui-input-slider-right { + width: 16px; + cursor: pointer; + background: url("arrows.png") center left no-repeat; +} + +.ui-input-slider-right { + background: url("arrows.png") center right no-repeat; +} + +.ui-input-slider-name { + width: 90px; + padding: 0 10px 0 0; + text-align: right; + text-transform: lowercase; +} + +.ui-input-slider-btn-set { + width: 25px; + background-color: #2C9FC9; + border-radius: 5px; + color: #FFF; + font-weight: bold; + line-height: 14px; + text-align: center; +} + +.ui-input-slider-btn-set:hover { + background-color: #379B4A; + cursor: pointer; +} + +/* + * COLOR PICKER TOOL + */ + +body { + max-width: 1000px; + margin: 0 auto; + + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + + box-shadow: 0 0 5px 0 #999; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + +} + +/** + * Resize Handle + */ +.resize-handle { + width: 10px; + height: 10px; + background: url('resize.png') center center no-repeat; + position: absolute; + bottom: 0; + right: 0; +} + +[data-resize='both']:hover { + cursor: nw-resize !important; +} + +[data-resize='width']:hover { + cursor: w-resize !important; +} + +[data-resize='height']:hover { + cursor: n-resize !important; +} + +[data-hidden='true'] { + display: none; +} + +[data-collapsed='true'] { + height: 0 !important; +} + +.block { + display: table; +} + +/** + * Container + */ +#container { + width: 100%; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + display: table; +} + +/** + * Picker Zone + */ + +#picker { + padding: 10px; + width: 980px; +} + +.ui-color-picker { + padding: 3px 5px; + float: left; + border-color: #FFF; +} + +.ui-color-picker .switch_mode { + display: none; +} + +.ui-color-picker .preview-color:hover { + cursor: move; +} + +/** + * Picker Container + */ + +#picker-samples { + width: 375px; + height: 114px; + max-height: 218px; + margin: 0 10px 0 30px; + overflow: hidden; + position: relative; + float: left; + + transition: all 0.2s; +} + +#picker-samples .sample { + width: 40px; + height: 40px; + margin: 5px; + border: 1px solid #DDD; + position: absolute; + float: left; + transition: all 0.2s; +} + +#picker-samples .sample:hover { + cursor: pointer; + border-color: #BBB; + transform: scale(1.15); + border-radius: 3px; +} + +#picker-samples .sample[data-active='true'] { + border-color: #999; +} + +#picker-samples .sample[data-active='true']:after { + content: ""; + position: absolute; + background: url('arrow.png') center no-repeat; + width: 100%; + height: 12px; + top: -12px; + z-index: 2; +} + +#picker-samples #add-icon { + width: 100%; + height: 100%; + position: relative; + box-shadow: inset 0px 0px 2px 0px #DDD; +} + +#picker-samples #add-icon:hover { + cursor: pointer; + border-color: #DDD; + box-shadow: inset 0px 0px 5px 0px #CCC; +} + +#picker-samples #add-icon:before, +#picker-samples #add-icon:after { + content: ""; + position: absolute; + background-color: #EEE; + box-shadow: 0 0 1px 0 #EEE; +} + +#picker-samples #add-icon:before { + width: 70%; + height: 16%; + top: 42%; + left: 15%; +} + +#picker-samples #add-icon:after { + width: 16%; + height: 70%; + top: 15%; + left: 42%; +} + +#picker-samples #add-icon:hover:before, +#picker-samples #add-icon:hover:after { + background-color: #DDD; + box-shadow: 0 0 1px 0 #DDD; +} + +/** + * Controls + */ + +#controls { + width: 110px; + padding: 10px; + float: right; +} + +#controls #picker-switch { + text-align: center; + float: left; +} + +#controls .icon { + width: 48px; + height: 48px; + margin: 10px 0; + background-repeat: no-repeat; + background-position: center; + border: 1px solid #DDD; + display: table; + float: left; +} + +#controls .icon:hover { + cursor: pointer; +} + +#controls .picker-icon { + background-image: url('picker.png'); +} + +#controls #void-sample { + margin-right: 10px; + background-image: url('void.png'); + background-position: center left; +} + +#controls #void-sample[data-active='true'] { + border-color: #CCC; + background-position: center right; +} + +#controls .switch { + width: 106px; + padding: 1px; + border: 1px solid #CCC; + font-size: 14px; + text-align: center; + line-height: 24px; + overflow: hidden; + float: left; +} + +#controls .switch:hover { + cursor: pointer; +} + +#controls .switch > * { + width: 50%; + padding: 2px 0; + background-color: #EEE; + float: left; +} + +#controls .switch [data-active='true'] { + color: #FFF; + background-image: url('grain.png'); + background-color: #777; +} + +/** + * Trash Can + */ + +#delete { + width: 100%; + height: 94px; + background-color: #DDD; + background-image: url('grain.png'); + background-repeat: repeat; + + text-align: center; + color: #777; + + position: relative; + float: right; +} + +#delete #trash-can { + width: 80%; + height: 80%; + border: 2px dashed #FFF; + border-radius: 5px; + background: url('trash-can.png') no-repeat center; + + position: absolute; + top: 10%; + left: 10%; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + transition: all 0.2s; +} + +#delete[drag-state='enter'] { + background-color: #999; +} + +/** + * Color Theme + */ + +#color-theme { + margin: 0 8px 0 0; + border: 1px solid #EEE; + display: inline-block; + float: right; +} + +#color-theme .box { + width: 80px; + height: 92px; + float: left; +} + +/** + * Color info box + */ +#color-info { + width: 360px; + float: left; +} + +#color-info .title { + width: 100%; + padding: 15px; + font-size: 18px; + text-align: center; + background-image: url('color-wheel.png'); + background-repeat:no-repeat; + background-position: center left 30%; +} + +#color-info .copy-container { + position: absolute; + top: -100%; +} + +#color-info .property { + min-width: 280px; + height: 30px; + margin: 10px 0; + text-align: center; + line-height: 30px; +} + +#color-info .property > * { + float: left; +} + +#color-info .property .type { + width: 60px; + height: 100%; + padding: 0 16px 0 0; + text-align: right; +} + +#color-info .property .value { + width: 200px; + height: 100%; + padding: 0 10px; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + font-size: 16px; + color: #777; + text-align: center; + background-color: #FFF; + border: none; +} + +#color-info .property .value:hover { + color: #37994A; +} + +#color-info .property .value:hover + .copy { + background-position: center right; +} + +#color-info .property .copy { + width: 24px; + height: 100%; + padding: 0 5px; + background-color: #FFF; + background-image: url('copy.png'); + background-repeat: no-repeat; + background-position: center left; + border-left: 1px solid #EEE; + text-align: right; + float: left; +} + +#color-info .property .copy:hover { + background-position: center right; +} + +/** + * Color Palette + */ + +#palette { + width: 1000px; + padding: 10px 0; + background-image: url('grain.png'); + background-repeat: repeat; + background-color: #EEE; + color: #777; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#color-palette { + width: 640px; + font-family: Arial, Helvetica, sans-serif; + color: #777; + float: left; +} + +#color-palette .container { + width: 100%; + height: 50px; + line-height: 50px; + overflow: hidden; + float: left; + transition: all 0.5s; +} + +#color-palette .container > * { + float: left; +} + +#color-palette .title { + width: 100px; + padding: 0 10px; + text-align: right; + line-height: inherit; +} + +#color-palette .palette { + width: 456px; + height: 38px; + margin: 3px; + padding: 3px; + display: table; + background-color: #FFF; +} + +#color-palette .palette .sample { + width: 30px; + height: 30px; + margin: 3px; + position: relative; + border: 1px solid #DDD; + float: left; + transition: all 0.2s; +} + +#color-palette .palette .sample:hover { + cursor: pointer; + border-color: #BBB; + transform: scale(1.15); + border-radius: 3px; +} + +#color-palette .controls { +} + +#color-palette .controls > * { + float: left; +} + +#color-palette .controls > *:hover { + cursor: pointer; +} + +#color-palette .controls .lock { + width: 24px; + height: 24px; + margin: 10px; + padding: 3px; + background-image: url('lock.png'); + background-repeat: no-repeat; + background-position: bottom right; +} + +#color-palette .controls .lock:hover { + /*background-image: url('images/unlocked-hover.png');*/ + background-position: bottom left; +} + +#color-palette .controls .lock[locked-state='true'] { + /*background-image: url('images/locked.png');*/ + background-position: top left ; +} + +#color-palette .controls .lock[locked-state='true']:hover { + /*background-image: url('images/lock-hover.png');*/ + background-position: top right; +} + +/** + * Canvas + */ + +#canvas { + width: 100%; + height: 300px; + min-height: 250px; + border-top: 1px solid #DDD; + background-image: url('grain.png'); + background-repeat: repeat; + position: relative; + float: left; +} + +#canvas[data-tutorial='drop'] { + text-align: center; + font-size: 30px; + color: #777; +} + +#canvas[data-tutorial='drop']:before { + content: "Drop colors here to compare"; + width: 40%; + padding: 30px 9% 70px 11%; + + background-image: url('drop.png'); + background-repeat: no-repeat; + background-position: left 35px top 60%; + + text-align: right; + + border: 3px dashed rgb(221, 221, 221); + border-radius: 15px; + + position: absolute; + top: 50px; + left: 20%; +} + +#canvas[data-tutorial='drop']:after { + content: "adjust, change or modify"; + width: 40%; + font-size: 24px; + position: absolute; + top: 130px; + left: 32%; + z-index: 2; +} + +#canvas [data-tutorial='dblclick'] { + background-color: #999 !important; +} + +#canvas [data-tutorial='dblclick']:before { + content: "double click to activate"; + width: 80px; + color: #FFF; + position: absolute; + top: 10%; + left: 20%; + z-index: 2; +} + +#canvas .sample { + width: 100px; + height: 100px; + min-width: 20px; + min-height: 20px; + position: absolute; + border: 1px solid rgba(255, 255, 255, 0.3); +} + +#canvas .sample:hover { + cursor: move; +} + +#canvas .sample[data-active='true']:after { + content: ""; + position: absolute; + background: url('arrow.png') center no-repeat; + width: 100%; + height: 12px; + top: -12px; + z-index: 2; +} + +#canvas .sample:hover > * { + cursor: pointer; + display: block !important; +} + +#canvas .sample .resize-handle { + display: none; +} + +#canvas .sample .pick { + width: 10px; + height: 10px; + margin: 5px; + background: url('pick.png') center no-repeat; + position: absolute; + top: 0; + left: 0; + display: none; +} + +#canvas .sample .delete { + width: 10px; + height: 10px; + margin: 5px; + background: url('close.png') center no-repeat; + position: absolute; + top: 0; + right: 0; + display: none; +} + +/** + * Canvas controls + */ + +#canvas .toggle-bg { + width: 16px; + height: 16px; + margin: 5px; + background: url("images/canvas-controls.png") center left no-repeat; + position: absolute; + top: 0; + right: 0; +} + +#canvas .toggle-bg:hover { + cursor: pointer; +} + +#canvas[data-bg='true'] { + background: none; +} + +#canvas[data-bg='true'] .toggle-bg { + background: url('canvas-controls.png') center right no-repeat; +} + +#zindex { + height: 20px; + margin: 5px; + font-size: 16px; + position: absolute; + opacity: 0; + top: -10000px; + left: 0; + color: #777; + float: left; + transition: opacity 1s; +} + +#zindex input { + border: 1px solid #DDD; + font-size: 16px; + color: #777; +} + +#zindex .ui-input-slider-info { + width: 60px; +} + +#zindex[data-active='true'] { + top: 0; + opacity: 1; +} diff --git a/tools/color-picker/trash-can.png b/tools/color-picker/trash-can.png new file mode 100644 index 0000000000000000000000000000000000000000..e7528bdb55c65b13c87c58596c7ab23fe214478c GIT binary patch literal 443 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaNp1AIbU-3xsF4-n8x+3yN;hDJ${UoeA$28#%Xw~0-~&-s6M^?c#(T*}0y zqkGTtGoy-lLSfBQ{gSAEJk#Csg|tF}dRBS5IEHu}e>>&0&>;mLSLUXxzgE59{x$dC ze{NN)X5*2xS4PV=y)3&hg;P;L4LTXJ1?&@t3 zy#FaK$!`a9%m)GGIh_1VRUJ;#FZekLO}fxipmgU0*M#GoruDtasUcm5HeJ(qyUG6Q z^-hI1R`(;%{`jZF-6p=}+U-*(c1Y@LEM1f~|8WmvhM*bC<|Ub7sUl3*)!R=B;# W?QzQ1r&oclX7F_Nb6Mw<&;$UxS@yaB literal 0 HcmV?d00001 diff --git a/tools/color-picker/void.png b/tools/color-picker/void.png new file mode 100644 index 0000000000000000000000000000000000000000..71bd564ef3c7dab62e219ca85be85c6d01c3e5ce GIT binary patch literal 1707 zcmeAS@N?(olHy`uVBq!ia0vp^2|z5t!3HE*U;dZ^q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1Ffc1+hD4M^`1)8S=jZArg4F0$^BXQ!4Z zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT zY?Xj6g?J&i0B&qvF*KNf0j6J(SfFpHX8`gNOrftYexnUy@&(kzb(T9Bihb5uTZsl3!k| z30CjxYvq|&T#}fVoa*Ufs{}MbFEca6%F@Wd)X>1x$j}vt4PA{b4J{1ZTrJGZoZZ}9 z%$=NJdR_99OLJ56N?>|Z5PFSq>IEf*+ybD@E~!PCWvMA{Mftf3U@u!`;&zJxPV=C8 zQ*gTl=mi}9&<8q39~7}j5e*XprXCOzo@{{}c*0N31E%&OV6yh<_WTXZE%Kf&jv*Dd zuFUex5OEY~)9ySd`pC7=J$cVA)fGD$#jjUzEYfJIFi37X?f7BB1K}Et0LVSEKvuH0{D+LDt_Sl(irz)=LK$~nLVqPq|TnDwR->l{VKM}LaV|> zZ}9Rps3xo_tX12{D#Li)F+9XoCOYfaYGHx(i=Wu-Uf57>J#2(iA13atd_`N@>v#RPq&V`vlkC(68FT<44k$ z+g1tcHv~TE**e5_e5{%G>%61YJQlw|=DiQZ zW!Eo1v1&`_rToVXf1SNo&RNX$;>1pgpw1*S2Tj=$uCi6!$6|2nsanY{z($OgNxyuOcpWy+Jzl;ovxC#;vXaF_x#_Qlu9{vp@8Uq>g~ zT$U5^e11@5RY1aCJ{bkC{k_a>Jty7MC+;)xNZ%~Pez16(+-Jc%We*qvf93ACI=As) z&c09KOs|vNg2aDkWh7kp+u#|v)VHTDn*D|7;lpn#WGfh^9j^%E{+lpo_sTz4J;T-9 z>MifzH9rtow&tk);*~$$45r4;UhwDXEk3VkIZJ;B?b+vc8wvh8eOK`EY(eEOvOnEwW=sEt1?C>{T(ji8`j#&HKc9h_A!ezF)afrAv7qY1 M)78&qol`;+07Za~Z~y=R literal 0 HcmV?d00001