1 | /*
|
---|
2 |
|
---|
3 | Colour.js
|
---|
4 |
|
---|
5 | Objects for handling and processing colours
|
---|
6 |
|
---|
7 | Created by Stephen Morley - http://code.stephenmorley.org/ - and released under
|
---|
8 | the terms of the CC0 1.0 Universal legal code:
|
---|
9 |
|
---|
10 | http://creativecommons.org/publicdomain/zero/1.0/legalcode
|
---|
11 |
|
---|
12 | */
|
---|
13 |
|
---|
14 | /* An abstract Colour implementation. Concrete Colour implementations should use
|
---|
15 | * an instance of this function as their prototype, and implement the getRGB and
|
---|
16 | * getHSL functions. getRGB should return an object representing the RGB
|
---|
17 | * components of this Colour, with the red, green, and blue components in the
|
---|
18 | * range [0,255] and the alpha component in the range [0,100]. getHSL should
|
---|
19 | * return an object representing the HSL components of this Colour, with the hue
|
---|
20 | * component in the range [0,360), the saturation and lightness components in
|
---|
21 | * the range [0,100], and the alpha component in the range [0,1].
|
---|
22 | */
|
---|
23 | function Colour(){
|
---|
24 |
|
---|
25 | /* Returns an object representing the RGBA components of this Colour. The red,
|
---|
26 | * green, and blue components are converted to integers in the range [0,255].
|
---|
27 | * The alpha is a value in the range [0,1].
|
---|
28 | */
|
---|
29 | this.getIntegerRGB = function(){
|
---|
30 |
|
---|
31 | // get the RGB components of this colour
|
---|
32 | var rgb = this.getRGB();
|
---|
33 |
|
---|
34 | // return the integer components
|
---|
35 | return {
|
---|
36 | 'r' : Math.round(rgb.r),
|
---|
37 | 'g' : Math.round(rgb.g),
|
---|
38 | 'b' : Math.round(rgb.b),
|
---|
39 | 'a' : rgb.a
|
---|
40 | };
|
---|
41 |
|
---|
42 | };
|
---|
43 |
|
---|
44 | /* Returns an object representing the RGBA components of this Colour. The red,
|
---|
45 | * green, and blue components are converted to numbers in the range [0,100].
|
---|
46 | * The alpha is a value in the range [0,1].
|
---|
47 | */
|
---|
48 | this.getPercentageRGB = function(){
|
---|
49 |
|
---|
50 | // get the RGB components of this colour
|
---|
51 | var rgb = this.getRGB();
|
---|
52 |
|
---|
53 | // return the percentage components
|
---|
54 | return {
|
---|
55 | 'r' : 100 * rgb.r / 255,
|
---|
56 | 'g' : 100 * rgb.g / 255,
|
---|
57 | 'b' : 100 * rgb.b / 255,
|
---|
58 | 'a' : rgb.a
|
---|
59 | };
|
---|
60 |
|
---|
61 | };
|
---|
62 |
|
---|
63 | /* Returns a string representing this Colour as a CSS hexadecimal RGB colour
|
---|
64 | * value - that is, a string of the form #RRGGBB where each of RR, GG, and BB
|
---|
65 | * are two-digit hexadecimal numbers.
|
---|
66 | */
|
---|
67 | this.getCSSHexadecimalRGB = function(){
|
---|
68 |
|
---|
69 | // get the integer RGB components
|
---|
70 | var rgb = this.getIntegerRGB();
|
---|
71 |
|
---|
72 | // determine the hexadecimal equivalents
|
---|
73 | var r16 = rgb.r.toString(16);
|
---|
74 | var g16 = rgb.g.toString(16);
|
---|
75 | var b16 = rgb.b.toString(16);
|
---|
76 |
|
---|
77 | // return the CSS RGB colour value
|
---|
78 | return '#'
|
---|
79 | + (r16.length == 2 ? r16 : '0' + r16)
|
---|
80 | + (g16.length == 2 ? g16 : '0' + g16)
|
---|
81 | + (b16.length == 2 ? b16 : '0' + b16);
|
---|
82 |
|
---|
83 | };
|
---|
84 |
|
---|
85 | /* Returns a string representing this Colour as a CSS integer RGB colour
|
---|
86 | * value - that is, a string of the form rgb(r,g,b) where each of r, g, and b
|
---|
87 | * are integers in the range [0,255].
|
---|
88 | */
|
---|
89 | this.getCSSIntegerRGB = function(){
|
---|
90 |
|
---|
91 | // get the integer RGB components
|
---|
92 | var rgb = this.getIntegerRGB();
|
---|
93 |
|
---|
94 | // return the CSS RGB colour value
|
---|
95 | return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
|
---|
96 |
|
---|
97 | };
|
---|
98 |
|
---|
99 | /* Returns a string representing this Colour as a CSS integer RGBA colour
|
---|
100 | * value - that is, a string of the form rgba(r,g,b,a) where each of r, g, and
|
---|
101 | * b are integers in the range [0,255] and a is in the range [0,1].
|
---|
102 | */
|
---|
103 | this.getCSSIntegerRGBA = function(){
|
---|
104 |
|
---|
105 | // get the integer RGB components
|
---|
106 | var rgb = this.getIntegerRGB();
|
---|
107 |
|
---|
108 | // return the CSS integer RGBA colour value
|
---|
109 | return 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')';
|
---|
110 |
|
---|
111 | };
|
---|
112 |
|
---|
113 | /* Returns a string representing this Colour as a CSS percentage RGB colour
|
---|
114 | * value - that is, a string of the form rgb(r%,g%,b%) where each of r, g, and
|
---|
115 | * b are in the range [0,100].
|
---|
116 | */
|
---|
117 | this.getCSSPercentageRGB = function(){
|
---|
118 |
|
---|
119 | // get the percentage RGB components
|
---|
120 | var rgb = this.getPercentageRGB();
|
---|
121 |
|
---|
122 | // return the CSS RGB colour value
|
---|
123 | return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%)';
|
---|
124 |
|
---|
125 | };
|
---|
126 |
|
---|
127 | /* Returns a string representing this Colour as a CSS percentage RGBA colour
|
---|
128 | * value - that is, a string of the form rgba(r%,g%,b%,a) where each of r, g,
|
---|
129 | * and b are in the range [0,100] and a is in the range [0,1].
|
---|
130 | */
|
---|
131 | this.getCSSPercentageRGBA = function(){
|
---|
132 |
|
---|
133 | // get the percentage RGB components
|
---|
134 | var rgb = this.getPercentageRGB();
|
---|
135 |
|
---|
136 | // return the CSS percentage RGBA colour value
|
---|
137 | return 'rgba(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%,' + rgb.a + ')';
|
---|
138 |
|
---|
139 | };
|
---|
140 |
|
---|
141 | /* Returns a string representing this Colour as a CSS HSL colour value - that
|
---|
142 | * is, a string of the form hsl(h,s%,l%) where h is in the range [0,360) and
|
---|
143 | * s and l are in the range [0,100].
|
---|
144 | */
|
---|
145 | this.getCSSHSL = function(){
|
---|
146 |
|
---|
147 | // get the HSL components
|
---|
148 | var hsl = this.getHSL();
|
---|
149 |
|
---|
150 | // return the CSS HSL colour value
|
---|
151 | return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%)';
|
---|
152 |
|
---|
153 | };
|
---|
154 |
|
---|
155 | /* Returns a string representing this Colour as a CSS HSLA colour value - that
|
---|
156 | * is, a string of the form hsla(h,s%,l%,a) where h is in the range [0,360),
|
---|
157 | * s and l are in the range [0,100], and a is in the range [0,1].
|
---|
158 | */
|
---|
159 | this.getCSSHSLA = function(){
|
---|
160 |
|
---|
161 | // get the HSL components
|
---|
162 | var hsl = this.getHSL();
|
---|
163 |
|
---|
164 | // return the CSS HSL colour value
|
---|
165 | return 'hsla(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%,' + hsl.a + ')';
|
---|
166 |
|
---|
167 | };
|
---|
168 |
|
---|
169 | /* Sets the colour of the specified node to this Colour. This function sets
|
---|
170 | * the CSS 'color' property for the node. The parameter is:
|
---|
171 | *
|
---|
172 | * node - the node whose colour should be set
|
---|
173 | */
|
---|
174 | this.setNodeColour = function(node){
|
---|
175 |
|
---|
176 | // set the colour of the node
|
---|
177 | node.style.color = this.getCSSHexadecimalRGB();
|
---|
178 |
|
---|
179 | };
|
---|
180 |
|
---|
181 | /* Sets the background colour of the specified node to this Colour. This
|
---|
182 | * function sets the CSS 'background-color' property for the node. The
|
---|
183 | * parameter is:
|
---|
184 | *
|
---|
185 | * node - the node whose background colour should be set
|
---|
186 | */
|
---|
187 | this.setNodeBackgroundColour = function(node){
|
---|
188 |
|
---|
189 | // set the background colour of the node
|
---|
190 | node.style.backgroundColor = this.getCSSHexadecimalRGB();
|
---|
191 |
|
---|
192 | };
|
---|
193 |
|
---|
194 | }
|
---|
195 |
|
---|
196 | /* Creates a colour specified in the RGB colour space, with an optional alpha
|
---|
197 | * component. The parameters are:
|
---|
198 | *
|
---|
199 | * r - the red component, clipped to the range [0,255]
|
---|
200 | * g - the green component, clipped to the range [0,255]
|
---|
201 | * b - the blue component, clipped to the range [0,255]
|
---|
202 | * a - the alpha component, clipped to the range [0,1] - this parameter is
|
---|
203 | * optional and defaults to 1
|
---|
204 | */
|
---|
205 | RGBColour.prototype = new Colour();
|
---|
206 | function RGBColour(r, g, b, a){
|
---|
207 |
|
---|
208 | // store the alpha component after clipping it if necessary
|
---|
209 | var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
|
---|
210 |
|
---|
211 | // store the RGB components after clipping them if necessary
|
---|
212 | var rgb =
|
---|
213 | {
|
---|
214 | 'r' : Math.max(0, Math.min(255, r)),
|
---|
215 | 'g' : Math.max(0, Math.min(255, g)),
|
---|
216 | 'b' : Math.max(0, Math.min(255, b))
|
---|
217 | };
|
---|
218 |
|
---|
219 | // initialise the HSV and HSL components to null
|
---|
220 | var hsv = null;
|
---|
221 | var hsl = null;
|
---|
222 |
|
---|
223 | /* Returns the HSV or HSL hue component of this RGBColour. The hue is in the
|
---|
224 | * range [0,360). The parameters are:
|
---|
225 | *
|
---|
226 | * maximum - the maximum of the RGB component values
|
---|
227 | * range - the range of the RGB component values
|
---|
228 | */
|
---|
229 | function getHue(maximum, range){
|
---|
230 |
|
---|
231 | // check whether the range is zero
|
---|
232 | if (range == 0){
|
---|
233 |
|
---|
234 | // set the hue to zero (any hue is acceptable as the colour is grey)
|
---|
235 | var hue = 0;
|
---|
236 |
|
---|
237 | }else{
|
---|
238 |
|
---|
239 | // determine which of the components has the highest value and set the hue
|
---|
240 | switch (maximum){
|
---|
241 |
|
---|
242 | // red has the highest value
|
---|
243 | case rgb.r:
|
---|
244 | var hue = (rgb.g - rgb.b) / range * 60;
|
---|
245 | if (hue < 0) hue += 360;
|
---|
246 | break;
|
---|
247 |
|
---|
248 | // green has the highest value
|
---|
249 | case rgb.g:
|
---|
250 | var hue = (rgb.b - rgb.r) / range * 60 + 120;
|
---|
251 | break;
|
---|
252 |
|
---|
253 | // blue has the highest value
|
---|
254 | case rgb.b:
|
---|
255 | var hue = (rgb.r - rgb.g) / range * 60 + 240;
|
---|
256 | break;
|
---|
257 |
|
---|
258 | }
|
---|
259 |
|
---|
260 | }
|
---|
261 |
|
---|
262 | // return the hue
|
---|
263 | return hue;
|
---|
264 |
|
---|
265 | }
|
---|
266 |
|
---|
267 | /* Calculates and stores the HSV components of this RGBColour so that they can
|
---|
268 | * be returned be the getHSV function.
|
---|
269 | */
|
---|
270 | function calculateHSV(){
|
---|
271 |
|
---|
272 | // get the maximum and range of the RGB component values
|
---|
273 | var maximum = Math.max(rgb.r, rgb.g, rgb.b);
|
---|
274 | var range = maximum - Math.min(rgb.r, rgb.g, rgb.b);
|
---|
275 |
|
---|
276 | // store the HSV components
|
---|
277 | hsv =
|
---|
278 | {
|
---|
279 | 'h' : getHue(maximum, range),
|
---|
280 | 's' : (maximum == 0 ? 0 : 100 * range / maximum),
|
---|
281 | 'v' : maximum / 2.55
|
---|
282 | };
|
---|
283 |
|
---|
284 | }
|
---|
285 |
|
---|
286 | /* Calculates and stores the HSL components of this RGBColour so that they can
|
---|
287 | * be returned be the getHSL function.
|
---|
288 | */
|
---|
289 | function calculateHSL(){
|
---|
290 |
|
---|
291 | // get the maximum and range of the RGB component values
|
---|
292 | var maximum = Math.max(rgb.r, rgb.g, rgb.b);
|
---|
293 | var range = maximum - Math.min(rgb.r, rgb.g, rgb.b);
|
---|
294 |
|
---|
295 | // determine the lightness in the range [0,1]
|
---|
296 | var l = maximum / 255 - range / 510;
|
---|
297 |
|
---|
298 | // store the HSL components
|
---|
299 | hsl =
|
---|
300 | {
|
---|
301 | 'h' : getHue(maximum, range),
|
---|
302 | 's' : (range == 0 ? 0 : range / 2.55 / (l < 0.5 ? l * 2 : 2 - l * 2)),
|
---|
303 | 'l' : 100 * l
|
---|
304 | };
|
---|
305 |
|
---|
306 | }
|
---|
307 |
|
---|
308 | /* Returns the RGB and alpha components of this RGBColour as an object with r,
|
---|
309 | * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
|
---|
310 | * the range [0,1].
|
---|
311 | */
|
---|
312 | this.getRGB = function(){
|
---|
313 |
|
---|
314 | // return the RGB components
|
---|
315 | return {
|
---|
316 | 'r' : rgb.r,
|
---|
317 | 'g' : rgb.g,
|
---|
318 | 'b' : rgb.b,
|
---|
319 | 'a' : alpha
|
---|
320 | };
|
---|
321 |
|
---|
322 | };
|
---|
323 |
|
---|
324 | /* Returns the HSV and alpha components of this RGBColour as an object with h,
|
---|
325 | * s, v, and a properties. h is in the range [0,360), s and v are in the range
|
---|
326 | * [0,100], and a is in the range [0,1].
|
---|
327 | */
|
---|
328 | this.getHSV = function(){
|
---|
329 |
|
---|
330 | // calculate the HSV components if necessary
|
---|
331 | if (hsv == null) calculateHSV();
|
---|
332 |
|
---|
333 | // return the HSV components
|
---|
334 | return {
|
---|
335 | 'h' : hsv.h,
|
---|
336 | 's' : hsv.s,
|
---|
337 | 'v' : hsv.v,
|
---|
338 | 'a' : alpha
|
---|
339 | };
|
---|
340 |
|
---|
341 | };
|
---|
342 |
|
---|
343 | /* Returns the HSL and alpha components of this RGBColour as an object with h,
|
---|
344 | * s, l, and a properties. h is in the range [0,360), s and l are in the range
|
---|
345 | * [0,100], and a is in the range [0,1].
|
---|
346 | */
|
---|
347 | this.getHSL = function(){
|
---|
348 |
|
---|
349 | // calculate the HSV components if necessary
|
---|
350 | if (hsl == null) calculateHSL();
|
---|
351 |
|
---|
352 | // return the HSL components
|
---|
353 | return {
|
---|
354 | 'h' : hsl.h,
|
---|
355 | 's' : hsl.s,
|
---|
356 | 'l' : hsl.l,
|
---|
357 | 'a' : alpha
|
---|
358 | };
|
---|
359 |
|
---|
360 | };
|
---|
361 |
|
---|
362 | }
|
---|
363 |
|
---|
364 | /* Creates a colour specified in the HSV colour space, with an optional alpha
|
---|
365 | * component. The parameters are:
|
---|
366 | *
|
---|
367 | * h - the hue component, wrapped to the range [0,360)
|
---|
368 | * s - the saturation component, clipped to the range [0,100]
|
---|
369 | * v - the value component, clipped to the range [0,100]
|
---|
370 | * a - the alpha component, clipped to the range [0,1] - this parameter is
|
---|
371 | * optional and defaults to 1
|
---|
372 | */
|
---|
373 | HSVColour.prototype = new Colour();
|
---|
374 | function HSVColour(h, s, v, a){
|
---|
375 |
|
---|
376 | // store the alpha component after clipping it if necessary
|
---|
377 | var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
|
---|
378 |
|
---|
379 | // store the HSV components after clipping or wrapping them if necessary
|
---|
380 | var hsv =
|
---|
381 | {
|
---|
382 | 'h' : (h % 360 + 360) % 360,
|
---|
383 | 's' : Math.max(0, Math.min(100, s)),
|
---|
384 | 'v' : Math.max(0, Math.min(100, v))
|
---|
385 | };
|
---|
386 |
|
---|
387 | // initialise the RGB and HSL components to null
|
---|
388 | var rgb = null;
|
---|
389 | var hsl = null;
|
---|
390 |
|
---|
391 | /* Calculates and stores the RGB components of this HSVColour so that they can
|
---|
392 | * be returned be the getRGB function.
|
---|
393 | */
|
---|
394 | function calculateRGB(){
|
---|
395 |
|
---|
396 | // check whether the saturation is zero
|
---|
397 | if (hsv.s == 0){
|
---|
398 |
|
---|
399 | // set the colour to the appropriate shade of grey
|
---|
400 | var r = hsv.v;
|
---|
401 | var g = hsv.v;
|
---|
402 | var b = hsv.v;
|
---|
403 |
|
---|
404 | }else{
|
---|
405 |
|
---|
406 | // set some temporary values
|
---|
407 | var f = hsv.h / 60 - Math.floor(hsv.h / 60);
|
---|
408 | var p = hsv.v * (1 - hsv.s / 100);
|
---|
409 | var q = hsv.v * (1 - hsv.s / 100 * f);
|
---|
410 | var t = hsv.v * (1 - hsv.s / 100 * (1 - f));
|
---|
411 |
|
---|
412 | // set the RGB colour components to their temporary values
|
---|
413 | switch (Math.floor(hsv.h / 60)){
|
---|
414 | case 0: var r = hsv.v; var g = t; var b = p; break;
|
---|
415 | case 1: var r = q; var g = hsv.v; var b = p; break;
|
---|
416 | case 2: var r = p; var g = hsv.v; var b = t; break;
|
---|
417 | case 3: var r = p; var g = q; var b = hsv.v; break;
|
---|
418 | case 4: var r = t; var g = p; var b = hsv.v; break;
|
---|
419 | case 5: var r = hsv.v; var g = p; var b = q; break;
|
---|
420 | }
|
---|
421 |
|
---|
422 | }
|
---|
423 |
|
---|
424 | // store the RGB components
|
---|
425 | rgb =
|
---|
426 | {
|
---|
427 | 'r' : r * 2.55,
|
---|
428 | 'g' : g * 2.55,
|
---|
429 | 'b' : b * 2.55
|
---|
430 | };
|
---|
431 |
|
---|
432 | }
|
---|
433 |
|
---|
434 | /* Calculates and stores the HSL components of this HSVColour so that they can
|
---|
435 | * be returned be the getHSL function.
|
---|
436 | */
|
---|
437 | function calculateHSL(){
|
---|
438 |
|
---|
439 | // determine the lightness in the range [0,100]
|
---|
440 | var l = (2 - hsv.s / 100) * hsv.v / 2;
|
---|
441 |
|
---|
442 | // store the HSL components
|
---|
443 | hsl =
|
---|
444 | {
|
---|
445 | 'h' : hsv.h,
|
---|
446 | 's' : hsv.s * hsv.v / (l < 50 ? l * 2 : 200 - l * 2),
|
---|
447 | 'l' : l
|
---|
448 | };
|
---|
449 |
|
---|
450 | // correct a division-by-zero error
|
---|
451 | if (isNaN(hsl.s)) hsl.s = 0;
|
---|
452 |
|
---|
453 | }
|
---|
454 |
|
---|
455 | /* Returns the RGB and alpha components of this HSVColour as an object with r,
|
---|
456 | * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
|
---|
457 | * the range [0,1].
|
---|
458 | */
|
---|
459 | this.getRGB = function(){
|
---|
460 |
|
---|
461 | // calculate the RGB components if necessary
|
---|
462 | if (rgb == null) calculateRGB();
|
---|
463 |
|
---|
464 | // return the RGB components
|
---|
465 | return {
|
---|
466 | 'r' : rgb.r,
|
---|
467 | 'g' : rgb.g,
|
---|
468 | 'b' : rgb.b,
|
---|
469 | 'a' : alpha
|
---|
470 | };
|
---|
471 |
|
---|
472 | };
|
---|
473 |
|
---|
474 | /* Returns the HSV and alpha components of this HSVColour as an object with h,
|
---|
475 | * s, v, and a properties. h is in the range [0,360), s and v are in the range
|
---|
476 | * [0,100], and a is in the range [0,1].
|
---|
477 | */
|
---|
478 | this.getHSV = function(){
|
---|
479 |
|
---|
480 | // return the HSV components
|
---|
481 | return {
|
---|
482 | 'h' : hsv.h,
|
---|
483 | 's' : hsv.s,
|
---|
484 | 'v' : hsv.v,
|
---|
485 | 'a' : alpha
|
---|
486 | };
|
---|
487 |
|
---|
488 | };
|
---|
489 |
|
---|
490 | /* Returns the HSL and alpha components of this HSVColour as an object with h,
|
---|
491 | * s, l, and a properties. h is in the range [0,360), s and l are in the range
|
---|
492 | * [0,100], and a is in the range [0,1].
|
---|
493 | */
|
---|
494 | this.getHSL = function(){
|
---|
495 |
|
---|
496 | // calculate the HSL components if necessary
|
---|
497 | if (hsl == null) calculateHSL();
|
---|
498 |
|
---|
499 | // return the HSL components
|
---|
500 | return {
|
---|
501 | 'h' : hsl.h,
|
---|
502 | 's' : hsl.s,
|
---|
503 | 'l' : hsl.l,
|
---|
504 | 'a' : alpha
|
---|
505 | };
|
---|
506 |
|
---|
507 | };
|
---|
508 |
|
---|
509 | }
|
---|
510 |
|
---|
511 | /* Creates a colour specified in the HSL colour space, with an optional alpha
|
---|
512 | * component. The parameters are:
|
---|
513 | *
|
---|
514 | * h - the hue component, wrapped to the range [0,360)
|
---|
515 | * s - the saturation component, clipped to the range [0,100]
|
---|
516 | * l - the lightness component, clipped to the range [0,100]
|
---|
517 | * a - the alpha component, clipped to the range [0,1] - this parameter is
|
---|
518 | * optional and defaults to 1
|
---|
519 | */
|
---|
520 | HSLColour.prototype = new Colour();
|
---|
521 | function HSLColour(h, s, l, a){
|
---|
522 |
|
---|
523 | // store the alpha component after clipping it if necessary
|
---|
524 | var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
|
---|
525 |
|
---|
526 | // store the HSL components after clipping or wrapping them if necessary
|
---|
527 | var hsl =
|
---|
528 | {
|
---|
529 | 'h' : (h % 360 + 360) % 360,
|
---|
530 | 's' : Math.max(0, Math.min(100, s)),
|
---|
531 | 'l' : Math.max(0, Math.min(100, l))
|
---|
532 | };
|
---|
533 |
|
---|
534 | // initialise the RGB and HSV components to null
|
---|
535 | var rgb = null;
|
---|
536 | var hsv = null;
|
---|
537 |
|
---|
538 | /* Calculates and stores the RGB components of this HSLColour so that they can
|
---|
539 | * be returned be the getRGB function.
|
---|
540 | */
|
---|
541 | function calculateRGB(){
|
---|
542 |
|
---|
543 | // check whether the saturation is zero
|
---|
544 | if (hsl.s == 0){
|
---|
545 |
|
---|
546 | // store the RGB components representing the appropriate shade of grey
|
---|
547 | rgb =
|
---|
548 | {
|
---|
549 | 'r' : hsl.l * 2.55,
|
---|
550 | 'g' : hsl.l * 2.55,
|
---|
551 | 'b' : hsl.l * 2.55
|
---|
552 | };
|
---|
553 |
|
---|
554 | }else{
|
---|
555 |
|
---|
556 | // set some temporary values
|
---|
557 | var p = hsl.l < 50
|
---|
558 | ? hsl.l * (1 + hsl.s / 100)
|
---|
559 | : hsl.l + hsl.s - hsl.l * hsl.s / 100;
|
---|
560 | var q = 2 * hsl.l - p;
|
---|
561 |
|
---|
562 | // initialise the RGB components
|
---|
563 | rgb =
|
---|
564 | {
|
---|
565 | 'r' : (h + 120) / 60 % 6,
|
---|
566 | 'g' : h / 60,
|
---|
567 | 'b' : (h + 240) / 60 % 6
|
---|
568 | };
|
---|
569 |
|
---|
570 | // loop over the RGB components
|
---|
571 | for (var key in rgb){
|
---|
572 |
|
---|
573 | // ensure that the property is not inherited from the root object
|
---|
574 | if (rgb.hasOwnProperty(key)){
|
---|
575 |
|
---|
576 | // set the component to its value in the range [0,100]
|
---|
577 | if (rgb[key] < 1){
|
---|
578 | rgb[key] = q + (p - q) * rgb[key];
|
---|
579 | }else if (rgb[key] < 3){
|
---|
580 | rgb[key] = p;
|
---|
581 | }else if (rgb[key] < 4){
|
---|
582 | rgb[key] = q + (p - q) * (4 - rgb[key]);
|
---|
583 | }else{
|
---|
584 | rgb[key] = q;
|
---|
585 | }
|
---|
586 |
|
---|
587 | // set the component to its value in the range [0,255]
|
---|
588 | rgb[key] *= 2.55;
|
---|
589 |
|
---|
590 | }
|
---|
591 |
|
---|
592 | }
|
---|
593 |
|
---|
594 | }
|
---|
595 |
|
---|
596 | }
|
---|
597 |
|
---|
598 | /* Calculates and stores the HSV components of this HSLColour so that they can
|
---|
599 | * be returned be the getHSL function.
|
---|
600 | */
|
---|
601 | function calculateHSV(){
|
---|
602 |
|
---|
603 | // set a temporary value
|
---|
604 | var t = hsl.s * (hsl.l < 50 ? hsl.l : 100 - hsl.l) / 100;
|
---|
605 |
|
---|
606 | // store the HSV components
|
---|
607 | hsv =
|
---|
608 | {
|
---|
609 | 'h' : hsl.h,
|
---|
610 | 's' : 200 * t / (hsl.l + t),
|
---|
611 | 'v' : t + hsl.l
|
---|
612 | };
|
---|
613 |
|
---|
614 | // correct a division-by-zero error
|
---|
615 | if (isNaN(hsv.s)) hsv.s = 0;
|
---|
616 |
|
---|
617 | }
|
---|
618 |
|
---|
619 | /* Returns the RGB and alpha components of this HSLColour as an object with r,
|
---|
620 | * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
|
---|
621 | * the range [0,1].
|
---|
622 | */
|
---|
623 | this.getRGB = function(){
|
---|
624 |
|
---|
625 | // calculate the RGB components if necessary
|
---|
626 | if (rgb == null) calculateRGB();
|
---|
627 |
|
---|
628 | // return the RGB components
|
---|
629 | return {
|
---|
630 | 'r' : rgb.r,
|
---|
631 | 'g' : rgb.g,
|
---|
632 | 'b' : rgb.b,
|
---|
633 | 'a' : alpha
|
---|
634 | };
|
---|
635 |
|
---|
636 | };
|
---|
637 |
|
---|
638 | /* Returns the HSV and alpha components of this HSLColour as an object with h,
|
---|
639 | * s, v, and a properties. h is in the range [0,360), s and v are in the range
|
---|
640 | * [0,100], and a is in the range [0,1].
|
---|
641 | */
|
---|
642 | this.getHSV = function(){
|
---|
643 |
|
---|
644 | // calculate the HSV components if necessary
|
---|
645 | if (hsv == null) calculateHSV();
|
---|
646 |
|
---|
647 | // return the HSV components
|
---|
648 | return {
|
---|
649 | 'h' : hsv.h,
|
---|
650 | 's' : hsv.s,
|
---|
651 | 'v' : hsv.v,
|
---|
652 | 'a' : alpha
|
---|
653 | };
|
---|
654 |
|
---|
655 | };
|
---|
656 |
|
---|
657 | /* Returns the HSL and alpha components of this HSLColour as an object with h,
|
---|
658 | * s, l, and a properties. h is in the range [0,360), s and l are in the range
|
---|
659 | * [0,100], and a is in the range [0,1].
|
---|
660 | */
|
---|
661 | this.getHSL = function(){
|
---|
662 |
|
---|
663 | // return the HSL components
|
---|
664 | return {
|
---|
665 | 'h' : hsl.h,
|
---|
666 | 's' : hsl.s,
|
---|
667 | 'l' : hsl.l,
|
---|
668 | 'a' : alpha
|
---|
669 | };
|
---|
670 |
|
---|
671 | };
|
---|
672 |
|
---|
673 | }
|
---|