spectrum-rails 1.3.1 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/spectrum-rails/version.rb +1 -1
- data/vendor/assets/javascripts/spectrum.js +1030 -996
- data/vendor/assets/stylesheets/spectrum.css +44 -44
- metadata +2 -2
|
@@ -1,115 +1,120 @@
|
|
|
1
|
-
// Spectrum Colorpicker v1.3.
|
|
1
|
+
// Spectrum Colorpicker v1.3.4
|
|
2
2
|
// https://github.com/bgrins/spectrum
|
|
3
3
|
// Author: Brian Grinstead
|
|
4
4
|
// License: MIT
|
|
5
5
|
|
|
6
6
|
(function (window, $, undefined) {
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
7
9
|
var defaultOpts = {
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
11
|
+
// Callbacks
|
|
12
|
+
beforeShow: noop,
|
|
13
|
+
move: noop,
|
|
14
|
+
change: noop,
|
|
15
|
+
show: noop,
|
|
16
|
+
hide: noop,
|
|
17
|
+
|
|
18
|
+
// Options
|
|
19
|
+
color: false,
|
|
20
|
+
flat: false,
|
|
21
|
+
showInput: false,
|
|
22
|
+
allowEmpty: false,
|
|
23
|
+
showButtons: true,
|
|
24
|
+
clickoutFiresChange: false,
|
|
25
|
+
showInitial: false,
|
|
26
|
+
showPalette: false,
|
|
27
|
+
showPaletteOnly: false,
|
|
28
|
+
showSelectionPalette: true,
|
|
29
|
+
localStorageKey: false,
|
|
30
|
+
appendTo: "body",
|
|
31
|
+
maxSelectionSize: 7,
|
|
32
|
+
cancelText: "cancel",
|
|
33
|
+
chooseText: "choose",
|
|
34
|
+
clearText: "Clear Color Selection",
|
|
35
|
+
noColorSelectedText: "No Color Selected",
|
|
36
|
+
preferredFormat: false,
|
|
37
|
+
className: "", // Deprecated - use containerClassName and replacerClassName instead.
|
|
38
|
+
containerClassName: "",
|
|
39
|
+
replacerClassName: "",
|
|
40
|
+
showAlpha: false,
|
|
41
|
+
theme: "sp-light",
|
|
42
|
+
palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
|
|
43
|
+
selectionPalette: [],
|
|
44
|
+
disabled: false
|
|
45
|
+
},
|
|
46
|
+
spectrums = [],
|
|
47
|
+
IE = !!/msie/i.exec( window.navigator.userAgent ),
|
|
48
|
+
rgbaSupport = (function() {
|
|
49
|
+
function contains( str, substr ) {
|
|
50
|
+
return !!~('' + str).indexOf(substr);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
var elem = document.createElement('div');
|
|
54
|
+
var style = elem.style;
|
|
55
|
+
style.cssText = 'background-color:rgba(0,0,0,.5)';
|
|
56
|
+
return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
|
|
57
|
+
})(),
|
|
58
|
+
inputTypeColorSupport = (function() {
|
|
59
|
+
var colorInput = $("<input type='color' value='!' />")[0];
|
|
60
|
+
return colorInput.type === "color" && colorInput.value !== "!";
|
|
61
|
+
})(),
|
|
62
|
+
replaceInput = [
|
|
63
|
+
"<div class='sp-replacer'>",
|
|
59
64
|
"<div class='sp-preview'><div class='sp-preview-inner'></div></div>",
|
|
60
65
|
"<div class='sp-dd'>▼</div>",
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
"</div>"
|
|
67
|
+
].join(''),
|
|
68
|
+
markup = (function () {
|
|
64
69
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
70
|
+
// IE does not support gradients with multiple stops, so we need to simulate
|
|
71
|
+
// that for the rainbow slider with 8 divs that each have a single gradient
|
|
72
|
+
var gradientFix = "";
|
|
73
|
+
if (IE) {
|
|
74
|
+
for (var i = 1; i <= 6; i++) {
|
|
75
|
+
gradientFix += "<div class='sp-" + i + "'></div>";
|
|
72
76
|
}
|
|
77
|
+
}
|
|
73
78
|
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
return [
|
|
80
|
+
"<div class='sp-container sp-hidden'>",
|
|
76
81
|
"<div class='sp-palette-container'>",
|
|
77
|
-
|
|
82
|
+
"<div class='sp-palette sp-thumb sp-cf'></div>",
|
|
78
83
|
"</div>",
|
|
79
84
|
"<div class='sp-picker-container'>",
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
"<div class='sp-top sp-cf'>",
|
|
86
|
+
"<div class='sp-fill'></div>",
|
|
87
|
+
"<div class='sp-top-inner'>",
|
|
88
|
+
"<div class='sp-color'>",
|
|
89
|
+
"<div class='sp-sat'>",
|
|
90
|
+
"<div class='sp-val'>",
|
|
91
|
+
"<div class='sp-dragger'></div>",
|
|
92
|
+
"</div>",
|
|
93
|
+
"</div>",
|
|
94
|
+
"</div>",
|
|
95
|
+
"<div class='sp-clear sp-clear-display'>",
|
|
96
|
+
"</div>",
|
|
97
|
+
"<div class='sp-hue'>",
|
|
98
|
+
"<div class='sp-slider'></div>",
|
|
99
|
+
gradientFix,
|
|
100
|
+
"</div>",
|
|
101
|
+
"</div>",
|
|
102
|
+
"<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
|
|
103
|
+
"</div>",
|
|
104
|
+
"<div class='sp-input-container sp-cf'>",
|
|
105
|
+
"<input class='sp-input' type='text' spellcheck='false' />",
|
|
106
|
+
"</div>",
|
|
107
|
+
"<div class='sp-initial sp-thumb sp-cf'></div>",
|
|
108
|
+
"<div class='sp-button-container sp-cf'>",
|
|
109
|
+
"<a class='sp-cancel' href='#'></a>",
|
|
110
|
+
"<button type='button' class='sp-choose'></button>",
|
|
111
|
+
"</div>",
|
|
89
112
|
"</div>",
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"<div class='sp-slider'></div>",
|
|
94
|
-
gradientFix,
|
|
95
|
-
"</div>",
|
|
96
|
-
"</div>",
|
|
97
|
-
"<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
|
|
98
|
-
"</div>",
|
|
99
|
-
"<div class='sp-input-container sp-cf'>",
|
|
100
|
-
"<input class='sp-input' type='text' spellcheck='false' />",
|
|
101
|
-
"</div>",
|
|
102
|
-
"<div class='sp-initial sp-thumb sp-cf'></div>",
|
|
103
|
-
"<div class='sp-button-container sp-cf'>",
|
|
104
|
-
"<a class='sp-cancel' href='#'></a>",
|
|
105
|
-
"<button class='sp-choose'></button>",
|
|
106
|
-
"</div>",
|
|
107
|
-
"</div>",
|
|
108
|
-
"</div>"
|
|
109
|
-
].join("");
|
|
110
|
-
})();
|
|
113
|
+
"</div>"
|
|
114
|
+
].join("");
|
|
115
|
+
})();
|
|
111
116
|
|
|
112
|
-
function paletteTemplate (p, color, className) {
|
|
117
|
+
function paletteTemplate (p, color, className, opts) {
|
|
113
118
|
var html = [];
|
|
114
119
|
for (var i = 0; i < p.length; i++) {
|
|
115
120
|
var current = p[i];
|
|
@@ -117,12 +122,17 @@
|
|
|
117
122
|
var tiny = tinycolor(current);
|
|
118
123
|
var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
|
|
119
124
|
c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
|
|
120
|
-
|
|
125
|
+
var formattedString = tiny.toString(opts.preferredFormat || "rgb");
|
|
121
126
|
var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
|
|
122
|
-
html.push('<span title="' +
|
|
127
|
+
html.push('<span title="' + formattedString + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';" /></span>');
|
|
123
128
|
} else {
|
|
124
129
|
var cls = 'sp-clear-display';
|
|
125
|
-
html.push('<
|
|
130
|
+
html.push($('<div />')
|
|
131
|
+
.append($('<span data-color="" style="background-color:transparent;" class="' + cls + '"></span>')
|
|
132
|
+
.attr('title', opts.noColorSelectedText)
|
|
133
|
+
)
|
|
134
|
+
.html()
|
|
135
|
+
);
|
|
126
136
|
}
|
|
127
137
|
}
|
|
128
138
|
return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>";
|
|
@@ -173,6 +183,7 @@
|
|
|
173
183
|
currentAlpha = 1,
|
|
174
184
|
palette = [],
|
|
175
185
|
paletteArray = [],
|
|
186
|
+
paletteLookup = {},
|
|
176
187
|
selectionPalette = opts.selectionPalette.slice(0),
|
|
177
188
|
maxSelectionSize = opts.maxSelectionSize,
|
|
178
189
|
draggingClass = "sp-dragging",
|
|
@@ -199,7 +210,7 @@
|
|
|
199
210
|
isInput = boundElement.is("input"),
|
|
200
211
|
isInputTypeColor = isInput && inputTypeColorSupport && boundElement.attr("type") === "color",
|
|
201
212
|
shouldReplace = isInput && !flat,
|
|
202
|
-
replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className) : $([]),
|
|
213
|
+
replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),
|
|
203
214
|
offsetElement = (shouldReplace) ? replacer : boundElement,
|
|
204
215
|
previewElement = replacer.find(".sp-preview-inner"),
|
|
205
216
|
initialColor = opts.color || (isInput && boundElement.val()),
|
|
@@ -219,6 +230,13 @@
|
|
|
219
230
|
if (opts.palette) {
|
|
220
231
|
palette = opts.palette.slice(0);
|
|
221
232
|
paletteArray = $.isArray(palette[0]) ? palette : [palette];
|
|
233
|
+
paletteLookup = {};
|
|
234
|
+
for (var i = 0; i < paletteArray.length; i++) {
|
|
235
|
+
for (var j = 0; j < paletteArray[i].length; j++) {
|
|
236
|
+
var rgb = tinycolor(paletteArray[i][j]).toRgbString();
|
|
237
|
+
paletteLookup[rgb] = true;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
222
240
|
}
|
|
223
241
|
|
|
224
242
|
container.toggleClass("sp-flat", flat);
|
|
@@ -229,7 +247,7 @@
|
|
|
229
247
|
container.toggleClass("sp-palette-disabled", !opts.showPalette);
|
|
230
248
|
container.toggleClass("sp-palette-only", opts.showPaletteOnly);
|
|
231
249
|
container.toggleClass("sp-initial-disabled", !opts.showInitial);
|
|
232
|
-
container.addClass(opts.className);
|
|
250
|
+
container.addClass(opts.className).addClass(opts.containerClassName);
|
|
233
251
|
|
|
234
252
|
reflow();
|
|
235
253
|
}
|
|
@@ -263,25 +281,7 @@
|
|
|
263
281
|
appendTo.append(container);
|
|
264
282
|
}
|
|
265
283
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
// Migrate old palettes over to new format. May want to remove this eventually.
|
|
269
|
-
try {
|
|
270
|
-
var oldPalette = window.localStorage[localStorageKey].split(",#");
|
|
271
|
-
if (oldPalette.length > 1) {
|
|
272
|
-
delete window.localStorage[localStorageKey];
|
|
273
|
-
$.each(oldPalette, function(i, c) {
|
|
274
|
-
addColorToSelectionPalette(c);
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
catch(e) { }
|
|
279
|
-
|
|
280
|
-
try {
|
|
281
|
-
selectionPalette = window.localStorage[localStorageKey].split(";");
|
|
282
|
-
}
|
|
283
|
-
catch (e) { }
|
|
284
|
-
}
|
|
284
|
+
updateSelectionPaletteFromStorage();
|
|
285
285
|
|
|
286
286
|
offsetElement.bind("click.spectrum touchstart.spectrum", function (e) {
|
|
287
287
|
if (!disabled) {
|
|
@@ -412,11 +412,11 @@
|
|
|
412
412
|
|
|
413
413
|
function palletElementClick(e) {
|
|
414
414
|
if (e.data && e.data.ignore) {
|
|
415
|
-
set($(
|
|
415
|
+
set($(e.target).data("color"));
|
|
416
416
|
move();
|
|
417
417
|
}
|
|
418
418
|
else {
|
|
419
|
-
set($(
|
|
419
|
+
set($(e.target).data("color"));
|
|
420
420
|
move();
|
|
421
421
|
updateOriginalInput(true);
|
|
422
422
|
hide();
|
|
@@ -430,11 +430,34 @@
|
|
|
430
430
|
initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, { ignore: true }, palletElementClick);
|
|
431
431
|
}
|
|
432
432
|
|
|
433
|
+
function updateSelectionPaletteFromStorage() {
|
|
434
|
+
|
|
435
|
+
if (localStorageKey && window.localStorage) {
|
|
436
|
+
|
|
437
|
+
// Migrate old palettes over to new format. May want to remove this eventually.
|
|
438
|
+
try {
|
|
439
|
+
var oldPalette = window.localStorage[localStorageKey].split(",#");
|
|
440
|
+
if (oldPalette.length > 1) {
|
|
441
|
+
delete window.localStorage[localStorageKey];
|
|
442
|
+
$.each(oldPalette, function(i, c) {
|
|
443
|
+
addColorToSelectionPalette(c);
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
catch(e) { }
|
|
448
|
+
|
|
449
|
+
try {
|
|
450
|
+
selectionPalette = window.localStorage[localStorageKey].split(";");
|
|
451
|
+
}
|
|
452
|
+
catch (e) { }
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
433
456
|
function addColorToSelectionPalette(color) {
|
|
434
457
|
if (showSelectionPalette) {
|
|
435
|
-
var
|
|
436
|
-
if ($.inArray(
|
|
437
|
-
selectionPalette.push(
|
|
458
|
+
var rgb = tinycolor(color).toRgbString();
|
|
459
|
+
if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
|
|
460
|
+
selectionPalette.push(rgb);
|
|
438
461
|
while(selectionPalette.length > maxSelectionSize) {
|
|
439
462
|
selectionPalette.shift();
|
|
440
463
|
}
|
|
@@ -451,25 +474,12 @@
|
|
|
451
474
|
|
|
452
475
|
function getUniqueSelectionPalette() {
|
|
453
476
|
var unique = [];
|
|
454
|
-
var p = selectionPalette;
|
|
455
|
-
var paletteLookup = {};
|
|
456
|
-
var rgb;
|
|
457
|
-
|
|
458
477
|
if (opts.showPalette) {
|
|
478
|
+
for (var i = 0; i < selectionPalette.length; i++) {
|
|
479
|
+
var rgb = tinycolor(selectionPalette[i]).toRgbString();
|
|
459
480
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
rgb = tinycolor(paletteArray[i][j]).toRgbString();
|
|
463
|
-
paletteLookup[rgb] = true;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
for (i = 0; i < p.length; i++) {
|
|
468
|
-
rgb = tinycolor(p[i]).toRgbString();
|
|
469
|
-
|
|
470
|
-
if (!paletteLookup.hasOwnProperty(rgb)) {
|
|
471
|
-
unique.push(p[i]);
|
|
472
|
-
paletteLookup[rgb] = true;
|
|
481
|
+
if (!paletteLookup[rgb]) {
|
|
482
|
+
unique.push(selectionPalette[i]);
|
|
473
483
|
}
|
|
474
484
|
}
|
|
475
485
|
}
|
|
@@ -482,11 +492,13 @@
|
|
|
482
492
|
var currentColor = get();
|
|
483
493
|
|
|
484
494
|
var html = $.map(paletteArray, function (palette, i) {
|
|
485
|
-
return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i);
|
|
495
|
+
return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts);
|
|
486
496
|
});
|
|
487
497
|
|
|
498
|
+
updateSelectionPaletteFromStorage();
|
|
499
|
+
|
|
488
500
|
if (selectionPalette) {
|
|
489
|
-
html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection"));
|
|
501
|
+
html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts));
|
|
490
502
|
}
|
|
491
503
|
|
|
492
504
|
paletteContainer.html(html.join(""));
|
|
@@ -496,7 +508,7 @@
|
|
|
496
508
|
if (opts.showInitial) {
|
|
497
509
|
var initial = colorOnShow;
|
|
498
510
|
var current = get();
|
|
499
|
-
initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial"));
|
|
511
|
+
initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts));
|
|
500
512
|
}
|
|
501
513
|
}
|
|
502
514
|
|
|
@@ -524,7 +536,7 @@
|
|
|
524
536
|
}
|
|
525
537
|
else {
|
|
526
538
|
var tiny = tinycolor(value);
|
|
527
|
-
if (tiny.
|
|
539
|
+
if (tiny.isValid()) {
|
|
528
540
|
set(tiny);
|
|
529
541
|
updateOriginalInput(true);
|
|
530
542
|
}
|
|
@@ -632,8 +644,8 @@
|
|
|
632
644
|
}
|
|
633
645
|
updateUI();
|
|
634
646
|
|
|
635
|
-
if (newColor && newColor.
|
|
636
|
-
currentPreferredFormat = preferredFormat || newColor.
|
|
647
|
+
if (newColor && newColor.isValid() && !ignoreFormatChange) {
|
|
648
|
+
currentPreferredFormat = preferredFormat || newColor.getFormat();
|
|
637
649
|
}
|
|
638
650
|
}
|
|
639
651
|
|
|
@@ -684,7 +696,7 @@
|
|
|
684
696
|
var realColor = get({ format: format }),
|
|
685
697
|
displayColor = '';
|
|
686
698
|
|
|
687
|
-
|
|
699
|
+
//reset background info for preview element
|
|
688
700
|
previewElement.removeClass("sp-clear-display");
|
|
689
701
|
previewElement.css('background-color', 'transparent');
|
|
690
702
|
|
|
@@ -889,9 +901,9 @@
|
|
|
889
901
|
}
|
|
890
902
|
|
|
891
903
|
/**
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
904
|
+
* checkOffset - get the offset below/above and left/right element depending on screen position
|
|
905
|
+
* Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
|
|
906
|
+
*/
|
|
895
907
|
function getOffset(picker, input) {
|
|
896
908
|
var extraY = 0;
|
|
897
909
|
var dpWidth = picker.outerWidth();
|
|
@@ -906,33 +918,33 @@
|
|
|
906
918
|
|
|
907
919
|
offset.left -=
|
|
908
920
|
Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
|
|
909
|
-
|
|
921
|
+
Math.abs(offset.left + dpWidth - viewWidth) : 0);
|
|
910
922
|
|
|
911
923
|
offset.top -=
|
|
912
924
|
Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
|
|
913
|
-
|
|
925
|
+
Math.abs(dpHeight + inputHeight - extraY) : extraY));
|
|
914
926
|
|
|
915
927
|
return offset;
|
|
916
928
|
}
|
|
917
929
|
|
|
918
930
|
/**
|
|
919
|
-
|
|
920
|
-
|
|
931
|
+
* noop - do nothing
|
|
932
|
+
*/
|
|
921
933
|
function noop() {
|
|
922
934
|
|
|
923
935
|
}
|
|
924
936
|
|
|
925
937
|
/**
|
|
926
|
-
|
|
927
|
-
|
|
938
|
+
* stopPropagation - makes the code only doing this a little easier to read in line
|
|
939
|
+
*/
|
|
928
940
|
function stopPropagation(e) {
|
|
929
941
|
e.stopPropagation();
|
|
930
942
|
}
|
|
931
943
|
|
|
932
944
|
/**
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
945
|
+
* Create a function bound to a given object
|
|
946
|
+
* Thanks to underscore.js
|
|
947
|
+
*/
|
|
936
948
|
function bind(func, obj) {
|
|
937
949
|
var slice = Array.prototype.slice;
|
|
938
950
|
var args = slice.call(arguments, 2);
|
|
@@ -942,9 +954,9 @@
|
|
|
942
954
|
}
|
|
943
955
|
|
|
944
956
|
/**
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
957
|
+
* Lightweight drag helper. Handles containment within the element, so that
|
|
958
|
+
* when dragging, the x is within [0,element.width] and y is within [0,element.height]
|
|
959
|
+
*/
|
|
948
960
|
function draggable(element, onmove, onstart, onstop) {
|
|
949
961
|
onmove = onmove || function () { };
|
|
950
962
|
onstart = onstart || function () { };
|
|
@@ -1043,11 +1055,9 @@
|
|
|
1043
1055
|
};
|
|
1044
1056
|
}
|
|
1045
1057
|
|
|
1046
|
-
function log(){/* jshint -W021 */if(window.console){if(Function.prototype.bind)log=Function.prototype.bind.call(console.log,console);else log=function(){Function.prototype.apply.call(console.log,console,arguments);};log.apply(this,arguments);}}
|
|
1047
|
-
|
|
1048
1058
|
/**
|
|
1049
|
-
|
|
1050
|
-
|
|
1059
|
+
* Define a jQuery plugin
|
|
1060
|
+
*/
|
|
1051
1061
|
var dataID = "spectrum.id";
|
|
1052
1062
|
$.fn.spectrum = function (opts, extra) {
|
|
1053
1063
|
|
|
@@ -1111,412 +1121,430 @@
|
|
|
1111
1121
|
}
|
|
1112
1122
|
};
|
|
1113
1123
|
|
|
1114
|
-
// TinyColor v0.
|
|
1124
|
+
// TinyColor v0.10.0
|
|
1115
1125
|
// https://github.com/bgrins/TinyColor
|
|
1116
1126
|
// 2013-08-10, Brian Grinstead, MIT License
|
|
1117
1127
|
|
|
1118
1128
|
(function() {
|
|
1119
1129
|
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
function tinycolor (color, opts) {
|
|
1130
|
-
|
|
1131
|
-
color = (color) ? color : '';
|
|
1132
|
-
opts = opts || { };
|
|
1133
|
-
|
|
1134
|
-
// If input is already a tinycolor, return itself
|
|
1135
|
-
if (typeof color == "object" && color.hasOwnProperty("_tc_id")) {
|
|
1136
|
-
return color;
|
|
1137
|
-
}
|
|
1130
|
+
var trimLeft = /^[\s,#]+/,
|
|
1131
|
+
trimRight = /\s+$/,
|
|
1132
|
+
tinyCounter = 0,
|
|
1133
|
+
math = Math,
|
|
1134
|
+
mathRound = math.round,
|
|
1135
|
+
mathMin = math.min,
|
|
1136
|
+
mathMax = math.max,
|
|
1137
|
+
mathRandom = math.random;
|
|
1138
1138
|
|
|
1139
|
-
|
|
1140
|
-
var r = rgb.r,
|
|
1141
|
-
g = rgb.g,
|
|
1142
|
-
b = rgb.b,
|
|
1143
|
-
a = rgb.a,
|
|
1144
|
-
roundA = mathRound(100*a) / 100,
|
|
1145
|
-
format = opts.format || rgb.format;
|
|
1139
|
+
var tinycolor = function tinycolor (color, opts) {
|
|
1146
1140
|
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
// .5 gets interpreted as half of the total, instead of half of 1
|
|
1150
|
-
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
|
|
1151
|
-
if (r < 1) { r = mathRound(r); }
|
|
1152
|
-
if (g < 1) { g = mathRound(g); }
|
|
1153
|
-
if (b < 1) { b = mathRound(b); }
|
|
1141
|
+
color = (color) ? color : '';
|
|
1142
|
+
opts = opts || { };
|
|
1154
1143
|
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
setAlpha: function(value) {
|
|
1164
|
-
a = boundAlpha(value);
|
|
1165
|
-
roundA = mathRound(100*a) / 100;
|
|
1166
|
-
},
|
|
1167
|
-
toHsv: function() {
|
|
1168
|
-
var hsv = rgbToHsv(r, g, b);
|
|
1169
|
-
return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: a };
|
|
1170
|
-
},
|
|
1171
|
-
toHsvString: function() {
|
|
1172
|
-
var hsv = rgbToHsv(r, g, b);
|
|
1173
|
-
var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
|
|
1174
|
-
return (a == 1) ?
|
|
1175
|
-
"hsv(" + h + ", " + s + "%, " + v + "%)" :
|
|
1176
|
-
"hsva(" + h + ", " + s + "%, " + v + "%, "+ roundA + ")";
|
|
1177
|
-
},
|
|
1178
|
-
toHsl: function() {
|
|
1179
|
-
var hsl = rgbToHsl(r, g, b);
|
|
1180
|
-
return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: a };
|
|
1181
|
-
},
|
|
1182
|
-
toHslString: function() {
|
|
1183
|
-
var hsl = rgbToHsl(r, g, b);
|
|
1184
|
-
var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
|
|
1185
|
-
return (a == 1) ?
|
|
1186
|
-
"hsl(" + h + ", " + s + "%, " + l + "%)" :
|
|
1187
|
-
"hsla(" + h + ", " + s + "%, " + l + "%, "+ roundA + ")";
|
|
1188
|
-
},
|
|
1189
|
-
toHex: function(allow3Char) {
|
|
1190
|
-
return rgbToHex(r, g, b, allow3Char);
|
|
1191
|
-
},
|
|
1192
|
-
toHexString: function(allow3Char) {
|
|
1193
|
-
return '#' + this.toHex(allow3Char);
|
|
1194
|
-
},
|
|
1195
|
-
toHex8: function() {
|
|
1196
|
-
return rgbaToHex(r, g, b, a);
|
|
1197
|
-
},
|
|
1198
|
-
toHex8String: function() {
|
|
1199
|
-
return '#' + this.toHex8();
|
|
1200
|
-
},
|
|
1201
|
-
toRgb: function() {
|
|
1202
|
-
return { r: mathRound(r), g: mathRound(g), b: mathRound(b), a: a };
|
|
1203
|
-
},
|
|
1204
|
-
toRgbString: function() {
|
|
1205
|
-
return (a == 1) ?
|
|
1206
|
-
"rgb(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ")" :
|
|
1207
|
-
"rgba(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ", " + roundA + ")";
|
|
1208
|
-
},
|
|
1209
|
-
toPercentageRgb: function() {
|
|
1210
|
-
return { r: mathRound(bound01(r, 255) * 100) + "%", g: mathRound(bound01(g, 255) * 100) + "%", b: mathRound(bound01(b, 255) * 100) + "%", a: a };
|
|
1211
|
-
},
|
|
1212
|
-
toPercentageRgbString: function() {
|
|
1213
|
-
return (a == 1) ?
|
|
1214
|
-
"rgb(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%)" :
|
|
1215
|
-
"rgba(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%, " + roundA + ")";
|
|
1216
|
-
},
|
|
1217
|
-
toName: function() {
|
|
1218
|
-
if (a === 0) {
|
|
1219
|
-
return "transparent";
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1222
|
-
return hexNames[rgbToHex(r, g, b, true)] || false;
|
|
1223
|
-
},
|
|
1224
|
-
toFilter: function(secondColor) {
|
|
1225
|
-
var hex8String = '#' + rgbaToHex(r, g, b, a);
|
|
1226
|
-
var secondHex8String = hex8String;
|
|
1227
|
-
var gradientType = opts && opts.gradientType ? "GradientType = 1, " : "";
|
|
1144
|
+
// If input is already a tinycolor, return itself
|
|
1145
|
+
if (color instanceof tinycolor) {
|
|
1146
|
+
return color;
|
|
1147
|
+
}
|
|
1148
|
+
// If we are called as a function, call using new instead
|
|
1149
|
+
if (!(this instanceof tinycolor)) {
|
|
1150
|
+
return new tinycolor(color, opts);
|
|
1151
|
+
}
|
|
1228
1152
|
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1153
|
+
var rgb = inputToRGB(color);
|
|
1154
|
+
this._r = rgb.r,
|
|
1155
|
+
this._g = rgb.g,
|
|
1156
|
+
this._b = rgb.b,
|
|
1157
|
+
this._a = rgb.a,
|
|
1158
|
+
this._roundA = mathRound(100*this._a) / 100,
|
|
1159
|
+
this._format = opts.format || rgb.format;
|
|
1160
|
+
this._gradientType = opts.gradientType;
|
|
1161
|
+
|
|
1162
|
+
// Don't let the range of [0,255] come back in [0,1].
|
|
1163
|
+
// Potentially lose a little bit of precision here, but will fix issues where
|
|
1164
|
+
// .5 gets interpreted as half of the total, instead of half of 1
|
|
1165
|
+
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
|
|
1166
|
+
if (this._r < 1) { this._r = mathRound(this._r); }
|
|
1167
|
+
if (this._g < 1) { this._g = mathRound(this._g); }
|
|
1168
|
+
if (this._b < 1) { this._b = mathRound(this._b); }
|
|
1169
|
+
|
|
1170
|
+
this._ok = rgb.ok;
|
|
1171
|
+
this._tc_id = tinyCounter++;
|
|
1172
|
+
};
|
|
1233
1173
|
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1174
|
+
tinycolor.prototype = {
|
|
1175
|
+
isValid: function() {
|
|
1176
|
+
return this._ok;
|
|
1177
|
+
},
|
|
1178
|
+
getFormat: function() {
|
|
1179
|
+
return this._format;
|
|
1180
|
+
},
|
|
1181
|
+
getAlpha: function() {
|
|
1182
|
+
return this._a;
|
|
1183
|
+
},
|
|
1184
|
+
setAlpha: function(value) {
|
|
1185
|
+
this._a = boundAlpha(value);
|
|
1186
|
+
this._roundA = mathRound(100*this._a) / 100;
|
|
1187
|
+
},
|
|
1188
|
+
toHsv: function() {
|
|
1189
|
+
var hsv = rgbToHsv(this._r, this._g, this._b);
|
|
1190
|
+
return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
|
|
1191
|
+
},
|
|
1192
|
+
toHsvString: function() {
|
|
1193
|
+
var hsv = rgbToHsv(this._r, this._g, this._b);
|
|
1194
|
+
var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
|
|
1195
|
+
return (this._a == 1) ?
|
|
1196
|
+
"hsv(" + h + ", " + s + "%, " + v + "%)" :
|
|
1197
|
+
"hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
|
|
1198
|
+
},
|
|
1199
|
+
toHsl: function() {
|
|
1200
|
+
var hsl = rgbToHsl(this._r, this._g, this._b);
|
|
1201
|
+
return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
|
|
1202
|
+
},
|
|
1203
|
+
toHslString: function() {
|
|
1204
|
+
var hsl = rgbToHsl(this._r, this._g, this._b);
|
|
1205
|
+
var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
|
|
1206
|
+
return (this._a == 1) ?
|
|
1207
|
+
"hsl(" + h + ", " + s + "%, " + l + "%)" :
|
|
1208
|
+
"hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
|
|
1209
|
+
},
|
|
1210
|
+
toHex: function(allow3Char) {
|
|
1211
|
+
return rgbToHex(this._r, this._g, this._b, allow3Char);
|
|
1212
|
+
},
|
|
1213
|
+
toHexString: function(allow3Char) {
|
|
1214
|
+
return '#' + this.toHex(allow3Char);
|
|
1215
|
+
},
|
|
1216
|
+
toHex8: function() {
|
|
1217
|
+
return rgbaToHex(this._r, this._g, this._b, this._a);
|
|
1218
|
+
},
|
|
1219
|
+
toHex8String: function() {
|
|
1220
|
+
return '#' + this.toHex8();
|
|
1221
|
+
},
|
|
1222
|
+
toRgb: function() {
|
|
1223
|
+
return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
|
|
1224
|
+
},
|
|
1225
|
+
toRgbString: function() {
|
|
1226
|
+
return (this._a == 1) ?
|
|
1227
|
+
"rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
|
|
1228
|
+
"rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
|
|
1229
|
+
},
|
|
1230
|
+
toPercentageRgb: function() {
|
|
1231
|
+
return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
|
|
1232
|
+
},
|
|
1233
|
+
toPercentageRgbString: function() {
|
|
1234
|
+
return (this._a == 1) ?
|
|
1235
|
+
"rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
|
|
1236
|
+
"rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
|
|
1237
|
+
},
|
|
1238
|
+
toName: function() {
|
|
1239
|
+
if (this._a === 0) {
|
|
1240
|
+
return "transparent";
|
|
1241
|
+
}
|
|
1239
1242
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
+
if (this._a < 1) {
|
|
1244
|
+
return false;
|
|
1245
|
+
}
|
|
1243
1246
|
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
if (format === "hex" || format === "hex6") {
|
|
1251
|
-
formattedString = this.toHexString();
|
|
1252
|
-
}
|
|
1253
|
-
if (format === "hex3") {
|
|
1254
|
-
formattedString = this.toHexString(true);
|
|
1255
|
-
}
|
|
1256
|
-
if (format === "hex8") {
|
|
1257
|
-
formattedString = this.toHex8String();
|
|
1258
|
-
}
|
|
1259
|
-
if (format === "name") {
|
|
1260
|
-
formattedString = this.toName();
|
|
1261
|
-
}
|
|
1262
|
-
if (format === "hsl") {
|
|
1263
|
-
formattedString = this.toHslString();
|
|
1264
|
-
}
|
|
1265
|
-
if (format === "hsv") {
|
|
1266
|
-
formattedString = this.toHsvString();
|
|
1267
|
-
}
|
|
1247
|
+
return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
|
|
1248
|
+
},
|
|
1249
|
+
toFilter: function(secondColor) {
|
|
1250
|
+
var hex8String = '#' + rgbaToHex(this._r, this._g, this._b, this._a);
|
|
1251
|
+
var secondHex8String = hex8String;
|
|
1252
|
+
var gradientType = this._gradientType ? "GradientType = 1, " : "";
|
|
1268
1253
|
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1254
|
+
if (secondColor) {
|
|
1255
|
+
var s = tinycolor(secondColor);
|
|
1256
|
+
secondHex8String = s.toHex8String();
|
|
1257
|
+
}
|
|
1272
1258
|
|
|
1273
|
-
|
|
1259
|
+
return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
|
|
1260
|
+
},
|
|
1261
|
+
toString: function(format) {
|
|
1262
|
+
var formatSet = !!format;
|
|
1263
|
+
format = format || this._format;
|
|
1264
|
+
|
|
1265
|
+
var formattedString = false;
|
|
1266
|
+
var hasAlpha = this._a < 1 && this._a >= 0;
|
|
1267
|
+
var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
|
|
1268
|
+
|
|
1269
|
+
if (needsAlphaFormat) {
|
|
1270
|
+
// Special case for "transparent", all other non-alpha formats
|
|
1271
|
+
// will return rgba when there is transparency.
|
|
1272
|
+
if (format === "name" && this._a === 0) {
|
|
1273
|
+
return this.toName();
|
|
1274
1274
|
}
|
|
1275
|
-
|
|
1275
|
+
return this.toRgbString();
|
|
1276
|
+
}
|
|
1277
|
+
if (format === "rgb") {
|
|
1278
|
+
formattedString = this.toRgbString();
|
|
1279
|
+
}
|
|
1280
|
+
if (format === "prgb") {
|
|
1281
|
+
formattedString = this.toPercentageRgbString();
|
|
1282
|
+
}
|
|
1283
|
+
if (format === "hex" || format === "hex6") {
|
|
1284
|
+
formattedString = this.toHexString();
|
|
1285
|
+
}
|
|
1286
|
+
if (format === "hex3") {
|
|
1287
|
+
formattedString = this.toHexString(true);
|
|
1288
|
+
}
|
|
1289
|
+
if (format === "hex8") {
|
|
1290
|
+
formattedString = this.toHex8String();
|
|
1291
|
+
}
|
|
1292
|
+
if (format === "name") {
|
|
1293
|
+
formattedString = this.toName();
|
|
1294
|
+
}
|
|
1295
|
+
if (format === "hsl") {
|
|
1296
|
+
formattedString = this.toHslString();
|
|
1297
|
+
}
|
|
1298
|
+
if (format === "hsv") {
|
|
1299
|
+
formattedString = this.toHsvString();
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
return formattedString || this.toHexString();
|
|
1276
1303
|
}
|
|
1304
|
+
};
|
|
1277
1305
|
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
}
|
|
1306
|
+
// If input is an object, force 1 into "1.0" to handle ratios properly
|
|
1307
|
+
// String input requires "1.0" as input, so 1 will be treated as 1
|
|
1308
|
+
tinycolor.fromRatio = function(color, opts) {
|
|
1309
|
+
if (typeof color == "object") {
|
|
1310
|
+
var newColor = {};
|
|
1311
|
+
for (var i in color) {
|
|
1312
|
+
if (color.hasOwnProperty(i)) {
|
|
1313
|
+
if (i === "a") {
|
|
1314
|
+
newColor[i] = color[i];
|
|
1315
|
+
}
|
|
1316
|
+
else {
|
|
1317
|
+
newColor[i] = convertToPercentage(color[i]);
|
|
1291
1318
|
}
|
|
1292
1319
|
}
|
|
1293
|
-
color = newColor;
|
|
1294
1320
|
}
|
|
1321
|
+
color = newColor;
|
|
1322
|
+
}
|
|
1295
1323
|
|
|
1296
|
-
|
|
1297
|
-
|
|
1324
|
+
return tinycolor(color, opts);
|
|
1325
|
+
};
|
|
1298
1326
|
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
if (typeof color == "object") {
|
|
1326
|
-
if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
|
|
1327
|
-
rgb = rgbToRgb(color.r, color.g, color.b);
|
|
1328
|
-
ok = true;
|
|
1329
|
-
format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
|
|
1330
|
-
}
|
|
1331
|
-
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
|
|
1332
|
-
color.s = convertToPercentage(color.s);
|
|
1333
|
-
color.v = convertToPercentage(color.v);
|
|
1334
|
-
rgb = hsvToRgb(color.h, color.s, color.v);
|
|
1335
|
-
ok = true;
|
|
1336
|
-
format = "hsv";
|
|
1337
|
-
}
|
|
1338
|
-
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
|
|
1339
|
-
color.s = convertToPercentage(color.s);
|
|
1340
|
-
color.l = convertToPercentage(color.l);
|
|
1341
|
-
rgb = hslToRgb(color.h, color.s, color.l);
|
|
1342
|
-
ok = true;
|
|
1343
|
-
format = "hsl";
|
|
1344
|
-
}
|
|
1327
|
+
// Given a string or object, convert that input to RGB
|
|
1328
|
+
// Possible string inputs:
|
|
1329
|
+
//
|
|
1330
|
+
// "red"
|
|
1331
|
+
// "#f00" or "f00"
|
|
1332
|
+
// "#ff0000" or "ff0000"
|
|
1333
|
+
// "#ff000000" or "ff000000"
|
|
1334
|
+
// "rgb 255 0 0" or "rgb (255, 0, 0)"
|
|
1335
|
+
// "rgb 1.0 0 0" or "rgb (1, 0, 0)"
|
|
1336
|
+
// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
|
|
1337
|
+
// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
|
|
1338
|
+
// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
|
|
1339
|
+
// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
|
|
1340
|
+
// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
|
|
1341
|
+
//
|
|
1342
|
+
function inputToRGB(color) {
|
|
1343
|
+
|
|
1344
|
+
var rgb = { r: 0, g: 0, b: 0 };
|
|
1345
|
+
var a = 1;
|
|
1346
|
+
var ok = false;
|
|
1347
|
+
var format = false;
|
|
1348
|
+
|
|
1349
|
+
if (typeof color == "string") {
|
|
1350
|
+
color = stringInputToObject(color);
|
|
1351
|
+
}
|
|
1345
1352
|
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1353
|
+
if (typeof color == "object") {
|
|
1354
|
+
if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
|
|
1355
|
+
rgb = rgbToRgb(color.r, color.g, color.b);
|
|
1356
|
+
ok = true;
|
|
1357
|
+
format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
|
|
1358
|
+
}
|
|
1359
|
+
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
|
|
1360
|
+
color.s = convertToPercentage(color.s);
|
|
1361
|
+
color.v = convertToPercentage(color.v);
|
|
1362
|
+
rgb = hsvToRgb(color.h, color.s, color.v);
|
|
1363
|
+
ok = true;
|
|
1364
|
+
format = "hsv";
|
|
1365
|
+
}
|
|
1366
|
+
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
|
|
1367
|
+
color.s = convertToPercentage(color.s);
|
|
1368
|
+
color.l = convertToPercentage(color.l);
|
|
1369
|
+
rgb = hslToRgb(color.h, color.s, color.l);
|
|
1370
|
+
ok = true;
|
|
1371
|
+
format = "hsl";
|
|
1349
1372
|
}
|
|
1350
1373
|
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
ok: ok,
|
|
1355
|
-
format: color.format || format,
|
|
1356
|
-
r: mathMin(255, mathMax(rgb.r, 0)),
|
|
1357
|
-
g: mathMin(255, mathMax(rgb.g, 0)),
|
|
1358
|
-
b: mathMin(255, mathMax(rgb.b, 0)),
|
|
1359
|
-
a: a
|
|
1360
|
-
};
|
|
1374
|
+
if (color.hasOwnProperty("a")) {
|
|
1375
|
+
a = color.a;
|
|
1376
|
+
}
|
|
1361
1377
|
}
|
|
1362
1378
|
|
|
1379
|
+
a = boundAlpha(a);
|
|
1380
|
+
|
|
1381
|
+
return {
|
|
1382
|
+
ok: ok,
|
|
1383
|
+
format: color.format || format,
|
|
1384
|
+
r: mathMin(255, mathMax(rgb.r, 0)),
|
|
1385
|
+
g: mathMin(255, mathMax(rgb.g, 0)),
|
|
1386
|
+
b: mathMin(255, mathMax(rgb.b, 0)),
|
|
1387
|
+
a: a
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1363
1390
|
|
|
1364
|
-
// Conversion Functions
|
|
1365
|
-
// --------------------
|
|
1366
1391
|
|
|
1367
|
-
|
|
1368
|
-
|
|
1392
|
+
// Conversion Functions
|
|
1393
|
+
// --------------------
|
|
1369
1394
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
// <http://www.w3.org/TR/css3-color/>
|
|
1373
|
-
// *Assumes:* r, g, b in [0, 255] or [0, 1]
|
|
1374
|
-
// *Returns:* { r, g, b } in [0, 255]
|
|
1375
|
-
function rgbToRgb(r, g, b){
|
|
1376
|
-
return {
|
|
1377
|
-
r: bound01(r, 255) * 255,
|
|
1378
|
-
g: bound01(g, 255) * 255,
|
|
1379
|
-
b: bound01(b, 255) * 255
|
|
1380
|
-
};
|
|
1381
|
-
}
|
|
1395
|
+
// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
|
|
1396
|
+
// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
|
|
1382
1397
|
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1398
|
+
// `rgbToRgb`
|
|
1399
|
+
// Handle bounds / percentage checking to conform to CSS color spec
|
|
1400
|
+
// <http://www.w3.org/TR/css3-color/>
|
|
1401
|
+
// *Assumes:* r, g, b in [0, 255] or [0, 1]
|
|
1402
|
+
// *Returns:* { r, g, b } in [0, 255]
|
|
1403
|
+
function rgbToRgb(r, g, b){
|
|
1404
|
+
return {
|
|
1405
|
+
r: bound01(r, 255) * 255,
|
|
1406
|
+
g: bound01(g, 255) * 255,
|
|
1407
|
+
b: bound01(b, 255) * 255
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1388
1410
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1411
|
+
// `rgbToHsl`
|
|
1412
|
+
// Converts an RGB color value to HSL.
|
|
1413
|
+
// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
|
|
1414
|
+
// *Returns:* { h, s, l } in [0,1]
|
|
1415
|
+
function rgbToHsl(r, g, b) {
|
|
1392
1416
|
|
|
1393
|
-
|
|
1394
|
-
|
|
1417
|
+
r = bound01(r, 255);
|
|
1418
|
+
g = bound01(g, 255);
|
|
1419
|
+
b = bound01(b, 255);
|
|
1395
1420
|
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
}
|
|
1399
|
-
else {
|
|
1400
|
-
var d = max - min;
|
|
1401
|
-
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
1402
|
-
switch(max) {
|
|
1403
|
-
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
|
1404
|
-
case g: h = (b - r) / d + 2; break;
|
|
1405
|
-
case b: h = (r - g) / d + 4; break;
|
|
1406
|
-
}
|
|
1421
|
+
var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
|
1422
|
+
var h, s, l = (max + min) / 2;
|
|
1407
1423
|
|
|
1408
|
-
|
|
1424
|
+
if(max == min) {
|
|
1425
|
+
h = s = 0; // achromatic
|
|
1426
|
+
}
|
|
1427
|
+
else {
|
|
1428
|
+
var d = max - min;
|
|
1429
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
1430
|
+
switch(max) {
|
|
1431
|
+
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
|
1432
|
+
case g: h = (b - r) / d + 2; break;
|
|
1433
|
+
case b: h = (r - g) / d + 4; break;
|
|
1409
1434
|
}
|
|
1410
1435
|
|
|
1411
|
-
|
|
1436
|
+
h /= 6;
|
|
1412
1437
|
}
|
|
1413
1438
|
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
|
|
1417
|
-
// *Returns:* { r, g, b } in the set [0, 255]
|
|
1418
|
-
function hslToRgb(h, s, l) {
|
|
1419
|
-
var r, g, b;
|
|
1420
|
-
|
|
1421
|
-
h = bound01(h, 360);
|
|
1422
|
-
s = bound01(s, 100);
|
|
1423
|
-
l = bound01(l, 100);
|
|
1424
|
-
|
|
1425
|
-
function hue2rgb(p, q, t) {
|
|
1426
|
-
if(t < 0) t += 1;
|
|
1427
|
-
if(t > 1) t -= 1;
|
|
1428
|
-
if(t < 1/6) return p + (q - p) * 6 * t;
|
|
1429
|
-
if(t < 1/2) return q;
|
|
1430
|
-
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
|
1431
|
-
return p;
|
|
1432
|
-
}
|
|
1439
|
+
return { h: h, s: s, l: l };
|
|
1440
|
+
}
|
|
1433
1441
|
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1442
|
+
// `hslToRgb`
|
|
1443
|
+
// Converts an HSL color value to RGB.
|
|
1444
|
+
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
|
|
1445
|
+
// *Returns:* { r, g, b } in the set [0, 255]
|
|
1446
|
+
function hslToRgb(h, s, l) {
|
|
1447
|
+
var r, g, b;
|
|
1448
|
+
|
|
1449
|
+
h = bound01(h, 360);
|
|
1450
|
+
s = bound01(s, 100);
|
|
1451
|
+
l = bound01(l, 100);
|
|
1452
|
+
|
|
1453
|
+
function hue2rgb(p, q, t) {
|
|
1454
|
+
if(t < 0) t += 1;
|
|
1455
|
+
if(t > 1) t -= 1;
|
|
1456
|
+
if(t < 1/6) return p + (q - p) * 6 * t;
|
|
1457
|
+
if(t < 1/2) return q;
|
|
1458
|
+
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
|
1459
|
+
return p;
|
|
1460
|
+
}
|
|
1444
1461
|
|
|
1445
|
-
|
|
1462
|
+
if(s === 0) {
|
|
1463
|
+
r = g = b = l; // achromatic
|
|
1464
|
+
}
|
|
1465
|
+
else {
|
|
1466
|
+
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
1467
|
+
var p = 2 * l - q;
|
|
1468
|
+
r = hue2rgb(p, q, h + 1/3);
|
|
1469
|
+
g = hue2rgb(p, q, h);
|
|
1470
|
+
b = hue2rgb(p, q, h - 1/3);
|
|
1446
1471
|
}
|
|
1447
1472
|
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
|
|
1451
|
-
// *Returns:* { h, s, v } in [0,1]
|
|
1452
|
-
function rgbToHsv(r, g, b) {
|
|
1473
|
+
return { r: r * 255, g: g * 255, b: b * 255 };
|
|
1474
|
+
}
|
|
1453
1475
|
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1476
|
+
// `rgbToHsv`
|
|
1477
|
+
// Converts an RGB color value to HSV
|
|
1478
|
+
// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
|
|
1479
|
+
// *Returns:* { h, s, v } in [0,1]
|
|
1480
|
+
function rgbToHsv(r, g, b) {
|
|
1457
1481
|
|
|
1458
|
-
|
|
1459
|
-
|
|
1482
|
+
r = bound01(r, 255);
|
|
1483
|
+
g = bound01(g, 255);
|
|
1484
|
+
b = bound01(b, 255);
|
|
1460
1485
|
|
|
1461
|
-
|
|
1462
|
-
|
|
1486
|
+
var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
|
1487
|
+
var h, s, v = max;
|
|
1463
1488
|
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
h
|
|
1489
|
+
var d = max - min;
|
|
1490
|
+
s = max === 0 ? 0 : d / max;
|
|
1491
|
+
|
|
1492
|
+
if(max == min) {
|
|
1493
|
+
h = 0; // achromatic
|
|
1494
|
+
}
|
|
1495
|
+
else {
|
|
1496
|
+
switch(max) {
|
|
1497
|
+
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
|
1498
|
+
case g: h = (b - r) / d + 2; break;
|
|
1499
|
+
case b: h = (r - g) / d + 4; break;
|
|
1474
1500
|
}
|
|
1475
|
-
|
|
1501
|
+
h /= 6;
|
|
1476
1502
|
}
|
|
1503
|
+
return { h: h, s: s, v: v };
|
|
1504
|
+
}
|
|
1477
1505
|
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1506
|
+
// `hsvToRgb`
|
|
1507
|
+
// Converts an HSV color value to RGB.
|
|
1508
|
+
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
|
|
1509
|
+
// *Returns:* { r, g, b } in the set [0, 255]
|
|
1510
|
+
function hsvToRgb(h, s, v) {
|
|
1511
|
+
|
|
1512
|
+
h = bound01(h, 360) * 6;
|
|
1513
|
+
s = bound01(s, 100);
|
|
1514
|
+
v = bound01(v, 100);
|
|
1515
|
+
|
|
1516
|
+
var i = math.floor(h),
|
|
1517
|
+
f = h - i,
|
|
1518
|
+
p = v * (1 - s),
|
|
1519
|
+
q = v * (1 - f * s),
|
|
1520
|
+
t = v * (1 - (1 - f) * s),
|
|
1521
|
+
mod = i % 6,
|
|
1522
|
+
r = [v, q, p, p, t, v][mod],
|
|
1523
|
+
g = [t, v, v, q, p, p][mod],
|
|
1524
|
+
b = [p, p, t, v, v, q][mod];
|
|
1525
|
+
|
|
1526
|
+
return { r: r * 255, g: g * 255, b: b * 255 };
|
|
1527
|
+
}
|
|
1497
1528
|
|
|
1498
|
-
|
|
1529
|
+
// `rgbToHex`
|
|
1530
|
+
// Converts an RGB color to hex
|
|
1531
|
+
// Assumes r, g, and b are contained in the set [0, 255]
|
|
1532
|
+
// Returns a 3 or 6 character hex
|
|
1533
|
+
function rgbToHex(r, g, b, allow3Char) {
|
|
1534
|
+
|
|
1535
|
+
var hex = [
|
|
1536
|
+
pad2(mathRound(r).toString(16)),
|
|
1537
|
+
pad2(mathRound(g).toString(16)),
|
|
1538
|
+
pad2(mathRound(b).toString(16))
|
|
1539
|
+
];
|
|
1540
|
+
|
|
1541
|
+
// Return a 3 character hex if possible
|
|
1542
|
+
if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
|
|
1543
|
+
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
|
|
1499
1544
|
}
|
|
1500
1545
|
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
// Assumes r, g, and b are contained in the set [0, 255]
|
|
1504
|
-
// Returns a 3 or 6 character hex
|
|
1505
|
-
function rgbToHex(r, g, b, allow3Char) {
|
|
1506
|
-
|
|
1507
|
-
var hex = [
|
|
1508
|
-
pad2(mathRound(r).toString(16)),
|
|
1509
|
-
pad2(mathRound(g).toString(16)),
|
|
1510
|
-
pad2(mathRound(b).toString(16))
|
|
1511
|
-
];
|
|
1512
|
-
|
|
1513
|
-
// Return a 3 character hex if possible
|
|
1514
|
-
if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
|
|
1515
|
-
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
return hex.join("");
|
|
1519
|
-
}
|
|
1546
|
+
return hex.join("");
|
|
1547
|
+
}
|
|
1520
1548
|
// `rgbaToHex`
|
|
1521
1549
|
// Converts an RGBA color plus alpha transparency to hex
|
|
1522
1550
|
// Assumes r, g, b and a are contained in the set [0, 255]
|
|
@@ -1533,536 +1561,542 @@
|
|
|
1533
1561
|
return hex.join("");
|
|
1534
1562
|
}
|
|
1535
1563
|
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1564
|
+
// `equals`
|
|
1565
|
+
// Can be called with any tinycolor input
|
|
1566
|
+
tinycolor.equals = function (color1, color2) {
|
|
1567
|
+
if (!color1 || !color2) { return false; }
|
|
1568
|
+
return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
|
|
1569
|
+
};
|
|
1570
|
+
tinycolor.random = function() {
|
|
1571
|
+
return tinycolor.fromRatio({
|
|
1572
|
+
r: mathRandom(),
|
|
1573
|
+
g: mathRandom(),
|
|
1574
|
+
b: mathRandom()
|
|
1575
|
+
});
|
|
1576
|
+
};
|
|
1550
1577
|
|
|
1551
|
-
// Modification Functions
|
|
1552
|
-
// ----------------------
|
|
1553
|
-
// Thanks to less.js for some of the basics here
|
|
1554
|
-
// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
|
|
1555
1578
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
hsl.s = clamp01(hsl.s);
|
|
1561
|
-
return tinycolor(hsl);
|
|
1562
|
-
};
|
|
1563
|
-
tinycolor.saturate = function (color, amount) {
|
|
1564
|
-
amount = (amount === 0) ? 0 : (amount || 10);
|
|
1565
|
-
var hsl = tinycolor(color).toHsl();
|
|
1566
|
-
hsl.s += amount / 100;
|
|
1567
|
-
hsl.s = clamp01(hsl.s);
|
|
1568
|
-
return tinycolor(hsl);
|
|
1569
|
-
};
|
|
1570
|
-
tinycolor.greyscale = function(color) {
|
|
1571
|
-
return tinycolor.desaturate(color, 100);
|
|
1572
|
-
};
|
|
1573
|
-
tinycolor.lighten = function(color, amount) {
|
|
1574
|
-
amount = (amount === 0) ? 0 : (amount || 10);
|
|
1575
|
-
var hsl = tinycolor(color).toHsl();
|
|
1576
|
-
hsl.l += amount / 100;
|
|
1577
|
-
hsl.l = clamp01(hsl.l);
|
|
1578
|
-
return tinycolor(hsl);
|
|
1579
|
-
};
|
|
1580
|
-
tinycolor.darken = function (color, amount) {
|
|
1581
|
-
amount = (amount === 0) ? 0 : (amount || 10);
|
|
1582
|
-
var hsl = tinycolor(color).toHsl();
|
|
1583
|
-
hsl.l -= amount / 100;
|
|
1584
|
-
hsl.l = clamp01(hsl.l);
|
|
1585
|
-
return tinycolor(hsl);
|
|
1586
|
-
};
|
|
1587
|
-
tinycolor.complement = function(color) {
|
|
1588
|
-
var hsl = tinycolor(color).toHsl();
|
|
1589
|
-
hsl.h = (hsl.h + 180) % 360;
|
|
1590
|
-
return tinycolor(hsl);
|
|
1591
|
-
};
|
|
1579
|
+
// Modification Functions
|
|
1580
|
+
// ----------------------
|
|
1581
|
+
// Thanks to less.js for some of the basics here
|
|
1582
|
+
// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
|
|
1592
1583
|
|
|
1584
|
+
tinycolor.desaturate = function (color, amount) {
|
|
1585
|
+
amount = (amount === 0) ? 0 : (amount || 10);
|
|
1586
|
+
var hsl = tinycolor(color).toHsl();
|
|
1587
|
+
hsl.s -= amount / 100;
|
|
1588
|
+
hsl.s = clamp01(hsl.s);
|
|
1589
|
+
return tinycolor(hsl);
|
|
1590
|
+
};
|
|
1591
|
+
tinycolor.saturate = function (color, amount) {
|
|
1592
|
+
amount = (amount === 0) ? 0 : (amount || 10);
|
|
1593
|
+
var hsl = tinycolor(color).toHsl();
|
|
1594
|
+
hsl.s += amount / 100;
|
|
1595
|
+
hsl.s = clamp01(hsl.s);
|
|
1596
|
+
return tinycolor(hsl);
|
|
1597
|
+
};
|
|
1598
|
+
tinycolor.greyscale = function(color) {
|
|
1599
|
+
return tinycolor.desaturate(color, 100);
|
|
1600
|
+
};
|
|
1601
|
+
tinycolor.lighten = function(color, amount) {
|
|
1602
|
+
amount = (amount === 0) ? 0 : (amount || 10);
|
|
1603
|
+
var hsl = tinycolor(color).toHsl();
|
|
1604
|
+
hsl.l += amount / 100;
|
|
1605
|
+
hsl.l = clamp01(hsl.l);
|
|
1606
|
+
return tinycolor(hsl);
|
|
1607
|
+
};
|
|
1608
|
+
tinycolor.brighten = function(color, amount) {
|
|
1609
|
+
amount = (amount === 0) ? 0 : (amount || 10);
|
|
1610
|
+
var rgb = tinycolor(color).toRgb();
|
|
1611
|
+
rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
|
|
1612
|
+
rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
|
|
1613
|
+
rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
|
|
1614
|
+
return tinycolor(rgb);
|
|
1615
|
+
};
|
|
1616
|
+
tinycolor.darken = function (color, amount) {
|
|
1617
|
+
amount = (amount === 0) ? 0 : (amount || 10);
|
|
1618
|
+
var hsl = tinycolor(color).toHsl();
|
|
1619
|
+
hsl.l -= amount / 100;
|
|
1620
|
+
hsl.l = clamp01(hsl.l);
|
|
1621
|
+
return tinycolor(hsl);
|
|
1622
|
+
};
|
|
1623
|
+
tinycolor.complement = function(color) {
|
|
1624
|
+
var hsl = tinycolor(color).toHsl();
|
|
1625
|
+
hsl.h = (hsl.h + 180) % 360;
|
|
1626
|
+
return tinycolor(hsl);
|
|
1627
|
+
};
|
|
1593
1628
|
|
|
1594
|
-
// Combination Functions
|
|
1595
|
-
// ---------------------
|
|
1596
|
-
// Thanks to jQuery xColor for some of the ideas behind these
|
|
1597
|
-
// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
|
|
1598
|
-
|
|
1599
|
-
tinycolor.triad = function(color) {
|
|
1600
|
-
var hsl = tinycolor(color).toHsl();
|
|
1601
|
-
var h = hsl.h;
|
|
1602
|
-
return [
|
|
1603
|
-
tinycolor(color),
|
|
1604
|
-
tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
|
|
1605
|
-
tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
|
|
1606
|
-
];
|
|
1607
|
-
};
|
|
1608
|
-
tinycolor.tetrad = function(color) {
|
|
1609
|
-
var hsl = tinycolor(color).toHsl();
|
|
1610
|
-
var h = hsl.h;
|
|
1611
|
-
return [
|
|
1612
|
-
tinycolor(color),
|
|
1613
|
-
tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
|
|
1614
|
-
tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
|
|
1615
|
-
tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
|
|
1616
|
-
];
|
|
1617
|
-
};
|
|
1618
|
-
tinycolor.splitcomplement = function(color) {
|
|
1619
|
-
var hsl = tinycolor(color).toHsl();
|
|
1620
|
-
var h = hsl.h;
|
|
1621
|
-
return [
|
|
1622
|
-
tinycolor(color),
|
|
1623
|
-
tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
|
|
1624
|
-
tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
|
|
1625
|
-
];
|
|
1626
|
-
};
|
|
1627
|
-
tinycolor.analogous = function(color, results, slices) {
|
|
1628
|
-
results = results || 6;
|
|
1629
|
-
slices = slices || 30;
|
|
1630
1629
|
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1630
|
+
// Combination Functions
|
|
1631
|
+
// ---------------------
|
|
1632
|
+
// Thanks to jQuery xColor for some of the ideas behind these
|
|
1633
|
+
// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
|
|
1634
1634
|
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1635
|
+
tinycolor.triad = function(color) {
|
|
1636
|
+
var hsl = tinycolor(color).toHsl();
|
|
1637
|
+
var h = hsl.h;
|
|
1638
|
+
return [
|
|
1639
|
+
tinycolor(color),
|
|
1640
|
+
tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
|
|
1641
|
+
tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
|
|
1642
|
+
];
|
|
1643
|
+
};
|
|
1644
|
+
tinycolor.tetrad = function(color) {
|
|
1645
|
+
var hsl = tinycolor(color).toHsl();
|
|
1646
|
+
var h = hsl.h;
|
|
1647
|
+
return [
|
|
1648
|
+
tinycolor(color),
|
|
1649
|
+
tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
|
|
1650
|
+
tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
|
|
1651
|
+
tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
|
|
1652
|
+
];
|
|
1653
|
+
};
|
|
1654
|
+
tinycolor.splitcomplement = function(color) {
|
|
1655
|
+
var hsl = tinycolor(color).toHsl();
|
|
1656
|
+
var h = hsl.h;
|
|
1657
|
+
return [
|
|
1658
|
+
tinycolor(color),
|
|
1659
|
+
tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
|
|
1660
|
+
tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
|
|
1661
|
+
];
|
|
1662
|
+
};
|
|
1663
|
+
tinycolor.analogous = function(color, results, slices) {
|
|
1664
|
+
results = results || 6;
|
|
1665
|
+
slices = slices || 30;
|
|
1647
1666
|
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
}
|
|
1667
|
+
var hsl = tinycolor(color).toHsl();
|
|
1668
|
+
var part = 360 / slices;
|
|
1669
|
+
var ret = [tinycolor(color)];
|
|
1652
1670
|
|
|
1653
|
-
|
|
1654
|
-
|
|
1671
|
+
for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
|
|
1672
|
+
hsl.h = (hsl.h + part) % 360;
|
|
1673
|
+
ret.push(tinycolor(hsl));
|
|
1674
|
+
}
|
|
1675
|
+
return ret;
|
|
1676
|
+
};
|
|
1677
|
+
tinycolor.monochromatic = function(color, results) {
|
|
1678
|
+
results = results || 6;
|
|
1679
|
+
var hsv = tinycolor(color).toHsv();
|
|
1680
|
+
var h = hsv.h, s = hsv.s, v = hsv.v;
|
|
1681
|
+
var ret = [];
|
|
1682
|
+
var modification = 1 / results;
|
|
1683
|
+
|
|
1684
|
+
while (results--) {
|
|
1685
|
+
ret.push(tinycolor({ h: h, s: s, v: v}));
|
|
1686
|
+
v = (v + modification) % 1;
|
|
1687
|
+
}
|
|
1655
1688
|
|
|
1689
|
+
return ret;
|
|
1690
|
+
};
|
|
1656
1691
|
|
|
1657
|
-
// Readability Functions
|
|
1658
|
-
// ---------------------
|
|
1659
|
-
// <http://www.w3.org/TR/AERT#color-contrast>
|
|
1660
|
-
|
|
1661
|
-
// `readability`
|
|
1662
|
-
// Analyze the 2 colors and returns an object with the following properties:
|
|
1663
|
-
// `brightness`: difference in brightness between the two colors
|
|
1664
|
-
// `color`: difference in color/hue between the two colors
|
|
1665
|
-
tinycolor.readability = function(color1, color2) {
|
|
1666
|
-
var a = tinycolor(color1).toRgb();
|
|
1667
|
-
var b = tinycolor(color2).toRgb();
|
|
1668
|
-
var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000;
|
|
1669
|
-
var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000;
|
|
1670
|
-
var colorDiff = (
|
|
1671
|
-
Math.max(a.r, b.r) - Math.min(a.r, b.r) +
|
|
1672
|
-
Math.max(a.g, b.g) - Math.min(a.g, b.g) +
|
|
1673
|
-
Math.max(a.b, b.b) - Math.min(a.b, b.b)
|
|
1674
|
-
);
|
|
1675
1692
|
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1693
|
+
// Readability Functions
|
|
1694
|
+
// ---------------------
|
|
1695
|
+
// <http://www.w3.org/TR/AERT#color-contrast>
|
|
1696
|
+
|
|
1697
|
+
// `readability`
|
|
1698
|
+
// Analyze the 2 colors and returns an object with the following properties:
|
|
1699
|
+
// `brightness`: difference in brightness between the two colors
|
|
1700
|
+
// `color`: difference in color/hue between the two colors
|
|
1701
|
+
tinycolor.readability = function(color1, color2) {
|
|
1702
|
+
var a = tinycolor(color1).toRgb();
|
|
1703
|
+
var b = tinycolor(color2).toRgb();
|
|
1704
|
+
var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000;
|
|
1705
|
+
var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000;
|
|
1706
|
+
var colorDiff = (
|
|
1707
|
+
Math.max(a.r, b.r) - Math.min(a.r, b.r) +
|
|
1708
|
+
Math.max(a.g, b.g) - Math.min(a.g, b.g) +
|
|
1709
|
+
Math.max(a.b, b.b) - Math.min(a.b, b.b)
|
|
1710
|
+
);
|
|
1711
|
+
|
|
1712
|
+
return {
|
|
1713
|
+
brightness: Math.abs(brightnessA - brightnessB),
|
|
1714
|
+
color: colorDiff
|
|
1680
1715
|
};
|
|
1716
|
+
};
|
|
1681
1717
|
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1718
|
+
// `readable`
|
|
1719
|
+
// http://www.w3.org/TR/AERT#color-contrast
|
|
1720
|
+
// Ensure that foreground and background color combinations provide sufficient contrast.
|
|
1721
|
+
// *Example*
|
|
1722
|
+
// tinycolor.readable("#000", "#111") => false
|
|
1723
|
+
tinycolor.readable = function(color1, color2) {
|
|
1724
|
+
var readability = tinycolor.readability(color1, color2);
|
|
1725
|
+
return readability.brightness > 125 && readability.color > 500;
|
|
1726
|
+
};
|
|
1691
1727
|
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
}
|
|
1728
|
+
// `mostReadable`
|
|
1729
|
+
// Given a base color and a list of possible foreground or background
|
|
1730
|
+
// colors for that base, returns the most readable color.
|
|
1731
|
+
// *Example*
|
|
1732
|
+
// tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
|
|
1733
|
+
tinycolor.mostReadable = function(baseColor, colorList) {
|
|
1734
|
+
var bestColor = null;
|
|
1735
|
+
var bestScore = 0;
|
|
1736
|
+
var bestIsReadable = false;
|
|
1737
|
+
for (var i=0; i < colorList.length; i++) {
|
|
1738
|
+
|
|
1739
|
+
// We normalize both around the "acceptable" breaking point,
|
|
1740
|
+
// but rank brightness constrast higher than hue.
|
|
1741
|
+
|
|
1742
|
+
var readability = tinycolor.readability(baseColor, colorList[i]);
|
|
1743
|
+
var readable = readability.brightness > 125 && readability.color > 500;
|
|
1744
|
+
var score = 3 * (readability.brightness / 125) + (readability.color / 500);
|
|
1745
|
+
|
|
1746
|
+
if ((readable && ! bestIsReadable) ||
|
|
1747
|
+
(readable && bestIsReadable && score > bestScore) ||
|
|
1748
|
+
((! readable) && (! bestIsReadable) && score > bestScore)) {
|
|
1749
|
+
bestIsReadable = readable;
|
|
1750
|
+
bestScore = score;
|
|
1751
|
+
bestColor = tinycolor(colorList[i]);
|
|
1717
1752
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1753
|
+
}
|
|
1754
|
+
return bestColor;
|
|
1755
|
+
};
|
|
1720
1756
|
|
|
1721
1757
|
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1758
|
+
// Big List of Colors
|
|
1759
|
+
// ------------------
|
|
1760
|
+
// <http://www.w3.org/TR/css3-color/#svg-color>
|
|
1761
|
+
var names = tinycolor.names = {
|
|
1762
|
+
aliceblue: "f0f8ff",
|
|
1763
|
+
antiquewhite: "faebd7",
|
|
1764
|
+
aqua: "0ff",
|
|
1765
|
+
aquamarine: "7fffd4",
|
|
1766
|
+
azure: "f0ffff",
|
|
1767
|
+
beige: "f5f5dc",
|
|
1768
|
+
bisque: "ffe4c4",
|
|
1769
|
+
black: "000",
|
|
1770
|
+
blanchedalmond: "ffebcd",
|
|
1771
|
+
blue: "00f",
|
|
1772
|
+
blueviolet: "8a2be2",
|
|
1773
|
+
brown: "a52a2a",
|
|
1774
|
+
burlywood: "deb887",
|
|
1775
|
+
burntsienna: "ea7e5d",
|
|
1776
|
+
cadetblue: "5f9ea0",
|
|
1777
|
+
chartreuse: "7fff00",
|
|
1778
|
+
chocolate: "d2691e",
|
|
1779
|
+
coral: "ff7f50",
|
|
1780
|
+
cornflowerblue: "6495ed",
|
|
1781
|
+
cornsilk: "fff8dc",
|
|
1782
|
+
crimson: "dc143c",
|
|
1783
|
+
cyan: "0ff",
|
|
1784
|
+
darkblue: "00008b",
|
|
1785
|
+
darkcyan: "008b8b",
|
|
1786
|
+
darkgoldenrod: "b8860b",
|
|
1787
|
+
darkgray: "a9a9a9",
|
|
1788
|
+
darkgreen: "006400",
|
|
1789
|
+
darkgrey: "a9a9a9",
|
|
1790
|
+
darkkhaki: "bdb76b",
|
|
1791
|
+
darkmagenta: "8b008b",
|
|
1792
|
+
darkolivegreen: "556b2f",
|
|
1793
|
+
darkorange: "ff8c00",
|
|
1794
|
+
darkorchid: "9932cc",
|
|
1795
|
+
darkred: "8b0000",
|
|
1796
|
+
darksalmon: "e9967a",
|
|
1797
|
+
darkseagreen: "8fbc8f",
|
|
1798
|
+
darkslateblue: "483d8b",
|
|
1799
|
+
darkslategray: "2f4f4f",
|
|
1800
|
+
darkslategrey: "2f4f4f",
|
|
1801
|
+
darkturquoise: "00ced1",
|
|
1802
|
+
darkviolet: "9400d3",
|
|
1803
|
+
deeppink: "ff1493",
|
|
1804
|
+
deepskyblue: "00bfff",
|
|
1805
|
+
dimgray: "696969",
|
|
1806
|
+
dimgrey: "696969",
|
|
1807
|
+
dodgerblue: "1e90ff",
|
|
1808
|
+
firebrick: "b22222",
|
|
1809
|
+
floralwhite: "fffaf0",
|
|
1810
|
+
forestgreen: "228b22",
|
|
1811
|
+
fuchsia: "f0f",
|
|
1812
|
+
gainsboro: "dcdcdc",
|
|
1813
|
+
ghostwhite: "f8f8ff",
|
|
1814
|
+
gold: "ffd700",
|
|
1815
|
+
goldenrod: "daa520",
|
|
1816
|
+
gray: "808080",
|
|
1817
|
+
green: "008000",
|
|
1818
|
+
greenyellow: "adff2f",
|
|
1819
|
+
grey: "808080",
|
|
1820
|
+
honeydew: "f0fff0",
|
|
1821
|
+
hotpink: "ff69b4",
|
|
1822
|
+
indianred: "cd5c5c",
|
|
1823
|
+
indigo: "4b0082",
|
|
1824
|
+
ivory: "fffff0",
|
|
1825
|
+
khaki: "f0e68c",
|
|
1826
|
+
lavender: "e6e6fa",
|
|
1827
|
+
lavenderblush: "fff0f5",
|
|
1828
|
+
lawngreen: "7cfc00",
|
|
1829
|
+
lemonchiffon: "fffacd",
|
|
1830
|
+
lightblue: "add8e6",
|
|
1831
|
+
lightcoral: "f08080",
|
|
1832
|
+
lightcyan: "e0ffff",
|
|
1833
|
+
lightgoldenrodyellow: "fafad2",
|
|
1834
|
+
lightgray: "d3d3d3",
|
|
1835
|
+
lightgreen: "90ee90",
|
|
1836
|
+
lightgrey: "d3d3d3",
|
|
1837
|
+
lightpink: "ffb6c1",
|
|
1838
|
+
lightsalmon: "ffa07a",
|
|
1839
|
+
lightseagreen: "20b2aa",
|
|
1840
|
+
lightskyblue: "87cefa",
|
|
1841
|
+
lightslategray: "789",
|
|
1842
|
+
lightslategrey: "789",
|
|
1843
|
+
lightsteelblue: "b0c4de",
|
|
1844
|
+
lightyellow: "ffffe0",
|
|
1845
|
+
lime: "0f0",
|
|
1846
|
+
limegreen: "32cd32",
|
|
1847
|
+
linen: "faf0e6",
|
|
1848
|
+
magenta: "f0f",
|
|
1849
|
+
maroon: "800000",
|
|
1850
|
+
mediumaquamarine: "66cdaa",
|
|
1851
|
+
mediumblue: "0000cd",
|
|
1852
|
+
mediumorchid: "ba55d3",
|
|
1853
|
+
mediumpurple: "9370db",
|
|
1854
|
+
mediumseagreen: "3cb371",
|
|
1855
|
+
mediumslateblue: "7b68ee",
|
|
1856
|
+
mediumspringgreen: "00fa9a",
|
|
1857
|
+
mediumturquoise: "48d1cc",
|
|
1858
|
+
mediumvioletred: "c71585",
|
|
1859
|
+
midnightblue: "191970",
|
|
1860
|
+
mintcream: "f5fffa",
|
|
1861
|
+
mistyrose: "ffe4e1",
|
|
1862
|
+
moccasin: "ffe4b5",
|
|
1863
|
+
navajowhite: "ffdead",
|
|
1864
|
+
navy: "000080",
|
|
1865
|
+
oldlace: "fdf5e6",
|
|
1866
|
+
olive: "808000",
|
|
1867
|
+
olivedrab: "6b8e23",
|
|
1868
|
+
orange: "ffa500",
|
|
1869
|
+
orangered: "ff4500",
|
|
1870
|
+
orchid: "da70d6",
|
|
1871
|
+
palegoldenrod: "eee8aa",
|
|
1872
|
+
palegreen: "98fb98",
|
|
1873
|
+
paleturquoise: "afeeee",
|
|
1874
|
+
palevioletred: "db7093",
|
|
1875
|
+
papayawhip: "ffefd5",
|
|
1876
|
+
peachpuff: "ffdab9",
|
|
1877
|
+
peru: "cd853f",
|
|
1878
|
+
pink: "ffc0cb",
|
|
1879
|
+
plum: "dda0dd",
|
|
1880
|
+
powderblue: "b0e0e6",
|
|
1881
|
+
purple: "800080",
|
|
1882
|
+
red: "f00",
|
|
1883
|
+
rosybrown: "bc8f8f",
|
|
1884
|
+
royalblue: "4169e1",
|
|
1885
|
+
saddlebrown: "8b4513",
|
|
1886
|
+
salmon: "fa8072",
|
|
1887
|
+
sandybrown: "f4a460",
|
|
1888
|
+
seagreen: "2e8b57",
|
|
1889
|
+
seashell: "fff5ee",
|
|
1890
|
+
sienna: "a0522d",
|
|
1891
|
+
silver: "c0c0c0",
|
|
1892
|
+
skyblue: "87ceeb",
|
|
1893
|
+
slateblue: "6a5acd",
|
|
1894
|
+
slategray: "708090",
|
|
1895
|
+
slategrey: "708090",
|
|
1896
|
+
snow: "fffafa",
|
|
1897
|
+
springgreen: "00ff7f",
|
|
1898
|
+
steelblue: "4682b4",
|
|
1899
|
+
tan: "d2b48c",
|
|
1900
|
+
teal: "008080",
|
|
1901
|
+
thistle: "d8bfd8",
|
|
1902
|
+
tomato: "ff6347",
|
|
1903
|
+
turquoise: "40e0d0",
|
|
1904
|
+
violet: "ee82ee",
|
|
1905
|
+
wheat: "f5deb3",
|
|
1906
|
+
white: "fff",
|
|
1907
|
+
whitesmoke: "f5f5f5",
|
|
1908
|
+
yellow: "ff0",
|
|
1909
|
+
yellowgreen: "9acd32"
|
|
1910
|
+
};
|
|
1875
1911
|
|
|
1876
|
-
|
|
1877
|
-
|
|
1912
|
+
// Make it easy to access colors via `hexNames[hex]`
|
|
1913
|
+
var hexNames = tinycolor.hexNames = flip(names);
|
|
1878
1914
|
|
|
1879
1915
|
|
|
1880
|
-
|
|
1881
|
-
|
|
1916
|
+
// Utilities
|
|
1917
|
+
// ---------
|
|
1882
1918
|
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
}
|
|
1919
|
+
// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
|
|
1920
|
+
function flip(o) {
|
|
1921
|
+
var flipped = { };
|
|
1922
|
+
for (var i in o) {
|
|
1923
|
+
if (o.hasOwnProperty(i)) {
|
|
1924
|
+
flipped[o[i]] = i;
|
|
1890
1925
|
}
|
|
1891
|
-
return flipped;
|
|
1892
1926
|
}
|
|
1927
|
+
return flipped;
|
|
1928
|
+
}
|
|
1893
1929
|
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1930
|
+
// Return a valid alpha value [0,1] with all invalid values being set to 1
|
|
1931
|
+
function boundAlpha(a) {
|
|
1932
|
+
a = parseFloat(a);
|
|
1897
1933
|
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
}
|
|
1901
|
-
|
|
1902
|
-
return a;
|
|
1934
|
+
if (isNaN(a) || a < 0 || a > 1) {
|
|
1935
|
+
a = 1;
|
|
1903
1936
|
}
|
|
1904
1937
|
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
if (isOnePointZero(n)) { n = "100%"; }
|
|
1908
|
-
|
|
1909
|
-
var processPercent = isPercentage(n);
|
|
1910
|
-
n = mathMin(max, mathMax(0, parseFloat(n)));
|
|
1938
|
+
return a;
|
|
1939
|
+
}
|
|
1911
1940
|
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
}
|
|
1941
|
+
// Take input from [0, n] and return it as [0, 1]
|
|
1942
|
+
function bound01(n, max) {
|
|
1943
|
+
if (isOnePointZero(n)) { n = "100%"; }
|
|
1916
1944
|
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
return 1;
|
|
1920
|
-
}
|
|
1945
|
+
var processPercent = isPercentage(n);
|
|
1946
|
+
n = mathMin(max, mathMax(0, parseFloat(n)));
|
|
1921
1947
|
|
|
1922
|
-
|
|
1923
|
-
|
|
1948
|
+
// Automatically convert percentage into number
|
|
1949
|
+
if (processPercent) {
|
|
1950
|
+
n = parseInt(n * max, 10) / 100;
|
|
1924
1951
|
}
|
|
1925
1952
|
|
|
1926
|
-
//
|
|
1927
|
-
|
|
1928
|
-
return
|
|
1953
|
+
// Handle floating point rounding errors
|
|
1954
|
+
if ((math.abs(n - max) < 0.000001)) {
|
|
1955
|
+
return 1;
|
|
1929
1956
|
}
|
|
1930
1957
|
|
|
1931
|
-
//
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
}
|
|
1958
|
+
// Convert into [0, 1] range if it isn't already
|
|
1959
|
+
return (n % max) / parseFloat(max);
|
|
1960
|
+
}
|
|
1935
1961
|
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
}
|
|
1962
|
+
// Force a number between 0 and 1
|
|
1963
|
+
function clamp01(val) {
|
|
1964
|
+
return mathMin(1, mathMax(0, val));
|
|
1965
|
+
}
|
|
1941
1966
|
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1967
|
+
// Parse a base-16 hex value into a base-10 integer
|
|
1968
|
+
function parseIntFromHex(val) {
|
|
1969
|
+
return parseInt(val, 16);
|
|
1970
|
+
}
|
|
1946
1971
|
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1972
|
+
// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
|
|
1973
|
+
// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
|
|
1974
|
+
function isOnePointZero(n) {
|
|
1975
|
+
return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
|
|
1976
|
+
}
|
|
1951
1977
|
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
}
|
|
1978
|
+
// Check to see if string passed in is a percentage
|
|
1979
|
+
function isPercentage(n) {
|
|
1980
|
+
return typeof n === "string" && n.indexOf('%') != -1;
|
|
1981
|
+
}
|
|
1957
1982
|
|
|
1958
|
-
|
|
1959
|
-
|
|
1983
|
+
// Force a hex value to have 2 characters
|
|
1984
|
+
function pad2(c) {
|
|
1985
|
+
return c.length == 1 ? '0' + c : '' + c;
|
|
1986
|
+
}
|
|
1960
1987
|
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
// Converts a hex value to a decimal
|
|
1966
|
-
function convertHexToDecimal(h) {
|
|
1967
|
-
return (parseIntFromHex(h) / 255);
|
|
1988
|
+
// Replace a decimal with it's percentage value
|
|
1989
|
+
function convertToPercentage(n) {
|
|
1990
|
+
if (n <= 1) {
|
|
1991
|
+
n = (n * 100) + "%";
|
|
1968
1992
|
}
|
|
1969
1993
|
|
|
1970
|
-
|
|
1994
|
+
return n;
|
|
1995
|
+
}
|
|
1971
1996
|
|
|
1972
|
-
|
|
1973
|
-
|
|
1997
|
+
// Converts a decimal to a hex value
|
|
1998
|
+
function convertDecimalToHex(d) {
|
|
1999
|
+
return Math.round(parseFloat(d) * 255).toString(16);
|
|
2000
|
+
}
|
|
2001
|
+
// Converts a hex value to a decimal
|
|
2002
|
+
function convertHexToDecimal(h) {
|
|
2003
|
+
return (parseIntFromHex(h) / 255);
|
|
2004
|
+
}
|
|
1974
2005
|
|
|
1975
|
-
|
|
1976
|
-
var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
|
|
2006
|
+
var matchers = (function() {
|
|
1977
2007
|
|
|
1978
|
-
|
|
1979
|
-
|
|
2008
|
+
// <http://www.w3.org/TR/css3-values/#integers>
|
|
2009
|
+
var CSS_INTEGER = "[-\\+]?\\d+%?";
|
|
1980
2010
|
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
// Whitespace can take the place of commas or opening paren
|
|
1984
|
-
var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
|
1985
|
-
var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
|
2011
|
+
// <http://www.w3.org/TR/css3-values/#number-value>
|
|
2012
|
+
var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
|
|
1986
2013
|
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
|
|
1990
|
-
hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
|
|
1991
|
-
hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
|
|
1992
|
-
hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
|
|
1993
|
-
hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
|
1994
|
-
hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
|
1995
|
-
hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
|
|
1996
|
-
};
|
|
1997
|
-
})();
|
|
2014
|
+
// Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
|
|
2015
|
+
var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
|
|
1998
2016
|
|
|
1999
|
-
//
|
|
2000
|
-
//
|
|
2001
|
-
//
|
|
2002
|
-
|
|
2017
|
+
// Actual matching.
|
|
2018
|
+
// Parentheses and commas are optional, but not required.
|
|
2019
|
+
// Whitespace can take the place of commas or opening paren
|
|
2020
|
+
var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
|
2021
|
+
var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
|
2003
2022
|
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
}
|
|
2023
|
+
return {
|
|
2024
|
+
rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
|
|
2025
|
+
rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
|
|
2026
|
+
hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
|
|
2027
|
+
hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
|
|
2028
|
+
hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
|
|
2029
|
+
hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
|
2030
|
+
hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
|
2031
|
+
hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
|
|
2032
|
+
};
|
|
2033
|
+
})();
|
|
2013
2034
|
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
var match;
|
|
2019
|
-
if ((match = matchers.rgb.exec(color))) {
|
|
2020
|
-
return { r: match[1], g: match[2], b: match[3] };
|
|
2021
|
-
}
|
|
2022
|
-
if ((match = matchers.rgba.exec(color))) {
|
|
2023
|
-
return { r: match[1], g: match[2], b: match[3], a: match[4] };
|
|
2024
|
-
}
|
|
2025
|
-
if ((match = matchers.hsl.exec(color))) {
|
|
2026
|
-
return { h: match[1], s: match[2], l: match[3] };
|
|
2027
|
-
}
|
|
2028
|
-
if ((match = matchers.hsla.exec(color))) {
|
|
2029
|
-
return { h: match[1], s: match[2], l: match[3], a: match[4] };
|
|
2030
|
-
}
|
|
2031
|
-
if ((match = matchers.hsv.exec(color))) {
|
|
2032
|
-
return { h: match[1], s: match[2], v: match[3] };
|
|
2033
|
-
}
|
|
2034
|
-
if ((match = matchers.hex8.exec(color))) {
|
|
2035
|
-
return {
|
|
2036
|
-
a: convertHexToDecimal(match[1]),
|
|
2037
|
-
r: parseIntFromHex(match[2]),
|
|
2038
|
-
g: parseIntFromHex(match[3]),
|
|
2039
|
-
b: parseIntFromHex(match[4]),
|
|
2040
|
-
format: named ? "name" : "hex8"
|
|
2041
|
-
};
|
|
2042
|
-
}
|
|
2043
|
-
if ((match = matchers.hex6.exec(color))) {
|
|
2044
|
-
return {
|
|
2045
|
-
r: parseIntFromHex(match[1]),
|
|
2046
|
-
g: parseIntFromHex(match[2]),
|
|
2047
|
-
b: parseIntFromHex(match[3]),
|
|
2048
|
-
format: named ? "name" : "hex"
|
|
2049
|
-
};
|
|
2050
|
-
}
|
|
2051
|
-
if ((match = matchers.hex3.exec(color))) {
|
|
2052
|
-
return {
|
|
2053
|
-
r: parseIntFromHex(match[1] + '' + match[1]),
|
|
2054
|
-
g: parseIntFromHex(match[2] + '' + match[2]),
|
|
2055
|
-
b: parseIntFromHex(match[3] + '' + match[3]),
|
|
2056
|
-
format: named ? "name" : "hex"
|
|
2057
|
-
};
|
|
2058
|
-
}
|
|
2035
|
+
// `stringInputToObject`
|
|
2036
|
+
// Permissive string parsing. Take in a number of formats, and output an object
|
|
2037
|
+
// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
|
|
2038
|
+
function stringInputToObject(color) {
|
|
2059
2039
|
|
|
2060
|
-
|
|
2040
|
+
color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
|
|
2041
|
+
var named = false;
|
|
2042
|
+
if (names[color]) {
|
|
2043
|
+
color = names[color];
|
|
2044
|
+
named = true;
|
|
2045
|
+
}
|
|
2046
|
+
else if (color == 'transparent') {
|
|
2047
|
+
return { r: 0, g: 0, b: 0, a: 0, format: "name" };
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
// Try to match string input using regular expressions.
|
|
2051
|
+
// Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
|
|
2052
|
+
// Just return an object and let the conversion functions handle that.
|
|
2053
|
+
// This way the result will be the same whether the tinycolor is initialized with string or object.
|
|
2054
|
+
var match;
|
|
2055
|
+
if ((match = matchers.rgb.exec(color))) {
|
|
2056
|
+
return { r: match[1], g: match[2], b: match[3] };
|
|
2057
|
+
}
|
|
2058
|
+
if ((match = matchers.rgba.exec(color))) {
|
|
2059
|
+
return { r: match[1], g: match[2], b: match[3], a: match[4] };
|
|
2060
|
+
}
|
|
2061
|
+
if ((match = matchers.hsl.exec(color))) {
|
|
2062
|
+
return { h: match[1], s: match[2], l: match[3] };
|
|
2063
|
+
}
|
|
2064
|
+
if ((match = matchers.hsla.exec(color))) {
|
|
2065
|
+
return { h: match[1], s: match[2], l: match[3], a: match[4] };
|
|
2066
|
+
}
|
|
2067
|
+
if ((match = matchers.hsv.exec(color))) {
|
|
2068
|
+
return { h: match[1], s: match[2], v: match[3] };
|
|
2069
|
+
}
|
|
2070
|
+
if ((match = matchers.hex8.exec(color))) {
|
|
2071
|
+
return {
|
|
2072
|
+
a: convertHexToDecimal(match[1]),
|
|
2073
|
+
r: parseIntFromHex(match[2]),
|
|
2074
|
+
g: parseIntFromHex(match[3]),
|
|
2075
|
+
b: parseIntFromHex(match[4]),
|
|
2076
|
+
format: named ? "name" : "hex8"
|
|
2077
|
+
};
|
|
2078
|
+
}
|
|
2079
|
+
if ((match = matchers.hex6.exec(color))) {
|
|
2080
|
+
return {
|
|
2081
|
+
r: parseIntFromHex(match[1]),
|
|
2082
|
+
g: parseIntFromHex(match[2]),
|
|
2083
|
+
b: parseIntFromHex(match[3]),
|
|
2084
|
+
format: named ? "name" : "hex"
|
|
2085
|
+
};
|
|
2086
|
+
}
|
|
2087
|
+
if ((match = matchers.hex3.exec(color))) {
|
|
2088
|
+
return {
|
|
2089
|
+
r: parseIntFromHex(match[1] + '' + match[1]),
|
|
2090
|
+
g: parseIntFromHex(match[2] + '' + match[2]),
|
|
2091
|
+
b: parseIntFromHex(match[3] + '' + match[3]),
|
|
2092
|
+
format: named ? "name" : "hex"
|
|
2093
|
+
};
|
|
2061
2094
|
}
|
|
2062
2095
|
|
|
2063
|
-
|
|
2064
|
-
|
|
2096
|
+
return false;
|
|
2097
|
+
}
|
|
2065
2098
|
|
|
2099
|
+
window.tinycolor = tinycolor;
|
|
2066
2100
|
})();
|
|
2067
2101
|
|
|
2068
2102
|
|