2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
8 YUI.add('color-harmony', function (Y, NAME) {
11 Color Harmony provides methods useful for color combination discovery.
14 @submodule color-harmony
23 ANALOGOUS_OFFSET = 10,
25 TETRAD_OFFSET = 360/6,
26 SQUARE_OFFSET = 360/4 ,
37 Returns an Array of two colors. The first color in the Array
38 will be the color passed in. The second will be the
39 complementary color of the color provided
41 @method getComplementary
47 getComplementary: function(str, to) {
48 var c = Harmony._start(str),
51 to = to || Color.findType(str);
54 offsets.push({ h: 180 });
56 return Harmony._adjustOffsetAndFinish(c, offsets, to);
60 Returns an Array of three colors. The first color in the Array
61 will be the color passed in. The second two will be split
66 @param {Number} [offset]
71 getSplit: function(str, offset, to) {
72 var c = Harmony._start(str),
75 offset = offset || SPLIT_OFFSET;
77 to = to || Color.findType(str);
80 offsets.push({ h: 180 + offset });
81 offsets.push({ h: 180 - offset });
83 return Harmony._adjustOffsetAndFinish(c, offsets, to);
87 Returns an Array of five colors. The first color in the Array
88 will be the color passed in. The remaining four will be
89 analogous colors two in either direction from the initially
94 @param {Number} [offset]
99 getAnalogous: function(str, offset, to) {
100 var c = Harmony._start(str),
103 offset = offset || ANALOGOUS_OFFSET;
104 to = to || Color.findType(str);
107 offsets.push({ h: offset });
108 offsets.push({ h: offset * 2 });
109 offsets.push({ h: -offset });
110 offsets.push({ h: -offset * 2 });
112 return Harmony._adjustOffsetAndFinish(c, offsets, to);
116 Returns an Array of three colors. The first color in the Array
117 will be the color passed in. The second two will be equidistant
118 from the start color and each other.
126 getTriad: function(str, to) {
127 var c = Harmony._start(str),
130 to = to || Color.findType(str);
133 offsets.push({ h: TRIAD_OFFSET });
134 offsets.push({ h: -TRIAD_OFFSET });
136 return Harmony._adjustOffsetAndFinish(c, offsets, to);
140 Returns an Array of four colors. The first color in the Array
141 will be the color passed in. The remaining three colors are
142 equidistant offsets from the starting color and each other.
146 @param {Number} [offset]
151 getTetrad: function(str, offset, to) {
152 var c = Harmony._start(str),
155 offset = offset || TETRAD_OFFSET;
156 to = to || Color.findType(str);
159 offsets.push({ h: offset });
160 offsets.push({ h: 180 });
161 offsets.push({ h: 180 + offset });
163 return Harmony._adjustOffsetAndFinish(c, offsets, to);
167 Returns an Array of four colors. The first color in the Array
168 will be the color passed in. The remaining three colors are
169 equidistant offsets from the starting color and each other.
177 getSquare: function(str, to) {
178 var c = Harmony._start(str),
181 to = to || Color.findType(str);
184 offsets.push({ h: SQUARE_OFFSET });
185 offsets.push({ h: SQUARE_OFFSET * 2 });
186 offsets.push({ h: SQUARE_OFFSET * 3 });
188 return Harmony._adjustOffsetAndFinish(c, offsets, to);
192 Calculates lightness offsets resulting in a monochromatic Array
195 @method getMonochrome
197 @param {Number} [count]
202 getMonochrome: function(str, count, to) {
203 var c = Harmony._start(str),
210 count = count || DEF_COUNT;
211 to = to || Color.findType(str);
218 step = 100 / (count - 1);
220 for (; i <= 100; i += step) {
221 _c[2] = Math.max(Math.min(i, 100), 0);
222 colors.push(_c.concat());
227 for (i=0; i<l; i++) {
228 colors[i] = Harmony._finish(colors[i], to);
235 Creates an Array of similar colors. Returned Array is prepended
236 with the color provided followed a number of colors decided
241 @param {Number} [offset]
242 @param {Number} [count]
247 getSimilar: function(str, offset, count, to) {
248 var c = Harmony._start(str),
260 to = to || Color.findType(str);
261 count = count || DEF_COUNT;
262 offset = offset || DEF_OFFSET;
264 slOffset = (offset > 100) ? 100 : offset;
265 sMin = Math.max(0, s - slOffset);
266 sMax = Math.min(100, s + slOffset);
267 lMin = Math.max(0, l - slOffset);
268 lMax = Math.min(100, l + slOffset);
271 for (i = 0; i < count; i++) {
272 sRand = ( Math.round( (Math.random() * (sMax - sMin)) + sMin ) );
273 lRand = ( Math.round( (Math.random() * (lMax - lMin)) + lMin ) );
276 h: ( Math.random() * (offset * 2)) - offset,
277 // because getOffset adjusts from the existing color, we
278 // need to adjust it negatively to get a good number for
279 // saturation and luminance, otherwise we get a lot of white
285 return Harmony._adjustOffsetAndFinish(c, offsets, to);
289 Adjusts the provided color by the offset(s) given. You may
290 adjust hue, saturation, and/or luminance in one step.
294 @param {Object} adjust
295 @param {Number} [adjust.h]
296 @param {Number} [adjust.s]
297 @param {Number} [adjust.l]
302 getOffset: function(str, adjust, to) {
303 var started = Y.Lang.isArray(str),
308 hsla = Harmony._start(str);
309 type = Color.findType(str);
318 hsla[0] = ((+hsla[0]) + adjust.h) % 360;
322 hsla[1] = Math.max(Math.min((+hsla[1]) + adjust.s, 100), 0);
326 hsla[2] = Math.max(Math.min((+hsla[2]) + adjust.l, 100), 0);
330 return Harmony._finish(hsla, to);
337 Returns 0 - 100 percentage of brightness from `0` (black) being the
338 darkest to `100` (white) being the brightest.
340 @method getBrightness
345 getBrightness: function(str) {
346 var c = Color.toArray(Color._convertTo(str, RGB)),
350 weights = Y.Color._brightnessWeights;
353 return Math.round(Math.sqrt(
354 (r * r * weights.r) +
355 (g * g * weights.g) +
361 Returns a new color value with adjusted luminance so that the
362 brightness of the return color matches the perceived brightness
363 of the `match` color provided.
365 @method getSimilarBrightness
367 @param {String} match
372 getSimilarBrightness: function(str, match, to){
373 var c = Color.toArray(Color._convertTo(str, HSL)),
374 b = Harmony.getBrightness(match);
376 to = to || Color.findType(str);
378 if (to === 'keyword') {
382 c[2] = Harmony._searchLuminanceForBrightness(c, b, 0, 100);
384 str = Color.fromArray(c, Y.Color.TYPES.HSLA);
386 return Color._convertTo(str, to);
389 //--------------------
391 //--------------------
393 Converts the provided color from additive to subtractive returning
394 an Array of HSLA values
401 _start: function(str) {
402 var hsla = Color.toArray(Color._convertTo(str, HSL));
403 hsla[0] = Harmony._toSubtractive(hsla[0]);
409 Converts the provided HSLA values from subtractive to additive
410 returning a converted color string
418 _finish: function(hsla, to) {
419 hsla[0] = Harmony._toAdditive(hsla[0]);
420 hsla = 'hsla(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%, ' + hsla[3] + ')';
422 if (to === 'keyword') {
426 return Color._convertTo(hsla, to);
430 Adjusts the hue degree from subtractive to additive
434 @return {Number} Converted additive hue
437 _toAdditive: function(hue) {
438 hue = Y.Color._constrainHue(hue);
442 } else if (hue < 240) {
443 hue = 120 + (hue - 180) * 2;
446 return Y.Color._constrainHue(hue, 10);
450 Adjusts the hue degree from additive to subtractive
452 @method _toSubtractive
454 @return {Number} Converted subtractive hue
457 _toSubtractive: function(hue) {
458 hue = Y.Color._constrainHue(hue);
462 } else if (hue < 240) {
463 hue = 180 + (hue - 120) / 2;
466 return Y.Color._constrainHue(hue, 10);
470 Contrain the hue to a value between 0 and 360 for calculations
471 and real color wheel value space. Provide a precision value
472 to round return value to a decimal place
474 @method _constrainHue
476 @param {Number} [precision]
477 @return {Number} Constrained hue value
480 _constrainHue: function(hue, precision) {
487 hue = Math.round(hue * precision) / precision;
494 Brightness weight factors for perceived brightness calculations
496 "standard" values are listed as R: 0.241, G: 0.691, B: 0.068
497 These values were changed based on grey scale comparison of hsl
498 to new hsl where brightness is said to be within plus or minus 0.01.
500 @property _brightnessWeights
503 _brightnessWeights: {
510 Calculates the luminance as a mid range between the min and max
511 to match the brightness level provided
513 @method _searchLuminanceForBrightness
514 @param {Array} color HSLA values
515 @param {Number} brightness Brightness to be matched
516 @param {Number} min Minimum range for luminance
517 @param {Number} max Maximum range for luminance
518 @return {Number} Found luminance to achieve requested brightness
521 _searchLuminanceForBrightness: function(color, brightness, min, max) {
522 var luminance = (max + min) / 2,
525 color[2] = luminance;
526 b = Harmony.getBrightness(Color.fromArray(color, Y.Color.TYPES.HSL));
528 if (b + 2 > brightness && b - 2 < brightness) {
530 } else if (b > brightness) {
531 return Harmony._searchLuminanceForBrightness(color, brightness, min, luminance);
533 return Harmony._searchLuminanceForBrightness(color, brightness, luminance, max);
538 Takes an HSL array, and an array of offsets and returns and array
539 of colors that have been adjusted. The returned colors will
540 match the array of offsets provided. If you wish you have the
541 same color value returned, you can provide null or an empty
542 object to the offsets. The returned array will contain color
543 value strings that have been adjusted from subtractive to
546 @method _adjustOffsetAndFinish
548 @param {Array} offsets
553 _adjustOffsetAndFinish: function(color, offsets, to) {
559 for (i = 0; i < l; i++ ) {
562 _c = Harmony.getOffset(_c, offsets[i]);
564 colors.push(Harmony._finish(_c, to));
572 Y.Color = Y.mix(Y.Color, Harmony);
575 }, '3.13.0', {"requires": ["color-hsl"]});