Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('color-harmony', function (Y, NAME) {
2
 
3
/**
4
Color Harmony provides methods useful for color combination discovery.
5
 
6
@module color
7
@submodule color-harmony
8
@class Harmony
9
@namespace Color
10
@since 3.8.0
11
*/
12
var HSL = 'hsl',
13
    RGB = 'rgb',
14
 
15
    SPLIT_OFFSET = 30,
16
    ANALOGOUS_OFFSET = 10,
17
    TRIAD_OFFSET = 360/3,
18
    TETRAD_OFFSET = 360/6,
19
    SQUARE_OFFSET = 360/4 ,
20
 
21
    DEF_COUNT = 5,
22
    DEF_OFFSET = 10,
23
 
24
    Color = Y.Color,
25
 
26
    Harmony = {
27
 
28
        // Color Groups
29
        /**
30
        Returns an Array of two colors. The first color in the Array
31
          will be the color passed in. The second will be the
32
          complementary color of the color provided
33
        @public
34
        @method getComplementary
35
        @param {String} str
36
        @param {String} [to]
37
        @return {Array}
38
        @since 3.8.0
39
        **/
40
        getComplementary: function(str, to) {
41
            var c = Harmony._start(str),
42
                offsets = [];
43
 
44
            to = to || Color.findType(str);
45
 
46
            offsets.push({});
47
            offsets.push({ h: 180 });
48
 
49
            return Harmony._adjustOffsetAndFinish(c, offsets, to);
50
        },
51
 
52
        /**
53
        Returns an Array of three colors. The first color in the Array
54
          will be the color passed in. The second two will be split
55
          complementary colors.
56
        @public
57
        @method getSplit
58
        @param {String} str
59
        @param {Number} [offset]
60
        @param {String} [to]
61
        @return {String}
62
        @since 3.8.0
63
        **/
64
        getSplit: function(str, offset, to) {
65
            var c = Harmony._start(str),
66
                offsets = [];
67
 
68
            offset = offset || SPLIT_OFFSET;
69
 
70
            to = to || Color.findType(str);
71
 
72
            offsets.push({});
73
            offsets.push({ h: 180 + offset });
74
            offsets.push({ h: 180 - offset });
75
 
76
            return Harmony._adjustOffsetAndFinish(c, offsets, to);
77
        },
78
 
79
        /**
80
        Returns an Array of five colors. The first color in the Array
81
          will be the color passed in. The remaining four will be
82
          analogous colors two in either direction from the initially
83
          provided color.
84
        @public
85
        @method getAnalogous
86
        @param {String} str
87
        @param {Number} [offset]
88
        @param {String} [to]
89
        @return {String}
90
        @since 3.8.0
91
        **/
92
        getAnalogous: function(str, offset, to) {
93
            var c = Harmony._start(str),
94
                offsets = [];
95
 
96
            offset = offset || ANALOGOUS_OFFSET;
97
            to = to || Color.findType(str);
98
 
99
            offsets.push({});
100
            offsets.push({ h: offset });
101
            offsets.push({ h: offset * 2 });
102
            offsets.push({ h: -offset });
103
            offsets.push({ h: -offset * 2 });
104
 
105
            return Harmony._adjustOffsetAndFinish(c, offsets, to);
106
        },
107
 
108
        /**
109
        Returns an Array of three colors. The first color in the Array
110
          will be the color passed in. The second two will be equidistant
111
          from the start color and each other.
112
        @public
113
        @method getTriad
114
        @param {String} str
115
        @param {String} [to]
116
        @return {String}
117
        @since 3.8.0
118
        **/
119
        getTriad: function(str, to) {
120
            var c = Harmony._start(str),
121
                offsets = [];
122
 
123
            to = to || Color.findType(str);
124
 
125
            offsets.push({});
126
            offsets.push({ h: TRIAD_OFFSET });
127
            offsets.push({ h: -TRIAD_OFFSET });
128
 
129
            return Harmony._adjustOffsetAndFinish(c, offsets, to);
130
        },
131
 
132
        /**
133
        Returns an Array of four colors. The first color in the Array
134
          will be the color passed in. The remaining three colors are
135
          equidistant offsets from the starting color and each other.
136
        @public
137
        @method getTetrad
138
        @param {String} str
139
        @param {Number} [offset]
140
        @param {String} [to]
141
        @return {String}
142
        @since 3.8.0
143
        **/
144
        getTetrad: function(str, offset, to) {
145
            var c = Harmony._start(str),
146
                offsets = [];
147
 
148
            offset = offset || TETRAD_OFFSET;
149
            to = to || Color.findType(str);
150
 
151
            offsets.push({});
152
            offsets.push({ h: offset });
153
            offsets.push({ h: 180 });
154
            offsets.push({ h: 180 + offset });
155
 
156
            return Harmony._adjustOffsetAndFinish(c, offsets, to);
157
        },
158
 
159
        /**
160
        Returns an Array of four colors. The first color in the Array
161
          will be the color passed in. The remaining three colors are
162
          equidistant offsets from the starting color and each other.
163
        @public
164
        @method getSquare
165
        @param {String} str
166
        @param {String} [to]
167
        @return {String}
168
        @since 3.8.0
169
        **/
170
        getSquare: function(str, to) {
171
            var c = Harmony._start(str),
172
                offsets = [];
173
 
174
            to = to || Color.findType(str);
175
 
176
            offsets.push({});
177
            offsets.push({ h: SQUARE_OFFSET });
178
            offsets.push({ h: SQUARE_OFFSET * 2 });
179
            offsets.push({ h: SQUARE_OFFSET * 3 });
180
 
181
            return Harmony._adjustOffsetAndFinish(c, offsets, to);
182
        },
183
 
184
        /**
185
        Calculates lightness offsets resulting in a monochromatic Array
186
          of values.
187
        @public
188
        @method getMonochrome
189
        @param {String} str
190
        @param {Number} [count]
191
        @param {String} [to]
192
        @return {String}
193
        @since 3.8.0
194
        **/
195
        getMonochrome: function(str, count, to) {
196
            var c = Harmony._start(str),
197
                colors = [],
198
                i = 0,
199
                l,
200
                step,
201
                _c = c.concat();
202
 
203
            count = count || DEF_COUNT;
204
            to = to || Color.findType(str);
205
 
206
 
207
            if (count < 2) {
208
                return str;
209
            }
210
 
211
            step = 100 / (count - 1);
212
 
213
            for (; i <= 100; i += step) {
214
                _c[2] = Math.max(Math.min(i, 100), 0);
215
                colors.push(_c.concat());
216
            }
217
 
218
            l = colors.length;
219
 
220
            for (i=0; i<l; i++) {
221
                colors[i] = Harmony._finish(colors[i], to);
222
            }
223
 
224
            return colors;
225
        },
226
 
227
        /**
228
        Creates an Array of similar colors. Returned Array is prepended
229
           with the color provided followed a number of colors decided
230
           by count
231
        @public
232
        @method getSimilar
233
        @param {String} str
234
        @param {Number} [offset]
235
        @param {Number} [count]
236
        @param {String} [to]
237
        @return {String}
238
        @since 3.8.0
239
        **/
240
        getSimilar: function(str, offset, count, to) {
241
            var c = Harmony._start(str),
242
                offsets = [],
243
                slOffset,
244
                s = +(c[1]),
245
                sMin,
246
                sMax,
247
                sRand,
248
                l = +(c[2]),
249
                lMin,
250
                lMax,
251
                lRand;
252
 
253
            to = to || Color.findType(str);
254
            count = count || DEF_COUNT;
255
            offset = offset || DEF_OFFSET;
256
 
257
            slOffset = (offset > 100) ? 100 : offset;
258
            sMin = Math.max(0,   s - slOffset);
259
            sMax = Math.min(100, s + slOffset);
260
            lMin = Math.max(0,   l - slOffset);
261
            lMax = Math.min(100, l + slOffset);
262
 
263
            offsets.push({});
264
            for (i = 0; i < count; i++) {
265
                sRand = ( Math.round( (Math.random() * (sMax - sMin)) + sMin ) );
266
                lRand = ( Math.round( (Math.random() * (lMax - lMin)) + lMin ) );
267
 
268
                offsets.push({
269
                    h: ( Math.random() * (offset * 2)) - offset,
270
                    // because getOffset adjusts from the existing color, we
271
                    // need to adjust it negatively to get a good number for
272
                    // saturation and luminance, otherwise we get a lot of white
273
                    s: -(s - sRand),
274
                    l: -(l - lRand)
275
                });
276
            }
277
 
278
            return Harmony._adjustOffsetAndFinish(c, offsets, to);
279
        },
280
 
281
        /**
282
        Adjusts the provided color by the offset(s) given. You may
283
          adjust hue, saturation, and/or luminance in one step.
284
        @public
285
        @method getOffset
286
        @param {String} str
287
        @param {Object} adjust
288
          @param {Number} [adjust.h]
289
          @param {Number} [adjust.s]
290
          @param {Number} [adjust.l]
291
        @param {String} [to]
292
        @return {String}
293
        @since 3.8.0
294
        **/
295
        getOffset: function(str, adjust, to) {
296
            var started = Y.Lang.isArray(str),
297
                hsla,
298
                type;
299
 
300
            if (!started) {
301
                hsla = Harmony._start(str);
302
                type = Color.findType(str);
303
            } else {
304
                hsla = str;
305
                type = 'hsl';
306
            }
307
 
308
            to = to || type;
309
 
310
            if (adjust.h) {
311
                hsla[0] = ((+hsla[0]) + adjust.h) % 360;
312
            }
313
 
314
            if (adjust.s) {
315
                hsla[1] = Math.max(Math.min((+hsla[1]) + adjust.s, 100), 0);
316
            }
317
 
318
            if (adjust.l) {
319
                hsla[2] = Math.max(Math.min((+hsla[2]) + adjust.l, 100), 0);
320
            }
321
 
322
            if (!started) {
323
                return Harmony._finish(hsla, to);
324
            }
325
 
326
            return hsla;
327
        },
328
 
329
        /**
330
        Returns 0 - 100 percentage of brightness from `0` (black) being the
331
          darkest to `100` (white) being the brightest.
332
        @public
333
        @method getBrightness
334
        @param {String} str
335
        @return {Number}
336
        @since 3.8.0
337
        **/
338
        getBrightness: function(str) {
339
            var c = Color.toArray(Color._convertTo(str, RGB)),
340
                r = c[0],
341
                g = c[1],
342
                b = c[2],
343
                weights = Y.Color._brightnessWeights;
344
 
345
 
346
            return Math.round(Math.sqrt(
347
                (r * r * weights.r) +
348
                (g * g * weights.g) +
349
                (b * b * weights.b)
350
            ) / 255 * 100);
351
        },
352
 
353
        /**
354
        Returns a new color value with adjusted luminance so that the
355
          brightness of the return color matches the perceived brightness
356
          of the `match` color provided.
357
        @public
358
        @method getSimilarBrightness
359
        @param {String} str
360
        @param {String} match
361
        @param {String} [to]
362
        @return {String}
363
        @since 3.8.0
364
        **/
365
        getSimilarBrightness: function(str, match, to){
366
            var c = Color.toArray(Color._convertTo(str, HSL)),
367
                b = Harmony.getBrightness(match);
368
 
369
            to = to || Color.findType(str);
370
 
371
            if (to === 'keyword') {
372
                to = 'hex';
373
            }
374
 
375
            c[2] = Harmony._searchLuminanceForBrightness(c, b, 0, 100);
376
 
377
            str = Color.fromArray(c, Y.Color.TYPES.HSLA);
378
 
379
            return Color._convertTo(str, to);
380
        },
381
 
382
        //--------------------
383
        // PRIVATE
384
        //--------------------
385
        /**
386
        Converts the provided color from additive to subtractive returning
387
          an Array of HSLA values
388
        @private
389
        @method _start
390
        @param {String} str
391
        @return {Array}
392
        @since 3.8.0
393
        */
394
        _start: function(str) {
395
            var hsla = Color.toArray(Color._convertTo(str, HSL));
396
            hsla[0] = Harmony._toSubtractive(hsla[0]);
397
 
398
            return hsla;
399
        },
400
 
401
        /**
402
        Converts the provided HSLA values from subtractive to additive
403
          returning a converted color string
404
        @private
405
        @method _finish
406
        @param {Array} hsla
407
        @param {String} [to]
408
        @return {String}
409
        @since 3.8.0
410
        */
411
        _finish: function(hsla, to) {
412
            hsla[0] = Harmony._toAdditive(hsla[0]);
413
            hsla = 'hsla(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%, ' + hsla[3] + ')';
414
 
415
            if (to === 'keyword') {
416
                to = 'hex';
417
            }
418
 
419
            return Color._convertTo(hsla, to);
420
        },
421
 
422
        /**
423
        Adjusts the hue degree from subtractive to additive
424
        @private
425
        @method _toAdditive
426
        @param {Number} hue
427
        @return {Number} Converted additive hue
428
        @since 3.8.0
429
        */
430
        _toAdditive: function(hue) {
431
            hue = Y.Color._constrainHue(hue);
432
 
433
            if (hue <= 180) {
434
                hue /= 1.5;
435
            } else if (hue < 240) {
436
                hue = 120 + (hue - 180) * 2;
437
            }
438
 
439
            return Y.Color._constrainHue(hue, 10);
440
        },
441
 
442
        /**
443
        Adjusts the hue degree from additive to subtractive
444
        @private
445
        @method _toSubtractive
446
        @param {Number} hue
447
        @return {Number} Converted subtractive hue
448
        @since 3.8.0
449
        */
450
        _toSubtractive: function(hue) {
451
            hue = Y.Color._constrainHue(hue);
452
 
453
            if (hue <= 120) {
454
                hue *= 1.5;
455
            } else if (hue < 240) {
456
                hue = 180 + (hue - 120) / 2;
457
            }
458
 
459
            return Y.Color._constrainHue(hue, 10);
460
        },
461
 
462
        /**
463
        Contrain the hue to a value between 0 and 360 for calculations
464
            and real color wheel value space. Provide a precision value
465
            to round return value to a decimal place
466
        @private
467
        @method _constrainHue
468
        @param {Number} hue
469
        @param {Number} [precision]
470
        @return {Number} Constrained hue value
471
        @since 3.8.0
472
        **/
473
        _constrainHue: function(hue, precision) {
474
            while (hue < 0) {
475
                hue += 360;
476
            }
477
            hue %= 360;
478
 
479
            if (precision) {
480
                hue = Math.round(hue * precision) / precision;
481
            }
482
 
483
            return hue;
484
        },
485
 
486
        /**
487
        Brightness weight factors for perceived brightness calculations
488
 
489
        "standard" values are listed as R: 0.241, G: 0.691, B: 0.068
490
        These values were changed based on grey scale comparison of hsl
491
          to new hsl where brightness is said to be within plus or minus 0.01.
492
        @private
493
        @property _brightnessWeights
494
        @since 3.8.0
495
        */
496
        _brightnessWeights: {
497
            r: 0.221,
498
            g: 0.711,
499
            b: 0.068
500
        },
501
 
502
        /**
503
        Calculates the luminance as a mid range between the min and max
504
          to match the brightness level provided
505
        @private
506
        @method _searchLuminanceForBrightness
507
        @param {Array} color HSLA values
508
        @param {Number} brightness Brightness to be matched
509
        @param {Number} min Minimum range for luminance
510
        @param {Number} max Maximum range for luminance
511
        @return {Number} Found luminance to achieve requested brightness
512
        @since 3.8.0
513
        **/
514
        _searchLuminanceForBrightness: function(color, brightness, min, max) {
515
            var luminance = (max + min) / 2,
516
                b;
517
 
518
            color[2] = luminance;
519
            b = Harmony.getBrightness(Color.fromArray(color, Y.Color.TYPES.HSL));
520
 
521
            if (b + 2 > brightness && b - 2 < brightness) {
522
                return luminance;
523
            } else if (b > brightness) {
524
                return Harmony._searchLuminanceForBrightness(color, brightness, min, luminance);
525
            } else {
526
                return Harmony._searchLuminanceForBrightness(color, brightness, luminance, max);
527
            }
528
        },
529
 
530
        /**
531
        Takes an HSL array, and an array of offsets and returns and array
532
            of colors that have been adjusted. The returned colors will
533
            match the array of offsets provided. If you wish you have the
534
            same color value returned, you can provide null or an empty
535
            object to the offsets. The returned array will contain color
536
            value strings that have been adjusted from subtractive to
537
            additive.
538
        @private
539
        @method _adjustOffsetAndFinish
540
        @param {Array} color
541
        @param {Array} offsets
542
        @param {String} to
543
        @return {Array}
544
        @since 3.8.0
545
        **/
546
        _adjustOffsetAndFinish: function(color, offsets, to) {
547
            var colors = [],
548
                i,
549
                l = offsets.length,
550
                _c;
551
 
552
            for (i = 0; i < l; i++ ) {
553
                _c = color.concat();
554
                if (offsets[i]) {
555
                    _c = Harmony.getOffset(_c, offsets[i]);
556
                }
557
                colors.push(Harmony._finish(_c, to));
558
            }
559
 
560
            return colors;
561
        }
562
 
563
    };
564
 
565
Y.Color = Y.mix(Y.Color, Harmony);
566
 
567
 
568
}, '3.18.1', {"requires": ["color-hsl"]});