@thednp/color-picker 0.0.2-alpha1 → 0.0.2-alpha2
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.
- package/README.md +2 -1
- package/dist/js/color-esm.js +94 -105
- package/dist/js/color-esm.min.js +2 -2
- package/dist/js/color-palette-esm.js +105 -119
- package/dist/js/color-palette-esm.min.js +2 -2
- package/dist/js/color-palette.js +105 -119
- package/dist/js/color-palette.min.js +2 -2
- package/dist/js/color-picker-element-esm.js +279 -375
- package/dist/js/color-picker-element-esm.min.js +2 -2
- package/dist/js/color-picker-element.js +279 -375
- package/dist/js/color-picker-element.min.js +2 -2
- package/dist/js/color-picker-esm.js +235 -323
- package/dist/js/color-picker-esm.min.js +2 -2
- package/dist/js/color-picker.js +235 -323
- package/dist/js/color-picker.min.js +2 -2
- package/dist/js/color.js +94 -105
- package/dist/js/color.min.js +2 -2
- package/package.json +7 -4
- package/src/js/color-palette.js +10 -13
- package/src/js/color-picker-element.js +46 -54
- package/src/js/color-picker.js +131 -206
- package/src/js/color.js +93 -106
- package/types/cp.d.ts +31 -29
- package/types/source/types.d.ts +1 -1
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* ColorPicker v0.0.
|
2
|
+
* ColorPicker v0.0.2alpha2 (http://thednp.github.io/color-picker)
|
3
3
|
* Copyright 2022 © thednp
|
4
4
|
* Licensed under MIT (https://github.com/thednp/color-picker/blob/master/LICENSE)
|
5
5
|
*/
|
@@ -837,6 +837,8 @@ function isColorName(color) {
|
|
837
837
|
if (nonColors.includes(color)
|
838
838
|
|| ['#', ...COLOR_FORMAT].some((f) => color.includes(f))) return false;
|
839
839
|
|
840
|
+
if (['black', 'white'].includes(color)) return true;
|
841
|
+
|
840
842
|
return ['rgb(255, 255, 255)', 'rgb(0, 0, 0)'].every((c) => {
|
841
843
|
setElementStyle(documentHead, { color });
|
842
844
|
const computedColor = getElementStyle(documentHead, 'color');
|
@@ -863,6 +865,11 @@ function isValidCSSUnit(color) {
|
|
863
865
|
*/
|
864
866
|
function bound01(N, max) {
|
865
867
|
let n = N;
|
868
|
+
|
869
|
+
if (typeof N === 'number'
|
870
|
+
&& Math.min(N, 0) === 0 // round values to 6 decimals Math.round(N * (10 ** 6)) / 10 ** 6
|
871
|
+
&& Math.max(N, 1) === 1) return N;
|
872
|
+
|
866
873
|
if (isOnePointZero(N)) n = '100%';
|
867
874
|
|
868
875
|
const processPercent = isPercentage(n);
|
@@ -966,15 +973,12 @@ function pad2(c) {
|
|
966
973
|
/**
|
967
974
|
* Converts an RGB colour value to HSL.
|
968
975
|
*
|
969
|
-
* @param {number}
|
970
|
-
* @param {number}
|
971
|
-
* @param {number}
|
976
|
+
* @param {number} r Red component [0, 1]
|
977
|
+
* @param {number} g Green component [0, 1]
|
978
|
+
* @param {number} b Blue component [0, 1]
|
972
979
|
* @returns {CP.HSL} {h,s,l} object with [0, 1] ranged values
|
973
980
|
*/
|
974
|
-
function rgbToHsl(
|
975
|
-
const r = R / 255;
|
976
|
-
const g = G / 255;
|
977
|
-
const b = B / 255;
|
981
|
+
function rgbToHsl(r, g, b) {
|
978
982
|
const max = Math.max(r, g, b);
|
979
983
|
const min = Math.min(r, g, b);
|
980
984
|
let h = 0;
|
@@ -986,17 +990,10 @@ function rgbToHsl(R, G, B) {
|
|
986
990
|
} else {
|
987
991
|
const d = max - min;
|
988
992
|
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
case g:
|
994
|
-
h = (b - r) / d + 2;
|
995
|
-
break;
|
996
|
-
case b:
|
997
|
-
h = (r - g) / d + 4;
|
998
|
-
break;
|
999
|
-
}
|
993
|
+
if (max === r) h = (g - b) / d + (g < b ? 6 : 0);
|
994
|
+
if (max === g) h = (b - r) / d + 2;
|
995
|
+
if (max === b) h = (r - g) / d + 4;
|
996
|
+
|
1000
997
|
h /= 6;
|
1001
998
|
}
|
1002
999
|
return { h, s, l };
|
@@ -1025,7 +1022,7 @@ function hueToRgb(p, q, t) {
|
|
1025
1022
|
* @param {number} h Hue Angle [0, 1]
|
1026
1023
|
* @param {number} s Saturation [0, 1]
|
1027
1024
|
* @param {number} l Lightness Angle [0, 1]
|
1028
|
-
* @returns {CP.RGB} {r,g,b} object with [0,
|
1025
|
+
* @returns {CP.RGB} {r,g,b} object with [0, 1] ranged values
|
1029
1026
|
*/
|
1030
1027
|
function hslToRgb(h, s, l) {
|
1031
1028
|
let r = 0;
|
@@ -1044,7 +1041,6 @@ function hslToRgb(h, s, l) {
|
|
1044
1041
|
g = hueToRgb(p, q, h);
|
1045
1042
|
b = hueToRgb(p, q, h - 1 / 3);
|
1046
1043
|
}
|
1047
|
-
[r, g, b] = [r, g, b].map((x) => x * 255);
|
1048
1044
|
|
1049
1045
|
return { r, g, b };
|
1050
1046
|
}
|
@@ -1054,16 +1050,12 @@ function hslToRgb(h, s, l) {
|
|
1054
1050
|
* @link https://www.w3.org/TR/css-color-4/#hwb-to-rgb
|
1055
1051
|
* @link http://alvyray.com/Papers/CG/hwb2rgb.htm
|
1056
1052
|
*
|
1057
|
-
* @param {number}
|
1058
|
-
* @param {number}
|
1059
|
-
* @param {number}
|
1053
|
+
* @param {number} r Red component [0, 1]
|
1054
|
+
* @param {number} g Green [0, 1]
|
1055
|
+
* @param {number} b Blue [0, 1]
|
1060
1056
|
* @return {CP.HWB} {h,w,b} object with [0, 1] ranged values
|
1061
1057
|
*/
|
1062
|
-
function rgbToHwb(
|
1063
|
-
const r = R / 255;
|
1064
|
-
const g = G / 255;
|
1065
|
-
const b = B / 255;
|
1066
|
-
|
1058
|
+
function rgbToHwb(r, g, b) {
|
1067
1059
|
let f = 0;
|
1068
1060
|
let i = 0;
|
1069
1061
|
const whiteness = Math.min(r, g, b);
|
@@ -1093,20 +1085,18 @@ function rgbToHwb(R, G, B) {
|
|
1093
1085
|
* @param {number} H Hue Angle [0, 1]
|
1094
1086
|
* @param {number} W Whiteness [0, 1]
|
1095
1087
|
* @param {number} B Blackness [0, 1]
|
1096
|
-
* @return {CP.RGB} {r,g,b} object with [0,
|
1088
|
+
* @return {CP.RGB} {r,g,b} object with [0, 1] ranged values
|
1097
1089
|
*
|
1098
1090
|
* @link https://www.w3.org/TR/css-color-4/#hwb-to-rgb
|
1099
1091
|
* @link http://alvyray.com/Papers/CG/hwb2rgb.htm
|
1100
1092
|
*/
|
1101
1093
|
function hwbToRgb(H, W, B) {
|
1102
1094
|
if (W + B >= 1) {
|
1103
|
-
const gray =
|
1095
|
+
const gray = W / (W + B);
|
1104
1096
|
return { r: gray, g: gray, b: gray };
|
1105
1097
|
}
|
1106
1098
|
let { r, g, b } = hslToRgb(H, 1, 0.5);
|
1107
|
-
[r, g, b] = [r, g, b]
|
1108
|
-
.map((v) => (v / 255) * (1 - W - B) + W)
|
1109
|
-
.map((v) => v * 255);
|
1099
|
+
[r, g, b] = [r, g, b].map((v) => v * (1 - W - B) + W);
|
1110
1100
|
|
1111
1101
|
return { r, g, b };
|
1112
1102
|
}
|
@@ -1114,15 +1104,12 @@ function hwbToRgb(H, W, B) {
|
|
1114
1104
|
/**
|
1115
1105
|
* Converts an RGB colour value to HSV.
|
1116
1106
|
*
|
1117
|
-
* @param {number}
|
1118
|
-
* @param {number}
|
1119
|
-
* @param {number}
|
1107
|
+
* @param {number} r Red component [0, 1]
|
1108
|
+
* @param {number} g Green [0, 1]
|
1109
|
+
* @param {number} b Blue [0, 1]
|
1120
1110
|
* @returns {CP.HSV} {h,s,v} object with [0, 1] ranged values
|
1121
1111
|
*/
|
1122
|
-
function rgbToHsv(
|
1123
|
-
const r = R / 255;
|
1124
|
-
const g = G / 255;
|
1125
|
-
const b = B / 255;
|
1112
|
+
function rgbToHsv(r, g, b) {
|
1126
1113
|
const max = Math.max(r, g, b);
|
1127
1114
|
const min = Math.min(r, g, b);
|
1128
1115
|
let h = 0;
|
@@ -1132,17 +1119,10 @@ function rgbToHsv(R, G, B) {
|
|
1132
1119
|
if (max === min) {
|
1133
1120
|
h = 0; // achromatic
|
1134
1121
|
} else {
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
case g:
|
1140
|
-
h = (b - r) / d + 2;
|
1141
|
-
break;
|
1142
|
-
case b:
|
1143
|
-
h = (r - g) / d + 4;
|
1144
|
-
break;
|
1145
|
-
}
|
1122
|
+
if (r === max) h = (g - b) / d + (g < b ? 6 : 0);
|
1123
|
+
if (g === max) h = (b - r) / d + 2;
|
1124
|
+
if (b === max) h = (r - g) / d + 4;
|
1125
|
+
|
1146
1126
|
h /= 6;
|
1147
1127
|
}
|
1148
1128
|
return { h, s, v };
|
@@ -1166,10 +1146,9 @@ function hsvToRgb(H, S, V) {
|
|
1166
1146
|
const q = v * (1 - f * s);
|
1167
1147
|
const t = v * (1 - (1 - f) * s);
|
1168
1148
|
const mod = i % 6;
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
[r, g, b] = [r, g, b].map((n) => n * 255);
|
1149
|
+
const r = [v, q, p, p, t, v][mod];
|
1150
|
+
const g = [t, v, v, q, p, p][mod];
|
1151
|
+
const b = [p, p, t, v, v, q][mod];
|
1173
1152
|
return { r, g, b };
|
1174
1153
|
}
|
1175
1154
|
|
@@ -1237,15 +1216,15 @@ function rgbaToHex(r, g, b, a, allow4Char) {
|
|
1237
1216
|
*/
|
1238
1217
|
function stringInputToObject(input) {
|
1239
1218
|
let color = toLowerCase(input.trim());
|
1219
|
+
|
1240
1220
|
if (color.length === 0) {
|
1241
1221
|
return {
|
1242
1222
|
r: 0, g: 0, b: 0, a: 1,
|
1243
1223
|
};
|
1244
1224
|
}
|
1245
|
-
|
1225
|
+
|
1246
1226
|
if (isColorName(color)) {
|
1247
1227
|
color = getRGBFromName(color);
|
1248
|
-
named = true;
|
1249
1228
|
} else if (nonColors.includes(color)) {
|
1250
1229
|
const a = color === 'transparent' ? 0 : 1;
|
1251
1230
|
return {
|
@@ -1264,24 +1243,28 @@ function stringInputToObject(input) {
|
|
1264
1243
|
r: m1, g: m2, b: m3, a: m4 !== undefined ? m4 : 1, format: 'rgb',
|
1265
1244
|
};
|
1266
1245
|
}
|
1246
|
+
|
1267
1247
|
[, m1, m2, m3, m4] = matchers.hsl.exec(color) || [];
|
1268
1248
|
if (m1 && m2 && m3/* && m4 */) {
|
1269
1249
|
return {
|
1270
1250
|
h: m1, s: m2, l: m3, a: m4 !== undefined ? m4 : 1, format: 'hsl',
|
1271
1251
|
};
|
1272
1252
|
}
|
1253
|
+
|
1273
1254
|
[, m1, m2, m3, m4] = matchers.hsv.exec(color) || [];
|
1274
1255
|
if (m1 && m2 && m3/* && m4 */) {
|
1275
1256
|
return {
|
1276
1257
|
h: m1, s: m2, v: m3, a: m4 !== undefined ? m4 : 1, format: 'hsv',
|
1277
1258
|
};
|
1278
1259
|
}
|
1260
|
+
|
1279
1261
|
[, m1, m2, m3, m4] = matchers.hwb.exec(color) || [];
|
1280
1262
|
if (m1 && m2 && m3) {
|
1281
1263
|
return {
|
1282
1264
|
h: m1, w: m2, b: m3, a: m4 !== undefined ? m4 : 1, format: 'hwb',
|
1283
1265
|
};
|
1284
1266
|
}
|
1267
|
+
|
1285
1268
|
[, m1, m2, m3, m4] = matchers.hex8.exec(color) || [];
|
1286
1269
|
if (m1 && m2 && m3 && m4) {
|
1287
1270
|
return {
|
@@ -1289,18 +1272,20 @@ function stringInputToObject(input) {
|
|
1289
1272
|
g: parseIntFromHex(m2),
|
1290
1273
|
b: parseIntFromHex(m3),
|
1291
1274
|
a: convertHexToDecimal(m4),
|
1292
|
-
format:
|
1275
|
+
format: 'hex',
|
1293
1276
|
};
|
1294
1277
|
}
|
1278
|
+
|
1295
1279
|
[, m1, m2, m3] = matchers.hex6.exec(color) || [];
|
1296
1280
|
if (m1 && m2 && m3) {
|
1297
1281
|
return {
|
1298
1282
|
r: parseIntFromHex(m1),
|
1299
1283
|
g: parseIntFromHex(m2),
|
1300
1284
|
b: parseIntFromHex(m3),
|
1301
|
-
format:
|
1285
|
+
format: 'hex',
|
1302
1286
|
};
|
1303
1287
|
}
|
1288
|
+
|
1304
1289
|
[, m1, m2, m3, m4] = matchers.hex4.exec(color) || [];
|
1305
1290
|
if (m1 && m2 && m3 && m4) {
|
1306
1291
|
return {
|
@@ -1308,19 +1293,20 @@ function stringInputToObject(input) {
|
|
1308
1293
|
g: parseIntFromHex(m2 + m2),
|
1309
1294
|
b: parseIntFromHex(m3 + m3),
|
1310
1295
|
a: convertHexToDecimal(m4 + m4),
|
1311
|
-
|
1312
|
-
format: named ? 'rgb' : 'hex',
|
1296
|
+
format: 'hex',
|
1313
1297
|
};
|
1314
1298
|
}
|
1299
|
+
|
1315
1300
|
[, m1, m2, m3] = matchers.hex3.exec(color) || [];
|
1316
1301
|
if (m1 && m2 && m3) {
|
1317
1302
|
return {
|
1318
1303
|
r: parseIntFromHex(m1 + m1),
|
1319
1304
|
g: parseIntFromHex(m2 + m2),
|
1320
1305
|
b: parseIntFromHex(m3 + m3),
|
1321
|
-
format:
|
1306
|
+
format: 'hex',
|
1322
1307
|
};
|
1323
1308
|
}
|
1309
|
+
|
1324
1310
|
return false;
|
1325
1311
|
}
|
1326
1312
|
|
@@ -1351,6 +1337,7 @@ function stringInputToObject(input) {
|
|
1351
1337
|
*/
|
1352
1338
|
function inputToRGB(input) {
|
1353
1339
|
let rgb = { r: 0, g: 0, b: 0 };
|
1340
|
+
/** @type {*} */
|
1354
1341
|
let color = input;
|
1355
1342
|
/** @type {string | number} */
|
1356
1343
|
let a = 1;
|
@@ -1367,39 +1354,41 @@ function inputToRGB(input) {
|
|
1367
1354
|
let format = inputFormat && COLOR_FORMAT.includes(inputFormat) ? inputFormat : 'rgb';
|
1368
1355
|
|
1369
1356
|
if (typeof input === 'string') {
|
1370
|
-
// @ts-ignore -- this now is converted to object
|
1371
1357
|
color = stringInputToObject(input);
|
1372
1358
|
if (color) ok = true;
|
1373
1359
|
}
|
1374
1360
|
if (typeof color === 'object') {
|
1375
1361
|
if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {
|
1376
1362
|
({ r, g, b } = color);
|
1377
|
-
// RGB values now are all in [0,
|
1378
|
-
[r, g, b] = [r, g, b].map((n) => bound01(n, isPercentage(n) ? 100 : 255)
|
1363
|
+
// RGB values now are all in [0, 1] range
|
1364
|
+
[r, g, b] = [r, g, b].map((n) => bound01(n, isPercentage(n) ? 100 : 255));
|
1379
1365
|
rgb = { r, g, b };
|
1380
1366
|
ok = true;
|
1381
|
-
format = 'rgb';
|
1382
|
-
}
|
1367
|
+
format = color.format || 'rgb';
|
1368
|
+
}
|
1369
|
+
if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {
|
1383
1370
|
({ h, s, v } = color);
|
1384
|
-
h =
|
1385
|
-
s =
|
1386
|
-
v =
|
1371
|
+
h = bound01(h, 360); // hue can be `5deg` or a [0, 1] value
|
1372
|
+
s = bound01(s, 100); // saturation can be `5%` or a [0, 1] value
|
1373
|
+
v = bound01(v, 100); // brightness can be `5%` or a [0, 1] value
|
1387
1374
|
rgb = hsvToRgb(h, s, v);
|
1388
1375
|
ok = true;
|
1389
1376
|
format = 'hsv';
|
1390
|
-
}
|
1377
|
+
}
|
1378
|
+
if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) {
|
1391
1379
|
({ h, s, l } = color);
|
1392
|
-
h =
|
1393
|
-
s =
|
1394
|
-
l =
|
1380
|
+
h = bound01(h, 360); // hue can be `5deg` or a [0, 1] value
|
1381
|
+
s = bound01(s, 100); // saturation can be `5%` or a [0, 1] value
|
1382
|
+
l = bound01(l, 100); // lightness can be `5%` or a [0, 1] value
|
1395
1383
|
rgb = hslToRgb(h, s, l);
|
1396
1384
|
ok = true;
|
1397
1385
|
format = 'hsl';
|
1398
|
-
}
|
1386
|
+
}
|
1387
|
+
if (isValidCSSUnit(color.h) && isValidCSSUnit(color.w) && isValidCSSUnit(color.b)) {
|
1399
1388
|
({ h, w, b } = color);
|
1400
|
-
h =
|
1401
|
-
w =
|
1402
|
-
b =
|
1389
|
+
h = bound01(h, 360); // hue can be `5deg` or a [0, 1] value
|
1390
|
+
w = bound01(w, 100); // whiteness can be `5%` or a [0, 1] value
|
1391
|
+
b = bound01(b, 100); // blackness can be `5%` or a [0, 1] value
|
1403
1392
|
rgb = hwbToRgb(h, w, b);
|
1404
1393
|
ok = true;
|
1405
1394
|
format = 'hwb';
|
@@ -1416,9 +1405,12 @@ function inputToRGB(input) {
|
|
1416
1405
|
return {
|
1417
1406
|
ok,
|
1418
1407
|
format,
|
1419
|
-
r: Math.min(255, Math.max(rgb.r, 0)),
|
1420
|
-
g: Math.min(255, Math.max(rgb.g, 0)),
|
1421
|
-
b: Math.min(255, Math.max(rgb.b, 0)),
|
1408
|
+
// r: Math.min(255, Math.max(rgb.r, 0)),
|
1409
|
+
// g: Math.min(255, Math.max(rgb.g, 0)),
|
1410
|
+
// b: Math.min(255, Math.max(rgb.b, 0)),
|
1411
|
+
r: rgb.r,
|
1412
|
+
g: rgb.g,
|
1413
|
+
b: rgb.b,
|
1422
1414
|
a: boundAlpha(a),
|
1423
1415
|
};
|
1424
1416
|
}
|
@@ -1437,16 +1429,13 @@ class Color {
|
|
1437
1429
|
constructor(input, config) {
|
1438
1430
|
let color = input;
|
1439
1431
|
const configFormat = config && COLOR_FORMAT.includes(config)
|
1440
|
-
? config : '
|
1432
|
+
? config : '';
|
1441
1433
|
|
1442
|
-
// If input is already a `Color`,
|
1434
|
+
// If input is already a `Color`, clone its values
|
1443
1435
|
if (color instanceof Color) {
|
1444
1436
|
color = inputToRGB(color);
|
1445
1437
|
}
|
1446
|
-
|
1447
|
-
const len = `${color}`.length;
|
1448
|
-
color = `#${(len === 2 ? '0' : '00')}${color}`;
|
1449
|
-
}
|
1438
|
+
|
1450
1439
|
const {
|
1451
1440
|
r, g, b, a, ok, format,
|
1452
1441
|
} = inputToRGB(color);
|
@@ -1496,24 +1485,21 @@ class Color {
|
|
1496
1485
|
let R = 0;
|
1497
1486
|
let G = 0;
|
1498
1487
|
let B = 0;
|
1499
|
-
const rp = r / 255;
|
1500
|
-
const rg = g / 255;
|
1501
|
-
const rb = b / 255;
|
1502
1488
|
|
1503
|
-
if (
|
1504
|
-
R =
|
1489
|
+
if (r <= 0.03928) {
|
1490
|
+
R = r / 12.92;
|
1505
1491
|
} else {
|
1506
|
-
R = ((
|
1492
|
+
R = ((r + 0.055) / 1.055) ** 2.4;
|
1507
1493
|
}
|
1508
|
-
if (
|
1509
|
-
G =
|
1494
|
+
if (g <= 0.03928) {
|
1495
|
+
G = g / 12.92;
|
1510
1496
|
} else {
|
1511
|
-
G = ((
|
1497
|
+
G = ((g + 0.055) / 1.055) ** 2.4;
|
1512
1498
|
}
|
1513
|
-
if (
|
1514
|
-
B =
|
1499
|
+
if (b <= 0.03928) {
|
1500
|
+
B = b / 12.92;
|
1515
1501
|
} else {
|
1516
|
-
B = ((
|
1502
|
+
B = ((b + 0.055) / 1.055) ** 2.4;
|
1517
1503
|
}
|
1518
1504
|
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
|
1519
1505
|
}
|
@@ -1523,7 +1509,7 @@ class Color {
|
|
1523
1509
|
* @returns {number} a number in the [0, 255] range
|
1524
1510
|
*/
|
1525
1511
|
get brightness() {
|
1526
|
-
const { r, g, b } = this;
|
1512
|
+
const { r, g, b } = this.toRgb();
|
1527
1513
|
return (r * 299 + g * 587 + b * 114) / 1000;
|
1528
1514
|
}
|
1529
1515
|
|
@@ -1532,12 +1518,14 @@ class Color {
|
|
1532
1518
|
* @returns {CP.RGBA} an {r,g,b,a} object with [0, 255] ranged values
|
1533
1519
|
*/
|
1534
1520
|
toRgb() {
|
1535
|
-
|
1521
|
+
let {
|
1536
1522
|
r, g, b, a,
|
1537
1523
|
} = this;
|
1538
1524
|
|
1525
|
+
[r, g, b] = [r, g, b].map((n) => roundPart(n * 255 * 100) / 100);
|
1526
|
+
a = roundPart(a * 100) / 100;
|
1539
1527
|
return {
|
1540
|
-
r, g, b, a
|
1528
|
+
r, g, b, a,
|
1541
1529
|
};
|
1542
1530
|
}
|
1543
1531
|
|
@@ -1631,7 +1619,7 @@ class Color {
|
|
1631
1619
|
toHsv() {
|
1632
1620
|
const {
|
1633
1621
|
r, g, b, a,
|
1634
|
-
} = this
|
1622
|
+
} = this;
|
1635
1623
|
const { h, s, v } = rgbToHsv(r, g, b);
|
1636
1624
|
|
1637
1625
|
return {
|
@@ -1646,7 +1634,7 @@ class Color {
|
|
1646
1634
|
toHsl() {
|
1647
1635
|
const {
|
1648
1636
|
r, g, b, a,
|
1649
|
-
} = this
|
1637
|
+
} = this;
|
1650
1638
|
const { h, s, l } = rgbToHsl(r, g, b);
|
1651
1639
|
|
1652
1640
|
return {
|
@@ -1731,6 +1719,7 @@ class Color {
|
|
1731
1719
|
*/
|
1732
1720
|
setAlpha(alpha) {
|
1733
1721
|
const self = this;
|
1722
|
+
if (typeof alpha !== 'number') return self;
|
1734
1723
|
self.a = boundAlpha(alpha);
|
1735
1724
|
return self;
|
1736
1725
|
}
|
@@ -1897,26 +1886,23 @@ class ColorPalette {
|
|
1897
1886
|
} else if (args.length === 2) {
|
1898
1887
|
[hueSteps, lightSteps] = args;
|
1899
1888
|
if ([hueSteps, lightSteps].some((n) => n < 1)) {
|
1900
|
-
throw TypeError('ColorPalette:
|
1889
|
+
throw TypeError('ColorPalette: both arguments must be higher than 0.');
|
1901
1890
|
}
|
1902
|
-
} else {
|
1903
|
-
throw TypeError('ColorPalette requires minimum 2 arguments');
|
1904
1891
|
}
|
1905
1892
|
|
1906
|
-
/** @type {
|
1893
|
+
/** @type {*} */
|
1907
1894
|
const colors = [];
|
1908
|
-
|
1909
1895
|
const hueStep = 360 / hueSteps;
|
1910
1896
|
const half = roundPart((lightSteps - (lightSteps % 2 ? 1 : 0)) / 2);
|
1911
|
-
const
|
1897
|
+
const steps1To13 = [0.25, 0.2, 0.15, 0.11, 0.09, 0.075];
|
1898
|
+
const lightSets = [[1, 2, 3], [4, 5], [6, 7], [8, 9], [10, 11], [12, 13]];
|
1899
|
+
const closestSet = lightSets.find((set) => set.includes(lightSteps));
|
1912
1900
|
|
1913
|
-
|
1914
|
-
|
1915
|
-
lightStep =
|
1916
|
-
|
1917
|
-
|
1918
|
-
lightStep = [12, 13].includes(lightSteps) ? 0.075 : lightStep;
|
1919
|
-
lightStep = lightSteps > 13 ? estimatedStep : lightStep;
|
1901
|
+
// find a lightStep that won't go beyond black and white
|
1902
|
+
// something within the [10-90] range of lightness
|
1903
|
+
const lightStep = closestSet
|
1904
|
+
? steps1To13[lightSets.indexOf(closestSet)]
|
1905
|
+
: (100 / (lightSteps + (lightSteps % 2 ? 0 : 1)) / 100);
|
1920
1906
|
|
1921
1907
|
// light tints
|
1922
1908
|
for (let i = 1; i < half + 1; i += 1) {
|
@@ -2431,7 +2417,7 @@ function setMarkup(self) {
|
|
2431
2417
|
setAttribute(input, tabIndex, '-1');
|
2432
2418
|
}
|
2433
2419
|
|
2434
|
-
var version = "0.0.
|
2420
|
+
var version = "0.0.2alpha2";
|
2435
2421
|
|
2436
2422
|
// @ts-ignore
|
2437
2423
|
|
@@ -2474,8 +2460,6 @@ function toggleEvents(self, action) {
|
|
2474
2460
|
fn(input, focusinEvent, self.showPicker);
|
2475
2461
|
fn(pickerToggle, mouseclickEvent, self.togglePicker);
|
2476
2462
|
|
2477
|
-
fn(input, keydownEvent, self.keyToggle);
|
2478
|
-
|
2479
2463
|
if (menuToggle) {
|
2480
2464
|
fn(menuToggle, mouseclickEvent, self.toggleMenu);
|
2481
2465
|
}
|
@@ -2513,8 +2497,7 @@ function toggleEventsOnShown(self, action) {
|
|
2513
2497
|
fn(doc, pointerEvents.move, self.pointerMove);
|
2514
2498
|
fn(doc, pointerEvents.up, self.pointerUp);
|
2515
2499
|
fn(parent, focusoutEvent, self.handleFocusOut);
|
2516
|
-
|
2517
|
-
fn(win, keyupEvent, self.handleDismiss);
|
2500
|
+
fn(doc, keyupEvent, self.handleDismiss);
|
2518
2501
|
}
|
2519
2502
|
|
2520
2503
|
/**
|
@@ -2598,7 +2581,7 @@ class ColorPicker {
|
|
2598
2581
|
const input = querySelector(target);
|
2599
2582
|
|
2600
2583
|
// invalidate
|
2601
|
-
if (!input) throw new TypeError(`ColorPicker target ${target} cannot be found.`);
|
2584
|
+
if (!input) throw new TypeError(`ColorPicker target "${target}" cannot be found.`);
|
2602
2585
|
self.input = input;
|
2603
2586
|
|
2604
2587
|
const parent = closest(input, colorPickerParentSelector);
|
@@ -2645,15 +2628,14 @@ class ColorPicker {
|
|
2645
2628
|
});
|
2646
2629
|
|
2647
2630
|
// update and expose component labels
|
2648
|
-
const
|
2649
|
-
|
2650
|
-
? JSON.parse(componentLabels) : componentLabels || {};
|
2631
|
+
const tempComponentLabels = componentLabels && isValidJSON(componentLabels)
|
2632
|
+
? JSON.parse(componentLabels) : componentLabels;
|
2651
2633
|
|
2652
2634
|
/** @type {Record<string, string>} */
|
2653
|
-
self.componentLabels = ObjectAssign(
|
2635
|
+
self.componentLabels = ObjectAssign(colorPickerLabels, tempComponentLabels);
|
2654
2636
|
|
2655
2637
|
/** @type {Color} */
|
2656
|
-
self.color = new Color('
|
2638
|
+
self.color = new Color(input.value || '#fff', format);
|
2657
2639
|
|
2658
2640
|
/** @type {CP.ColorFormats} */
|
2659
2641
|
self.format = format;
|
@@ -2662,7 +2644,7 @@ class ColorPicker {
|
|
2662
2644
|
if (colorKeywords instanceof Array) {
|
2663
2645
|
self.colorKeywords = colorKeywords;
|
2664
2646
|
} else if (typeof colorKeywords === 'string' && colorKeywords.length) {
|
2665
|
-
self.colorKeywords = colorKeywords.split(',');
|
2647
|
+
self.colorKeywords = colorKeywords.split(',').map((x) => x.trim());
|
2666
2648
|
}
|
2667
2649
|
|
2668
2650
|
// set colour presets
|
@@ -2691,7 +2673,6 @@ class ColorPicker {
|
|
2691
2673
|
self.handleFocusOut = self.handleFocusOut.bind(self);
|
2692
2674
|
self.changeHandler = self.changeHandler.bind(self);
|
2693
2675
|
self.handleDismiss = self.handleDismiss.bind(self);
|
2694
|
-
self.keyToggle = self.keyToggle.bind(self);
|
2695
2676
|
self.handleKnobs = self.handleKnobs.bind(self);
|
2696
2677
|
|
2697
2678
|
// generate markup
|
@@ -2783,76 +2764,83 @@ class ColorPicker {
|
|
2783
2764
|
return inputValue !== '' && new Color(inputValue).isValid;
|
2784
2765
|
}
|
2785
2766
|
|
2767
|
+
/** Returns the colour appearance, usually the closest colour name for the current value. */
|
2768
|
+
get appearance() {
|
2769
|
+
const {
|
2770
|
+
colorLabels, hsl, hsv, format,
|
2771
|
+
} = this;
|
2772
|
+
|
2773
|
+
const hue = roundPart(hsl.h * 360);
|
2774
|
+
const saturationSource = format === 'hsl' ? hsl.s : hsv.s;
|
2775
|
+
const saturation = roundPart(saturationSource * 100);
|
2776
|
+
const lightness = roundPart(hsl.l * 100);
|
2777
|
+
const hsvl = hsv.v * 100;
|
2778
|
+
|
2779
|
+
let colorName;
|
2780
|
+
|
2781
|
+
// determine color appearance
|
2782
|
+
if (lightness === 100 && saturation === 0) {
|
2783
|
+
colorName = colorLabels.white;
|
2784
|
+
} else if (lightness === 0) {
|
2785
|
+
colorName = colorLabels.black;
|
2786
|
+
} else if (saturation === 0) {
|
2787
|
+
colorName = colorLabels.grey;
|
2788
|
+
} else if (hue < 15 || hue >= 345) {
|
2789
|
+
colorName = colorLabels.red;
|
2790
|
+
} else if (hue >= 15 && hue < 45) {
|
2791
|
+
colorName = hsvl > 80 && saturation > 80 ? colorLabels.orange : colorLabels.brown;
|
2792
|
+
} else if (hue >= 45 && hue < 75) {
|
2793
|
+
const isGold = hue > 46 && hue < 54 && hsvl < 80 && saturation > 90;
|
2794
|
+
const isOlive = hue >= 54 && hue < 75 && hsvl < 80;
|
2795
|
+
colorName = isGold ? colorLabels.gold : colorLabels.yellow;
|
2796
|
+
colorName = isOlive ? colorLabels.olive : colorName;
|
2797
|
+
} else if (hue >= 75 && hue < 155) {
|
2798
|
+
colorName = hsvl < 68 ? colorLabels.green : colorLabels.lime;
|
2799
|
+
} else if (hue >= 155 && hue < 175) {
|
2800
|
+
colorName = colorLabels.teal;
|
2801
|
+
} else if (hue >= 175 && hue < 195) {
|
2802
|
+
colorName = colorLabels.cyan;
|
2803
|
+
} else if (hue >= 195 && hue < 255) {
|
2804
|
+
colorName = colorLabels.blue;
|
2805
|
+
} else if (hue >= 255 && hue < 270) {
|
2806
|
+
colorName = colorLabels.violet;
|
2807
|
+
} else if (hue >= 270 && hue < 295) {
|
2808
|
+
colorName = colorLabels.magenta;
|
2809
|
+
} else if (hue >= 295 && hue < 345) {
|
2810
|
+
colorName = colorLabels.pink;
|
2811
|
+
}
|
2812
|
+
return colorName;
|
2813
|
+
}
|
2814
|
+
|
2786
2815
|
/** Updates `ColorPicker` visuals. */
|
2787
2816
|
updateVisuals() {
|
2788
2817
|
const self = this;
|
2789
2818
|
const {
|
2790
|
-
|
2819
|
+
controlPositions, visuals,
|
2791
2820
|
} = self;
|
2792
2821
|
const [v1, v2, v3] = visuals;
|
2793
|
-
const {
|
2794
|
-
const hue =
|
2795
|
-
|
2796
|
-
: controlPositions.c2y / offsetHeight;
|
2797
|
-
// @ts-ignore - `hslToRgb` is assigned to `Color` as static method
|
2798
|
-
const { r, g, b } = Color.hslToRgb(hue, 1, 0.5);
|
2822
|
+
const { offsetHeight } = v1;
|
2823
|
+
const hue = controlPositions.c2y / offsetHeight;
|
2824
|
+
const { r, g, b } = new Color({ h: hue, s: 1, l: 0.5 }).toRgb();
|
2799
2825
|
const whiteGrad = 'linear-gradient(rgb(255,255,255) 0%, rgb(255,255,255) 100%)';
|
2800
2826
|
const alpha = 1 - controlPositions.c3y / offsetHeight;
|
2801
2827
|
const roundA = roundPart((alpha * 100)) / 100;
|
2802
2828
|
|
2803
|
-
|
2804
|
-
|
2805
|
-
|
2806
|
-
|
2807
|
-
|
2808
|
-
|
2809
|
-
|
2810
|
-
|
2811
|
-
|
2812
|
-
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
|
2817
|
-
setElementStyle(v2, { background: hueGradient });
|
2818
|
-
} else {
|
2819
|
-
const saturation = roundPart((controlPositions.c2y / offsetHeight) * 100);
|
2820
|
-
const fill0 = new Color({
|
2821
|
-
r: 255, g: 0, b: 0, a: alpha,
|
2822
|
-
}).saturate(-saturation).toRgbString();
|
2823
|
-
const fill1 = new Color({
|
2824
|
-
r: 255, g: 255, b: 0, a: alpha,
|
2825
|
-
}).saturate(-saturation).toRgbString();
|
2826
|
-
const fill2 = new Color({
|
2827
|
-
r: 0, g: 255, b: 0, a: alpha,
|
2828
|
-
}).saturate(-saturation).toRgbString();
|
2829
|
-
const fill3 = new Color({
|
2830
|
-
r: 0, g: 255, b: 255, a: alpha,
|
2831
|
-
}).saturate(-saturation).toRgbString();
|
2832
|
-
const fill4 = new Color({
|
2833
|
-
r: 0, g: 0, b: 255, a: alpha,
|
2834
|
-
}).saturate(-saturation).toRgbString();
|
2835
|
-
const fill5 = new Color({
|
2836
|
-
r: 255, g: 0, b: 255, a: alpha,
|
2837
|
-
}).saturate(-saturation).toRgbString();
|
2838
|
-
const fill6 = new Color({
|
2839
|
-
r: 255, g: 0, b: 0, a: alpha,
|
2840
|
-
}).saturate(-saturation).toRgbString();
|
2841
|
-
const fillGradient = `linear-gradient(to right,
|
2842
|
-
${fill0} 0%, ${fill1} 16.67%, ${fill2} 33.33%, ${fill3} 50%,
|
2843
|
-
${fill4} 66.67%, ${fill5} 83.33%, ${fill6} 100%)`;
|
2844
|
-
const lightGrad = `linear-gradient(rgba(255,255,255,${roundA}) 0%, rgba(255,255,255,0) 50%),
|
2845
|
-
linear-gradient(rgba(0,0,0,0) 50%, rgba(0,0,0,${roundA}) 100%)`;
|
2846
|
-
|
2847
|
-
setElementStyle(v1, { background: `${lightGrad},${fillGradient},${whiteGrad}` });
|
2848
|
-
const {
|
2849
|
-
r: gr, g: gg, b: gb,
|
2850
|
-
} = new Color({ r, g, b }).greyscale().toRgb();
|
2829
|
+
const fill = new Color({
|
2830
|
+
h: hue, s: 1, l: 0.5, a: alpha,
|
2831
|
+
}).toRgbString();
|
2832
|
+
const hueGradient = `linear-gradient(
|
2833
|
+
rgb(255,0,0) 0%, rgb(255,255,0) 16.67%,
|
2834
|
+
rgb(0,255,0) 33.33%, rgb(0,255,255) 50%,
|
2835
|
+
rgb(0,0,255) 66.67%, rgb(255,0,255) 83.33%,
|
2836
|
+
rgb(255,0,0) 100%)`;
|
2837
|
+
setElementStyle(v1, {
|
2838
|
+
background: `linear-gradient(rgba(0,0,0,0) 0%, rgba(0,0,0,${roundA}) 100%),
|
2839
|
+
linear-gradient(to right, rgba(255,255,255,${roundA}) 0%, ${fill} 100%),
|
2840
|
+
${whiteGrad}`,
|
2841
|
+
});
|
2842
|
+
setElementStyle(v2, { background: hueGradient });
|
2851
2843
|
|
2852
|
-
setElementStyle(v2, {
|
2853
|
-
background: `linear-gradient(rgb(${r},${g},${b}) 0%, rgb(${gr},${gg},${gb}) 100%)`,
|
2854
|
-
});
|
2855
|
-
}
|
2856
2844
|
setElementStyle(v3, {
|
2857
2845
|
background: `linear-gradient(rgba(${r},${g},${b},1) 0%,rgba(${r},${g},${b},0) 100%)`,
|
2858
2846
|
});
|
@@ -3002,13 +2990,13 @@ class ColorPicker {
|
|
3002
2990
|
const [v1, v2, v3] = visuals;
|
3003
2991
|
const [c1, c2, c3] = controlKnobs;
|
3004
2992
|
/** @type {HTMLElement} */
|
3005
|
-
const visual =
|
3006
|
-
? target : querySelector('.visual-control', target.parentElement);
|
2993
|
+
const visual = controlKnobs.includes(target) ? target.previousElementSibling : target;
|
3007
2994
|
const visualRect = getBoundingClientRect(visual);
|
2995
|
+
const html = getDocumentElement(v1);
|
3008
2996
|
const X = type === 'touchstart' ? touches[0].pageX : pageX;
|
3009
2997
|
const Y = type === 'touchstart' ? touches[0].pageY : pageY;
|
3010
|
-
const offsetX = X -
|
3011
|
-
const offsetY = Y -
|
2998
|
+
const offsetX = X - html.scrollLeft - visualRect.left;
|
2999
|
+
const offsetY = Y - html.scrollTop - visualRect.top;
|
3012
3000
|
|
3013
3001
|
if (target === v1 || target === c1) {
|
3014
3002
|
self.dragElement = visual;
|
@@ -3068,10 +3056,11 @@ class ColorPicker {
|
|
3068
3056
|
if (!dragElement) return;
|
3069
3057
|
|
3070
3058
|
const controlRect = getBoundingClientRect(dragElement);
|
3071
|
-
const
|
3072
|
-
const
|
3073
|
-
const
|
3074
|
-
const
|
3059
|
+
const win = getDocumentElement(v1);
|
3060
|
+
const X = type === touchmoveEvent ? touches[0].pageX : pageX;
|
3061
|
+
const Y = type === touchmoveEvent ? touches[0].pageY : pageY;
|
3062
|
+
const offsetX = X - win.scrollLeft - controlRect.left;
|
3063
|
+
const offsetY = Y - win.scrollTop - controlRect.top;
|
3075
3064
|
|
3076
3065
|
if (dragElement === v1) {
|
3077
3066
|
self.changeControl1(offsetX, offsetY);
|
@@ -3098,19 +3087,19 @@ class ColorPicker {
|
|
3098
3087
|
if (![keyArrowUp, keyArrowDown, keyArrowLeft, keyArrowRight].includes(code)) return;
|
3099
3088
|
e.preventDefault();
|
3100
3089
|
|
3101
|
-
const {
|
3090
|
+
const { controlKnobs, visuals } = self;
|
3102
3091
|
const { offsetWidth, offsetHeight } = visuals[0];
|
3103
3092
|
const [c1, c2, c3] = controlKnobs;
|
3104
3093
|
const { activeElement } = getDocument(c1);
|
3105
3094
|
const currentKnob = controlKnobs.find((x) => x === activeElement);
|
3106
|
-
const yRatio = offsetHeight /
|
3095
|
+
const yRatio = offsetHeight / 360;
|
3107
3096
|
|
3108
3097
|
if (currentKnob) {
|
3109
3098
|
let offsetX = 0;
|
3110
3099
|
let offsetY = 0;
|
3111
3100
|
|
3112
3101
|
if (target === c1) {
|
3113
|
-
const xRatio = offsetWidth /
|
3102
|
+
const xRatio = offsetWidth / 100;
|
3114
3103
|
|
3115
3104
|
if ([keyArrowLeft, keyArrowRight].includes(code)) {
|
3116
3105
|
self.controlPositions.c1x += code === keyArrowRight ? xRatio : -xRatio;
|
@@ -3160,7 +3149,7 @@ class ColorPicker {
|
|
3160
3149
|
if (activeElement === input || (activeElement && inputs.includes(activeElement))) {
|
3161
3150
|
if (activeElement === input) {
|
3162
3151
|
if (isNonColorValue) {
|
3163
|
-
colorSource = '
|
3152
|
+
colorSource = currentValue === 'transparent' ? 'rgba(0,0,0,0)' : 'rgb(0,0,0)';
|
3164
3153
|
} else {
|
3165
3154
|
colorSource = currentValue;
|
3166
3155
|
}
|
@@ -3211,9 +3200,7 @@ class ColorPicker {
|
|
3211
3200
|
changeControl1(X, Y) {
|
3212
3201
|
const self = this;
|
3213
3202
|
let [offsetX, offsetY] = [0, 0];
|
3214
|
-
const {
|
3215
|
-
format, controlPositions, visuals,
|
3216
|
-
} = self;
|
3203
|
+
const { controlPositions, visuals } = self;
|
3217
3204
|
const { offsetHeight, offsetWidth } = visuals[0];
|
3218
3205
|
|
3219
3206
|
if (X > offsetWidth) offsetX = offsetWidth;
|
@@ -3222,29 +3209,19 @@ class ColorPicker {
|
|
3222
3209
|
if (Y > offsetHeight) offsetY = offsetHeight;
|
3223
3210
|
else if (Y >= 0) offsetY = Y;
|
3224
3211
|
|
3225
|
-
const hue =
|
3226
|
-
? offsetX / offsetWidth
|
3227
|
-
: controlPositions.c2y / offsetHeight;
|
3212
|
+
const hue = controlPositions.c2y / offsetHeight;
|
3228
3213
|
|
3229
|
-
const saturation =
|
3230
|
-
? 1 - controlPositions.c2y / offsetHeight
|
3231
|
-
: offsetX / offsetWidth;
|
3214
|
+
const saturation = offsetX / offsetWidth;
|
3232
3215
|
|
3233
3216
|
const lightness = 1 - offsetY / offsetHeight;
|
3234
3217
|
const alpha = 1 - controlPositions.c3y / offsetHeight;
|
3235
3218
|
|
3236
|
-
const colorObject = format === 'hsl'
|
3237
|
-
? {
|
3238
|
-
h: hue, s: saturation, l: lightness, a: alpha,
|
3239
|
-
}
|
3240
|
-
: {
|
3241
|
-
h: hue, s: saturation, v: lightness, a: alpha,
|
3242
|
-
};
|
3243
|
-
|
3244
3219
|
// new color
|
3245
3220
|
const {
|
3246
3221
|
r, g, b, a,
|
3247
|
-
} = new Color(
|
3222
|
+
} = new Color({
|
3223
|
+
h: hue, s: saturation, v: lightness, a: alpha,
|
3224
|
+
});
|
3248
3225
|
|
3249
3226
|
ObjectAssign(self.color, {
|
3250
3227
|
r, g, b, a,
|
@@ -3271,7 +3248,7 @@ class ColorPicker {
|
|
3271
3248
|
changeControl2(Y) {
|
3272
3249
|
const self = this;
|
3273
3250
|
const {
|
3274
|
-
|
3251
|
+
controlPositions, visuals,
|
3275
3252
|
} = self;
|
3276
3253
|
const { offsetHeight, offsetWidth } = visuals[0];
|
3277
3254
|
|
@@ -3280,26 +3257,17 @@ class ColorPicker {
|
|
3280
3257
|
if (Y > offsetHeight) offsetY = offsetHeight;
|
3281
3258
|
else if (Y >= 0) offsetY = Y;
|
3282
3259
|
|
3283
|
-
const hue =
|
3284
|
-
|
3285
|
-
: offsetY / offsetHeight;
|
3286
|
-
const saturation = format === 'hsl'
|
3287
|
-
? 1 - offsetY / offsetHeight
|
3288
|
-
: controlPositions.c1x / offsetWidth;
|
3260
|
+
const hue = offsetY / offsetHeight;
|
3261
|
+
const saturation = controlPositions.c1x / offsetWidth;
|
3289
3262
|
const lightness = 1 - controlPositions.c1y / offsetHeight;
|
3290
3263
|
const alpha = 1 - controlPositions.c3y / offsetHeight;
|
3291
|
-
const colorObject = format === 'hsl'
|
3292
|
-
? {
|
3293
|
-
h: hue, s: saturation, l: lightness, a: alpha,
|
3294
|
-
}
|
3295
|
-
: {
|
3296
|
-
h: hue, s: saturation, v: lightness, a: alpha,
|
3297
|
-
};
|
3298
3264
|
|
3299
3265
|
// new color
|
3300
3266
|
const {
|
3301
3267
|
r, g, b, a,
|
3302
|
-
} = new Color(
|
3268
|
+
} = new Color({
|
3269
|
+
h: hue, s: saturation, v: lightness, a: alpha,
|
3270
|
+
});
|
3303
3271
|
|
3304
3272
|
ObjectAssign(self.color, {
|
3305
3273
|
r, g, b, a,
|
@@ -3386,18 +3354,18 @@ class ColorPicker {
|
|
3386
3354
|
setControlPositions() {
|
3387
3355
|
const self = this;
|
3388
3356
|
const {
|
3389
|
-
|
3357
|
+
visuals, color, hsv,
|
3390
3358
|
} = self;
|
3391
3359
|
const { offsetHeight, offsetWidth } = visuals[0];
|
3392
3360
|
const alpha = color.a;
|
3393
|
-
const hue =
|
3361
|
+
const hue = hsv.h;
|
3394
3362
|
|
3395
|
-
const saturation =
|
3396
|
-
const lightness =
|
3363
|
+
const saturation = hsv.s;
|
3364
|
+
const lightness = hsv.v;
|
3397
3365
|
|
3398
|
-
self.controlPositions.c1x =
|
3366
|
+
self.controlPositions.c1x = saturation * offsetWidth;
|
3399
3367
|
self.controlPositions.c1y = (1 - lightness) * offsetHeight;
|
3400
|
-
self.controlPositions.c2y =
|
3368
|
+
self.controlPositions.c2y = hue * offsetHeight;
|
3401
3369
|
self.controlPositions.c3y = (1 - alpha) * offsetHeight;
|
3402
3370
|
}
|
3403
3371
|
|
@@ -3405,78 +3373,40 @@ class ColorPicker {
|
|
3405
3373
|
updateAppearance() {
|
3406
3374
|
const self = this;
|
3407
3375
|
const {
|
3408
|
-
componentLabels,
|
3409
|
-
|
3376
|
+
componentLabels, color, parent,
|
3377
|
+
hsv, hex, format, controlKnobs,
|
3410
3378
|
} = self;
|
3411
3379
|
const {
|
3412
3380
|
appearanceLabel, hexLabel, valueLabel,
|
3413
3381
|
} = componentLabels;
|
3414
|
-
|
3382
|
+
let { r, g, b } = color.toRgb();
|
3415
3383
|
const [knob1, knob2, knob3] = controlKnobs;
|
3416
|
-
const hue = roundPart(
|
3384
|
+
const hue = roundPart(hsv.h * 360);
|
3417
3385
|
const alpha = color.a;
|
3418
|
-
const
|
3419
|
-
const
|
3420
|
-
const
|
3421
|
-
const hsvl = hsv.v * 100;
|
3422
|
-
let colorName;
|
3423
|
-
|
3424
|
-
// determine color appearance
|
3425
|
-
if (lightness === 100 && saturation === 0) {
|
3426
|
-
colorName = colorLabels.white;
|
3427
|
-
} else if (lightness === 0) {
|
3428
|
-
colorName = colorLabels.black;
|
3429
|
-
} else if (saturation === 0) {
|
3430
|
-
colorName = colorLabels.grey;
|
3431
|
-
} else if (hue < 15 || hue >= 345) {
|
3432
|
-
colorName = colorLabels.red;
|
3433
|
-
} else if (hue >= 15 && hue < 45) {
|
3434
|
-
colorName = hsvl > 80 && saturation > 80 ? colorLabels.orange : colorLabels.brown;
|
3435
|
-
} else if (hue >= 45 && hue < 75) {
|
3436
|
-
const isGold = hue > 46 && hue < 54 && hsvl < 80 && saturation > 90;
|
3437
|
-
const isOlive = hue >= 54 && hue < 75 && hsvl < 80;
|
3438
|
-
colorName = isGold ? colorLabels.gold : colorLabels.yellow;
|
3439
|
-
colorName = isOlive ? colorLabels.olive : colorName;
|
3440
|
-
} else if (hue >= 75 && hue < 155) {
|
3441
|
-
colorName = hsvl < 68 ? colorLabels.green : colorLabels.lime;
|
3442
|
-
} else if (hue >= 155 && hue < 175) {
|
3443
|
-
colorName = colorLabels.teal;
|
3444
|
-
} else if (hue >= 175 && hue < 195) {
|
3445
|
-
colorName = colorLabels.cyan;
|
3446
|
-
} else if (hue >= 195 && hue < 255) {
|
3447
|
-
colorName = colorLabels.blue;
|
3448
|
-
} else if (hue >= 255 && hue < 270) {
|
3449
|
-
colorName = colorLabels.violet;
|
3450
|
-
} else if (hue >= 270 && hue < 295) {
|
3451
|
-
colorName = colorLabels.magenta;
|
3452
|
-
} else if (hue >= 295 && hue < 345) {
|
3453
|
-
colorName = colorLabels.pink;
|
3454
|
-
}
|
3386
|
+
const saturation = roundPart(hsv.s * 100);
|
3387
|
+
const lightness = roundPart(hsv.v * 100);
|
3388
|
+
const colorName = self.appearance;
|
3455
3389
|
|
3456
3390
|
let colorLabel = `${hexLabel} ${hex.split('').join(' ')}`;
|
3457
3391
|
|
3458
|
-
if (format === '
|
3459
|
-
colorLabel = `HSL: ${hue}°, ${saturation}%, ${lightness}%`;
|
3460
|
-
setAttribute(knob1, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3461
|
-
setAttribute(knob1, ariaValueText, `${hue}° & ${lightness}%`);
|
3462
|
-
setAttribute(knob1, ariaValueNow, `${hue}`);
|
3463
|
-
setAttribute(knob2, ariaValueText, `${saturation}%`);
|
3464
|
-
setAttribute(knob2, ariaValueNow, `${saturation}`);
|
3465
|
-
} else if (format === 'hwb') {
|
3392
|
+
if (format === 'hwb') {
|
3466
3393
|
const { hwb } = self;
|
3467
3394
|
const whiteness = roundPart(hwb.w * 100);
|
3468
3395
|
const blackness = roundPart(hwb.b * 100);
|
3469
3396
|
colorLabel = `HWB: ${hue}°, ${whiteness}%, ${blackness}%`;
|
3470
|
-
setAttribute(knob1, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3471
3397
|
setAttribute(knob1, ariaValueText, `${whiteness}% & ${blackness}%`);
|
3472
3398
|
setAttribute(knob1, ariaValueNow, `${whiteness}`);
|
3399
|
+
setAttribute(knob2, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3473
3400
|
setAttribute(knob2, ariaValueText, `${hue}%`);
|
3474
3401
|
setAttribute(knob2, ariaValueNow, `${hue}`);
|
3475
3402
|
} else {
|
3403
|
+
[r, g, b] = [r, g, b].map(roundPart);
|
3404
|
+
colorLabel = format === 'hsl' ? `HSL: ${hue}°, ${saturation}%, ${lightness}%` : colorLabel;
|
3476
3405
|
colorLabel = format === 'rgb' ? `RGB: ${r}, ${g}, ${b}` : colorLabel;
|
3477
|
-
|
3406
|
+
|
3478
3407
|
setAttribute(knob1, ariaValueText, `${lightness}% & ${saturation}%`);
|
3479
3408
|
setAttribute(knob1, ariaValueNow, `${lightness}`);
|
3409
|
+
setAttribute(knob2, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3480
3410
|
setAttribute(knob2, ariaValueText, `${hue}°`);
|
3481
3411
|
setAttribute(knob2, ariaValueNow, `${hue}`);
|
3482
3412
|
}
|
@@ -3571,37 +3501,13 @@ class ColorPicker {
|
|
3571
3501
|
}
|
3572
3502
|
}
|
3573
3503
|
|
3574
|
-
/**
|
3575
|
-
* The `Space` & `Enter` keys specific event listener.
|
3576
|
-
* Toggle visibility of the `ColorPicker` / the presets menu, showing one will hide the other.
|
3577
|
-
* @param {KeyboardEvent} e
|
3578
|
-
* @this {ColorPicker}
|
3579
|
-
*/
|
3580
|
-
keyToggle(e) {
|
3581
|
-
const self = this;
|
3582
|
-
const { menuToggle } = self;
|
3583
|
-
const { activeElement } = getDocument(menuToggle);
|
3584
|
-
const { code } = e;
|
3585
|
-
|
3586
|
-
if ([keyEnter, keySpace].includes(code)) {
|
3587
|
-
if ((menuToggle && activeElement === menuToggle) || !activeElement) {
|
3588
|
-
e.preventDefault();
|
3589
|
-
if (!activeElement) {
|
3590
|
-
self.togglePicker(e);
|
3591
|
-
} else {
|
3592
|
-
self.toggleMenu();
|
3593
|
-
}
|
3594
|
-
}
|
3595
|
-
}
|
3596
|
-
}
|
3597
|
-
|
3598
3504
|
/**
|
3599
3505
|
* Toggle the `ColorPicker` dropdown visibility.
|
3600
|
-
* @param {Event} e
|
3506
|
+
* @param {Event=} e
|
3601
3507
|
* @this {ColorPicker}
|
3602
3508
|
*/
|
3603
3509
|
togglePicker(e) {
|
3604
|
-
e.preventDefault();
|
3510
|
+
if (e) e.preventDefault();
|
3605
3511
|
const self = this;
|
3606
3512
|
const { colorPicker } = self;
|
3607
3513
|
|
@@ -3622,8 +3528,13 @@ class ColorPicker {
|
|
3622
3528
|
}
|
3623
3529
|
}
|
3624
3530
|
|
3625
|
-
/**
|
3626
|
-
|
3531
|
+
/**
|
3532
|
+
* Toggles the visibility of the `ColorPicker` presets menu.
|
3533
|
+
* @param {Event=} e
|
3534
|
+
* @this {ColorPicker}
|
3535
|
+
*/
|
3536
|
+
toggleMenu(e) {
|
3537
|
+
if (e) e.preventDefault();
|
3627
3538
|
const self = this;
|
3628
3539
|
const { colorMenu } = self;
|
3629
3540
|
|
@@ -3649,6 +3560,10 @@ class ColorPicker {
|
|
3649
3560
|
const relatedBtn = openPicker ? pickerToggle : menuToggle;
|
3650
3561
|
const animationDuration = openDropdown && getElementTransitionDuration(openDropdown);
|
3651
3562
|
|
3563
|
+
// if (!self.isValid) {
|
3564
|
+
self.value = self.color.toString(true);
|
3565
|
+
// }
|
3566
|
+
|
3652
3567
|
if (openDropdown) {
|
3653
3568
|
removeClass(openDropdown, 'show');
|
3654
3569
|
setAttribute(relatedBtn, ariaExpanded, 'false');
|
@@ -3662,9 +3577,6 @@ class ColorPicker {
|
|
3662
3577
|
}, animationDuration);
|
3663
3578
|
}
|
3664
3579
|
|
3665
|
-
if (!self.isValid) {
|
3666
|
-
self.value = self.color.toString();
|
3667
|
-
}
|
3668
3580
|
if (!focusPrevented) {
|
3669
3581
|
focus(pickerToggle);
|
3670
3582
|
}
|