-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsort_options.js
156 lines (130 loc) · 4.4 KB
/
sort_options.js
1
2
3
4
5
6
7
8
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// All sort modes take in a color array ([r, g, b, a]) and return a numeric value
//
// In: [10, 22, 53, 255]
// Out: 114.4
//
const SORT_MODES = {
'Hue': { 'max': 360, 'func': getHue },
'Saturation': { 'max': 100, 'func': getSaturation },
'Brightness': { 'max': 255, 'func': getBrightness },
'Lightness': { 'max': 255, 'func': getLightness },
'Luminance': { 'max': 255, 'func': getLuminance },
'Chroma': { 'max': 255, 'func': getChroma },
'Absolute': { 'max': 255 * 3, 'func': (c) => c[0] + c[1] + c[2] },
'Red': { 'max': 255, 'func': (c) => c[0] },
'Green': { 'max': 255, 'func': (c) => c[1] },
'Blue': { 'max': 255, 'func': (c) => c[2] },
'Cyan': { 'max': 510, 'func': (c) => c[1] + c[2] },
'Yellow': { 'max': 510, 'func': (c) => c[0] + c[1] },
'Magenta': { 'max': 510, 'func': (c) => c[0] + c[2] },
'Hue + Luminance': { 'max': 360 + 255, 'func': (c) => getHue(c) + getLuminance(c) },
'Hue ÷ Saturation': { 'max': 360 / 100, 'func': (c) => getHue(c) + getSaturation(c) },
'Hue x Saturation': { 'max': 360 * 100, 'func': (c) => getHue(c) * getSaturation(c) },
'Hue + Sat + Bri': { 'max': 360 + 100 + 100, 'func': (c) => getHue(c) + getSaturation(c) + getBrightness(c) },
'Experimental': { 'max': 360 + (100 * 100), 'func': (c) => getHue(c) + (getSaturation(c) * getBrightness(c)) },
'Red x Green': { 'max': 255 * 255, 'func': (c) => (c[0] + 1) / (c[1] + 1) },
'Red x Blue': { 'max': 255 * 255, 'func': (c) => (c[0] + 1) / (c[2] + 1) },
'Green x Blue': { 'max': 255 * 255, 'func': (c) => (c[1] + 1) / (c[2] + 1) },
'Black/White(2)': { 'max': 2, 'func': (c) => int((c[0] + c[1] + c[2]) / 128 / 3) },
'Grey Shades(8)': { 'max': 8, 'func': (c) => int((c[0] + c[1] + c[2]) / 32 / 3) },
// Need to figure out max value before enabling.
// 'Hash V1': { 'max': null, 'func': (c) => getHashV1(c) },
// 'Hash V2': { 'max': null, 'func': (c) => getHashV2(c) },
}
//
// Helper functions to keep SORT_MODES short and readable
//
// Taken from p5js
// Original: p5.ColorConversion._rgbaToHSBA
function getHue(rgba) {
let red = rgba[0];
let green = rgba[1];
let blue = rgba[2];
let val = Math.max(red, green, blue);
let chroma = val - Math.min(red, green, blue);
let hue, sat;
if (chroma === 0) { // Return early if grayscale.
hue = 0;
sat = 0;
}
else {
// sat = chroma / val;
if (red === val) { // Magenta to yellow.
hue = (green - blue) / chroma;
} else if (green === val) { // Yellow to cyan.
hue = 2 + (blue - red) / chroma;
} else if (blue === val) { // Cyan to magenta.
hue = 4 + (red - green) / chroma;
}
if (hue < 0) { // Confine hue to the interval [0, 1).
hue += 6;
} else if (hue >= 6) {
hue -= 6;
}
}
return int(hue / 6 * 360);
};
function getSaturation(rgba) {
let red = rgba[0];
let green = rgba[1];
let blue = rgba[2];
let val = Math.max(red, green, blue);
let chroma = val - Math.min(red, green, blue);
let sat;
if (chroma === 0) { // Return early if grayscale.
sat = 0;
}
else {
sat = chroma / val;
}
return int(sat * 100);
};
function getBrightness(rgba) {
let red = rgba[0];
let green = rgba[1];
let blue = rgba[2];
let val = Math.max(red, green, blue);
return int(val);
};
function getLightness(rgba) {
let red = rgba[0];
let green = rgba[1];
let blue = rgba[2];
let val = Math.max(red, green, blue);
let min = Math.min(red, green, blue);
let li = (val + min) / 2;
return int(li);
}
function getLuminance(c) {
return int(0.299 * c[0] + 0.587 * c[1] + 0.114 * c[2]);
}
function getChroma(c) {
let red = c[0];
let blue = c[1];
let green = c[2];
let val = Math.max(red, green, blue);
let chroma = val - Math.min(red, green, blue);
return int(chroma);
}
function getHashV1(rgba) {
let s = rgba[0].toString() + rgba[1].toString() + rgba[2].toString();
let hash = 0;
for (let i = 0; i < s.length; i += 1) {
let c = s.charCodeAt(i);
hash = ((hash<<5)-hash) + c;
hash = hash & hash;
}
return hash;
}
function getHashV2(rgba) {
let str = rgba[0].toString() + rgba[1].toString() + rgba[2].toString();
let hash = 5381;
let i = str.length;
while (i) {
hash = (hash * 33) ^ str.charCodeAt(--i);
}
/* JavaScript does bitwise operations (like XOR, above) on 32-bit signed
* integers. Since we want the results to be always positive, convert the
* signed int to an unsigned by doing an unsigned bitshift. */
return hash >>> 0;
}