/js/BubbleDots/lib/color.js

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs · JavaScript · 261 lines · 159 code · 27 blank · 75 comment · 19 complexity · 1827978974dc39644c08e30cc5adf5e9 MD5 · raw file

  1. /**
  2. * @author Hyperandroid || http://hyperandroid.com/
  3. *
  4. * Helper classes for color manipulation.
  5. *
  6. **/
  7. (function() {
  8. CAAT = (typeof CAAT === 'undefined') ? {} : CAAT;
  9. /**
  10. * Class with color utilities.
  11. *
  12. * @constructor
  13. */
  14. CAAT.Color = function() {
  15. return this;
  16. };
  17. CAAT.Color.prototype= {
  18. /**
  19. * HSV to RGB color conversion
  20. * <p>
  21. * H runs from 0 to 360 degrees<br>
  22. * S and V run from 0 to 100
  23. * <p>
  24. * Ported from the excellent java algorithm by Eugene Vishnevsky at:
  25. * http://www.cs.rit.edu/~ncs/color/t_convert.html
  26. *
  27. * @static
  28. */
  29. hsvToRgb: function(h, s, v)
  30. {
  31. var r, g, b;
  32. var i;
  33. var f, p, q, t;
  34. // Make sure our arguments stay in-range
  35. h = Math.max(0, Math.min(360, h));
  36. s = Math.max(0, Math.min(100, s));
  37. v = Math.max(0, Math.min(100, v));
  38. // We accept saturation and value arguments from 0 to 100 because that's
  39. // how Photoshop represents those values. Internally, however, the
  40. // saturation and value are calculated from a range of 0 to 1. We make
  41. // That conversion here.
  42. s /= 100;
  43. v /= 100;
  44. if(s == 0) {
  45. // Achromatic (grey)
  46. r = g = b = v;
  47. return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
  48. }
  49. h /= 60; // sector 0 to 5
  50. i = Math.floor(h);
  51. f = h - i; // factorial part of h
  52. p = v * (1 - s);
  53. q = v * (1 - s * f);
  54. t = v * (1 - s * (1 - f));
  55. switch(i) {
  56. case 0:
  57. r = v;
  58. g = t;
  59. b = p;
  60. break;
  61. case 1:
  62. r = q;
  63. g = v;
  64. b = p;
  65. break;
  66. case 2:
  67. r = p;
  68. g = v;
  69. b = t;
  70. break;
  71. case 3:
  72. r = p;
  73. g = q;
  74. b = v;
  75. break;
  76. case 4:
  77. r = t;
  78. g = p;
  79. b = v;
  80. break;
  81. default: // case 5:
  82. r = v;
  83. g = p;
  84. b = q;
  85. }
  86. return new CAAT.Color.RGB(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));
  87. },
  88. /**
  89. * Enumeration to define types of color ramps.
  90. * @enum {number}
  91. */
  92. RampEnumeration : {
  93. RAMP_RGBA: 0,
  94. RAMP_RGB: 1,
  95. RAMP_CHANNEL_RGB: 2,
  96. RAMP_CHANNEL_RGBA: 3,
  97. RAMP_CHANNEL_RGB_ARRAY: 4,
  98. RAMP_CHANNEL_RGBA_ARRAY:5
  99. },
  100. /**
  101. * Interpolate the color between two given colors. The return value will be a calculated color
  102. * among the two given initial colors which corresponds to the 'step'th color of the 'nsteps'
  103. * calculated colors.
  104. * @param r0 {number} initial color red component.
  105. * @param g0 {number} initial color green component.
  106. * @param b0 {number} initial color blue component.
  107. * @param r1 {number} final color red component.
  108. * @param g1 {number} final color green component.
  109. * @param b1 {number} final color blue component.
  110. * @param nsteps {number} number of colors to calculate including the two given colors. If 16 is passed as value,
  111. * 14 colors plus the two initial ones will be calculated.
  112. * @param step {number} return this color index of all the calculated colors.
  113. *
  114. * @return { r{number}, g{number}, b{number} } return an object with the new calculated color components.
  115. * @static
  116. */
  117. interpolate : function( r0, g0, b0, r1, g1, b1, nsteps, step) {
  118. if ( step<=0 ) {
  119. return {
  120. r:r0,
  121. g:g0,
  122. b:b0
  123. };
  124. } else if ( step>=nsteps ) {
  125. return {
  126. r:r1,
  127. g:g1,
  128. b:b1
  129. };
  130. }
  131. var r= (r0+ (r1-r0)/nsteps*step)>>0;
  132. var g= (g0+ (g1-g0)/nsteps*step)>>0;
  133. var b= (b0+ (b1-b0)/nsteps*step)>>0;
  134. if ( r>255 ) {r=255;} else if (r<0) {r=0;}
  135. if ( g>255 ) {g=255;} else if (g<0) {g=0;}
  136. if ( b>255 ) {b=255;} else if (b<0) {b=0;}
  137. return {
  138. r:r,
  139. g:g,
  140. b:b
  141. };
  142. },
  143. /**
  144. * Generate a ramp of colors from an array of given colors.
  145. * @param fromColorsArray {[number]} an array of colors. each color is defined by an integer number from which
  146. * color components will be extracted. Be aware of the alpha component since it will also be interpolated for
  147. * new colors.
  148. * @param rampSize {number} number of colors to produce.
  149. * @param returnType {CAAT.ColorUtils.RampEnumeration} a value of CAAT.ColorUtils.RampEnumeration enumeration.
  150. *
  151. * @return { [{number},{number},{number},{number}] } an array of integers each of which represents a color of
  152. * the calculated color ramp.
  153. *
  154. * @static
  155. */
  156. makeRGBColorRamp : function( fromColorsArray, rampSize, returnType ) {
  157. var ramp= [];
  158. var nc= fromColorsArray.length-1;
  159. var chunk= rampSize/nc;
  160. for( var i=0; i<nc; i++ ) {
  161. var c= fromColorsArray[i];
  162. var a0= (c>>24)&0xff;
  163. var r0= (c&0xff0000)>>16;
  164. var g0= (c&0xff00)>>8;
  165. var b0= c&0xff;
  166. var c1= fromColorsArray[i+1];
  167. var a1= (c1>>24)&0xff;
  168. var r1= (c1&0xff0000)>>16;
  169. var g1= (c1&0xff00)>>8;
  170. var b1= c1&0xff;
  171. var da= (a1-a0)/chunk;
  172. var dr= (r1-r0)/chunk;
  173. var dg= (g1-g0)/chunk;
  174. var db= (b1-b0)/chunk;
  175. for( var j=0; j<chunk; j++ ) {
  176. var na= (a0+da*j)>>0;
  177. var nr= (r0+dr*j)>>0;
  178. var ng= (g0+dg*j)>>0;
  179. var nb= (b0+db*j)>>0;
  180. switch( returnType ) {
  181. case this.RampEnumeration.RAMP_RGBA:
  182. ramp.push( 'argb('+na+','+nr+','+ng+','+nb+')' );
  183. break;
  184. case this.RampEnumeration.RAMP_RGB:
  185. ramp.push( 'rgb('+nr+','+ng+','+nb+')' );
  186. break;
  187. case this.RampEnumeration.RAMP_CHANNEL_RGB:
  188. ramp.push( 0xff000000 | nr<<16 | ng<<8 | nb );
  189. break;
  190. case this.RampEnumeration.RAMP_CHANNEL_RGBA:
  191. ramp.push( na<<24 | nr<<16 | ng<<8 | nb );
  192. break;
  193. case this.RampEnumeration.RAMP_CHANNEL_RGBA_ARRAY:
  194. ramp.push([ nr, ng, nb, na ]);
  195. break;
  196. case this.RampEnumeration.RAMP_CHANNEL_RGB_ARRAY:
  197. ramp.push([ nr, ng, nb ]);
  198. break;
  199. }
  200. }
  201. }
  202. return ramp;
  203. }
  204. };
  205. })();
  206. (function() {
  207. /**
  208. * RGB color implementation
  209. * @param r {number} an integer in the range 0..255
  210. * @param g {number} an integer in the range 0..255
  211. * @param b {number} an integer in the range 0..255
  212. *
  213. * @constructor
  214. */
  215. CAAT.Color.RGB = function(r, g, b) {
  216. this.r = r || 255;
  217. this.g = g || 255;
  218. this.b = b || 255;
  219. return this;
  220. };
  221. CAAT.Color.RGB.prototype= {
  222. r: 255,
  223. g: 255,
  224. b: 255,
  225. /**
  226. * Get color hexadecimal representation.
  227. * @return {string} a string with color hexadecimal representation.
  228. */
  229. toHex: function() {
  230. // See: http://jsperf.com/rgb-decimal-to-hex/5
  231. return ('000000' + ((this.r << 16) + (this.g << 8) + this.b).toString(16)).slice(-6);
  232. }
  233. };
  234. })();