@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
package/dist/js/color-picker.js
CHANGED
@@ -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
|
*/
|
@@ -843,6 +843,8 @@
|
|
843
843
|
if (nonColors.includes(color)
|
844
844
|
|| ['#', ...COLOR_FORMAT].some((f) => color.includes(f))) return false;
|
845
845
|
|
846
|
+
if (['black', 'white'].includes(color)) return true;
|
847
|
+
|
846
848
|
return ['rgb(255, 255, 255)', 'rgb(0, 0, 0)'].every((c) => {
|
847
849
|
setElementStyle(documentHead, { color });
|
848
850
|
const computedColor = getElementStyle(documentHead, 'color');
|
@@ -869,6 +871,11 @@
|
|
869
871
|
*/
|
870
872
|
function bound01(N, max) {
|
871
873
|
let n = N;
|
874
|
+
|
875
|
+
if (typeof N === 'number'
|
876
|
+
&& Math.min(N, 0) === 0 // round values to 6 decimals Math.round(N * (10 ** 6)) / 10 ** 6
|
877
|
+
&& Math.max(N, 1) === 1) return N;
|
878
|
+
|
872
879
|
if (isOnePointZero(N)) n = '100%';
|
873
880
|
|
874
881
|
const processPercent = isPercentage(n);
|
@@ -972,15 +979,12 @@
|
|
972
979
|
/**
|
973
980
|
* Converts an RGB colour value to HSL.
|
974
981
|
*
|
975
|
-
* @param {number}
|
976
|
-
* @param {number}
|
977
|
-
* @param {number}
|
982
|
+
* @param {number} r Red component [0, 1]
|
983
|
+
* @param {number} g Green component [0, 1]
|
984
|
+
* @param {number} b Blue component [0, 1]
|
978
985
|
* @returns {CP.HSL} {h,s,l} object with [0, 1] ranged values
|
979
986
|
*/
|
980
|
-
function rgbToHsl(
|
981
|
-
const r = R / 255;
|
982
|
-
const g = G / 255;
|
983
|
-
const b = B / 255;
|
987
|
+
function rgbToHsl(r, g, b) {
|
984
988
|
const max = Math.max(r, g, b);
|
985
989
|
const min = Math.min(r, g, b);
|
986
990
|
let h = 0;
|
@@ -992,17 +996,10 @@
|
|
992
996
|
} else {
|
993
997
|
const d = max - min;
|
994
998
|
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
case g:
|
1000
|
-
h = (b - r) / d + 2;
|
1001
|
-
break;
|
1002
|
-
case b:
|
1003
|
-
h = (r - g) / d + 4;
|
1004
|
-
break;
|
1005
|
-
}
|
999
|
+
if (max === r) h = (g - b) / d + (g < b ? 6 : 0);
|
1000
|
+
if (max === g) h = (b - r) / d + 2;
|
1001
|
+
if (max === b) h = (r - g) / d + 4;
|
1002
|
+
|
1006
1003
|
h /= 6;
|
1007
1004
|
}
|
1008
1005
|
return { h, s, l };
|
@@ -1031,7 +1028,7 @@
|
|
1031
1028
|
* @param {number} h Hue Angle [0, 1]
|
1032
1029
|
* @param {number} s Saturation [0, 1]
|
1033
1030
|
* @param {number} l Lightness Angle [0, 1]
|
1034
|
-
* @returns {CP.RGB} {r,g,b} object with [0,
|
1031
|
+
* @returns {CP.RGB} {r,g,b} object with [0, 1] ranged values
|
1035
1032
|
*/
|
1036
1033
|
function hslToRgb(h, s, l) {
|
1037
1034
|
let r = 0;
|
@@ -1050,7 +1047,6 @@
|
|
1050
1047
|
g = hueToRgb(p, q, h);
|
1051
1048
|
b = hueToRgb(p, q, h - 1 / 3);
|
1052
1049
|
}
|
1053
|
-
[r, g, b] = [r, g, b].map((x) => x * 255);
|
1054
1050
|
|
1055
1051
|
return { r, g, b };
|
1056
1052
|
}
|
@@ -1060,16 +1056,12 @@
|
|
1060
1056
|
* @link https://www.w3.org/TR/css-color-4/#hwb-to-rgb
|
1061
1057
|
* @link http://alvyray.com/Papers/CG/hwb2rgb.htm
|
1062
1058
|
*
|
1063
|
-
* @param {number}
|
1064
|
-
* @param {number}
|
1065
|
-
* @param {number}
|
1059
|
+
* @param {number} r Red component [0, 1]
|
1060
|
+
* @param {number} g Green [0, 1]
|
1061
|
+
* @param {number} b Blue [0, 1]
|
1066
1062
|
* @return {CP.HWB} {h,w,b} object with [0, 1] ranged values
|
1067
1063
|
*/
|
1068
|
-
function rgbToHwb(
|
1069
|
-
const r = R / 255;
|
1070
|
-
const g = G / 255;
|
1071
|
-
const b = B / 255;
|
1072
|
-
|
1064
|
+
function rgbToHwb(r, g, b) {
|
1073
1065
|
let f = 0;
|
1074
1066
|
let i = 0;
|
1075
1067
|
const whiteness = Math.min(r, g, b);
|
@@ -1099,20 +1091,18 @@
|
|
1099
1091
|
* @param {number} H Hue Angle [0, 1]
|
1100
1092
|
* @param {number} W Whiteness [0, 1]
|
1101
1093
|
* @param {number} B Blackness [0, 1]
|
1102
|
-
* @return {CP.RGB} {r,g,b} object with [0,
|
1094
|
+
* @return {CP.RGB} {r,g,b} object with [0, 1] ranged values
|
1103
1095
|
*
|
1104
1096
|
* @link https://www.w3.org/TR/css-color-4/#hwb-to-rgb
|
1105
1097
|
* @link http://alvyray.com/Papers/CG/hwb2rgb.htm
|
1106
1098
|
*/
|
1107
1099
|
function hwbToRgb(H, W, B) {
|
1108
1100
|
if (W + B >= 1) {
|
1109
|
-
const gray =
|
1101
|
+
const gray = W / (W + B);
|
1110
1102
|
return { r: gray, g: gray, b: gray };
|
1111
1103
|
}
|
1112
1104
|
let { r, g, b } = hslToRgb(H, 1, 0.5);
|
1113
|
-
[r, g, b] = [r, g, b]
|
1114
|
-
.map((v) => (v / 255) * (1 - W - B) + W)
|
1115
|
-
.map((v) => v * 255);
|
1105
|
+
[r, g, b] = [r, g, b].map((v) => v * (1 - W - B) + W);
|
1116
1106
|
|
1117
1107
|
return { r, g, b };
|
1118
1108
|
}
|
@@ -1120,15 +1110,12 @@
|
|
1120
1110
|
/**
|
1121
1111
|
* Converts an RGB colour value to HSV.
|
1122
1112
|
*
|
1123
|
-
* @param {number}
|
1124
|
-
* @param {number}
|
1125
|
-
* @param {number}
|
1113
|
+
* @param {number} r Red component [0, 1]
|
1114
|
+
* @param {number} g Green [0, 1]
|
1115
|
+
* @param {number} b Blue [0, 1]
|
1126
1116
|
* @returns {CP.HSV} {h,s,v} object with [0, 1] ranged values
|
1127
1117
|
*/
|
1128
|
-
function rgbToHsv(
|
1129
|
-
const r = R / 255;
|
1130
|
-
const g = G / 255;
|
1131
|
-
const b = B / 255;
|
1118
|
+
function rgbToHsv(r, g, b) {
|
1132
1119
|
const max = Math.max(r, g, b);
|
1133
1120
|
const min = Math.min(r, g, b);
|
1134
1121
|
let h = 0;
|
@@ -1138,17 +1125,10 @@
|
|
1138
1125
|
if (max === min) {
|
1139
1126
|
h = 0; // achromatic
|
1140
1127
|
} else {
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
case g:
|
1146
|
-
h = (b - r) / d + 2;
|
1147
|
-
break;
|
1148
|
-
case b:
|
1149
|
-
h = (r - g) / d + 4;
|
1150
|
-
break;
|
1151
|
-
}
|
1128
|
+
if (r === max) h = (g - b) / d + (g < b ? 6 : 0);
|
1129
|
+
if (g === max) h = (b - r) / d + 2;
|
1130
|
+
if (b === max) h = (r - g) / d + 4;
|
1131
|
+
|
1152
1132
|
h /= 6;
|
1153
1133
|
}
|
1154
1134
|
return { h, s, v };
|
@@ -1172,10 +1152,9 @@
|
|
1172
1152
|
const q = v * (1 - f * s);
|
1173
1153
|
const t = v * (1 - (1 - f) * s);
|
1174
1154
|
const mod = i % 6;
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
[r, g, b] = [r, g, b].map((n) => n * 255);
|
1155
|
+
const r = [v, q, p, p, t, v][mod];
|
1156
|
+
const g = [t, v, v, q, p, p][mod];
|
1157
|
+
const b = [p, p, t, v, v, q][mod];
|
1179
1158
|
return { r, g, b };
|
1180
1159
|
}
|
1181
1160
|
|
@@ -1243,15 +1222,15 @@
|
|
1243
1222
|
*/
|
1244
1223
|
function stringInputToObject(input) {
|
1245
1224
|
let color = toLowerCase(input.trim());
|
1225
|
+
|
1246
1226
|
if (color.length === 0) {
|
1247
1227
|
return {
|
1248
1228
|
r: 0, g: 0, b: 0, a: 1,
|
1249
1229
|
};
|
1250
1230
|
}
|
1251
|
-
|
1231
|
+
|
1252
1232
|
if (isColorName(color)) {
|
1253
1233
|
color = getRGBFromName(color);
|
1254
|
-
named = true;
|
1255
1234
|
} else if (nonColors.includes(color)) {
|
1256
1235
|
const a = color === 'transparent' ? 0 : 1;
|
1257
1236
|
return {
|
@@ -1270,24 +1249,28 @@
|
|
1270
1249
|
r: m1, g: m2, b: m3, a: m4 !== undefined ? m4 : 1, format: 'rgb',
|
1271
1250
|
};
|
1272
1251
|
}
|
1252
|
+
|
1273
1253
|
[, m1, m2, m3, m4] = matchers.hsl.exec(color) || [];
|
1274
1254
|
if (m1 && m2 && m3/* && m4 */) {
|
1275
1255
|
return {
|
1276
1256
|
h: m1, s: m2, l: m3, a: m4 !== undefined ? m4 : 1, format: 'hsl',
|
1277
1257
|
};
|
1278
1258
|
}
|
1259
|
+
|
1279
1260
|
[, m1, m2, m3, m4] = matchers.hsv.exec(color) || [];
|
1280
1261
|
if (m1 && m2 && m3/* && m4 */) {
|
1281
1262
|
return {
|
1282
1263
|
h: m1, s: m2, v: m3, a: m4 !== undefined ? m4 : 1, format: 'hsv',
|
1283
1264
|
};
|
1284
1265
|
}
|
1266
|
+
|
1285
1267
|
[, m1, m2, m3, m4] = matchers.hwb.exec(color) || [];
|
1286
1268
|
if (m1 && m2 && m3) {
|
1287
1269
|
return {
|
1288
1270
|
h: m1, w: m2, b: m3, a: m4 !== undefined ? m4 : 1, format: 'hwb',
|
1289
1271
|
};
|
1290
1272
|
}
|
1273
|
+
|
1291
1274
|
[, m1, m2, m3, m4] = matchers.hex8.exec(color) || [];
|
1292
1275
|
if (m1 && m2 && m3 && m4) {
|
1293
1276
|
return {
|
@@ -1295,18 +1278,20 @@
|
|
1295
1278
|
g: parseIntFromHex(m2),
|
1296
1279
|
b: parseIntFromHex(m3),
|
1297
1280
|
a: convertHexToDecimal(m4),
|
1298
|
-
format:
|
1281
|
+
format: 'hex',
|
1299
1282
|
};
|
1300
1283
|
}
|
1284
|
+
|
1301
1285
|
[, m1, m2, m3] = matchers.hex6.exec(color) || [];
|
1302
1286
|
if (m1 && m2 && m3) {
|
1303
1287
|
return {
|
1304
1288
|
r: parseIntFromHex(m1),
|
1305
1289
|
g: parseIntFromHex(m2),
|
1306
1290
|
b: parseIntFromHex(m3),
|
1307
|
-
format:
|
1291
|
+
format: 'hex',
|
1308
1292
|
};
|
1309
1293
|
}
|
1294
|
+
|
1310
1295
|
[, m1, m2, m3, m4] = matchers.hex4.exec(color) || [];
|
1311
1296
|
if (m1 && m2 && m3 && m4) {
|
1312
1297
|
return {
|
@@ -1314,19 +1299,20 @@
|
|
1314
1299
|
g: parseIntFromHex(m2 + m2),
|
1315
1300
|
b: parseIntFromHex(m3 + m3),
|
1316
1301
|
a: convertHexToDecimal(m4 + m4),
|
1317
|
-
|
1318
|
-
format: named ? 'rgb' : 'hex',
|
1302
|
+
format: 'hex',
|
1319
1303
|
};
|
1320
1304
|
}
|
1305
|
+
|
1321
1306
|
[, m1, m2, m3] = matchers.hex3.exec(color) || [];
|
1322
1307
|
if (m1 && m2 && m3) {
|
1323
1308
|
return {
|
1324
1309
|
r: parseIntFromHex(m1 + m1),
|
1325
1310
|
g: parseIntFromHex(m2 + m2),
|
1326
1311
|
b: parseIntFromHex(m3 + m3),
|
1327
|
-
format:
|
1312
|
+
format: 'hex',
|
1328
1313
|
};
|
1329
1314
|
}
|
1315
|
+
|
1330
1316
|
return false;
|
1331
1317
|
}
|
1332
1318
|
|
@@ -1357,6 +1343,7 @@
|
|
1357
1343
|
*/
|
1358
1344
|
function inputToRGB(input) {
|
1359
1345
|
let rgb = { r: 0, g: 0, b: 0 };
|
1346
|
+
/** @type {*} */
|
1360
1347
|
let color = input;
|
1361
1348
|
/** @type {string | number} */
|
1362
1349
|
let a = 1;
|
@@ -1373,39 +1360,41 @@
|
|
1373
1360
|
let format = inputFormat && COLOR_FORMAT.includes(inputFormat) ? inputFormat : 'rgb';
|
1374
1361
|
|
1375
1362
|
if (typeof input === 'string') {
|
1376
|
-
// @ts-ignore -- this now is converted to object
|
1377
1363
|
color = stringInputToObject(input);
|
1378
1364
|
if (color) ok = true;
|
1379
1365
|
}
|
1380
1366
|
if (typeof color === 'object') {
|
1381
1367
|
if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {
|
1382
1368
|
({ r, g, b } = color);
|
1383
|
-
// RGB values now are all in [0,
|
1384
|
-
[r, g, b] = [r, g, b].map((n) => bound01(n, isPercentage(n) ? 100 : 255)
|
1369
|
+
// RGB values now are all in [0, 1] range
|
1370
|
+
[r, g, b] = [r, g, b].map((n) => bound01(n, isPercentage(n) ? 100 : 255));
|
1385
1371
|
rgb = { r, g, b };
|
1386
1372
|
ok = true;
|
1387
|
-
format = 'rgb';
|
1388
|
-
}
|
1373
|
+
format = color.format || 'rgb';
|
1374
|
+
}
|
1375
|
+
if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {
|
1389
1376
|
({ h, s, v } = color);
|
1390
|
-
h =
|
1391
|
-
s =
|
1392
|
-
v =
|
1377
|
+
h = bound01(h, 360); // hue can be `5deg` or a [0, 1] value
|
1378
|
+
s = bound01(s, 100); // saturation can be `5%` or a [0, 1] value
|
1379
|
+
v = bound01(v, 100); // brightness can be `5%` or a [0, 1] value
|
1393
1380
|
rgb = hsvToRgb(h, s, v);
|
1394
1381
|
ok = true;
|
1395
1382
|
format = 'hsv';
|
1396
|
-
}
|
1383
|
+
}
|
1384
|
+
if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) {
|
1397
1385
|
({ h, s, l } = color);
|
1398
|
-
h =
|
1399
|
-
s =
|
1400
|
-
l =
|
1386
|
+
h = bound01(h, 360); // hue can be `5deg` or a [0, 1] value
|
1387
|
+
s = bound01(s, 100); // saturation can be `5%` or a [0, 1] value
|
1388
|
+
l = bound01(l, 100); // lightness can be `5%` or a [0, 1] value
|
1401
1389
|
rgb = hslToRgb(h, s, l);
|
1402
1390
|
ok = true;
|
1403
1391
|
format = 'hsl';
|
1404
|
-
}
|
1392
|
+
}
|
1393
|
+
if (isValidCSSUnit(color.h) && isValidCSSUnit(color.w) && isValidCSSUnit(color.b)) {
|
1405
1394
|
({ h, w, b } = color);
|
1406
|
-
h =
|
1407
|
-
w =
|
1408
|
-
b =
|
1395
|
+
h = bound01(h, 360); // hue can be `5deg` or a [0, 1] value
|
1396
|
+
w = bound01(w, 100); // whiteness can be `5%` or a [0, 1] value
|
1397
|
+
b = bound01(b, 100); // blackness can be `5%` or a [0, 1] value
|
1409
1398
|
rgb = hwbToRgb(h, w, b);
|
1410
1399
|
ok = true;
|
1411
1400
|
format = 'hwb';
|
@@ -1422,9 +1411,12 @@
|
|
1422
1411
|
return {
|
1423
1412
|
ok,
|
1424
1413
|
format,
|
1425
|
-
r: Math.min(255, Math.max(rgb.r, 0)),
|
1426
|
-
g: Math.min(255, Math.max(rgb.g, 0)),
|
1427
|
-
b: Math.min(255, Math.max(rgb.b, 0)),
|
1414
|
+
// r: Math.min(255, Math.max(rgb.r, 0)),
|
1415
|
+
// g: Math.min(255, Math.max(rgb.g, 0)),
|
1416
|
+
// b: Math.min(255, Math.max(rgb.b, 0)),
|
1417
|
+
r: rgb.r,
|
1418
|
+
g: rgb.g,
|
1419
|
+
b: rgb.b,
|
1428
1420
|
a: boundAlpha(a),
|
1429
1421
|
};
|
1430
1422
|
}
|
@@ -1443,16 +1435,13 @@
|
|
1443
1435
|
constructor(input, config) {
|
1444
1436
|
let color = input;
|
1445
1437
|
const configFormat = config && COLOR_FORMAT.includes(config)
|
1446
|
-
? config : '
|
1438
|
+
? config : '';
|
1447
1439
|
|
1448
|
-
// If input is already a `Color`,
|
1440
|
+
// If input is already a `Color`, clone its values
|
1449
1441
|
if (color instanceof Color) {
|
1450
1442
|
color = inputToRGB(color);
|
1451
1443
|
}
|
1452
|
-
|
1453
|
-
const len = `${color}`.length;
|
1454
|
-
color = `#${(len === 2 ? '0' : '00')}${color}`;
|
1455
|
-
}
|
1444
|
+
|
1456
1445
|
const {
|
1457
1446
|
r, g, b, a, ok, format,
|
1458
1447
|
} = inputToRGB(color);
|
@@ -1502,24 +1491,21 @@
|
|
1502
1491
|
let R = 0;
|
1503
1492
|
let G = 0;
|
1504
1493
|
let B = 0;
|
1505
|
-
const rp = r / 255;
|
1506
|
-
const rg = g / 255;
|
1507
|
-
const rb = b / 255;
|
1508
1494
|
|
1509
|
-
if (
|
1510
|
-
R =
|
1495
|
+
if (r <= 0.03928) {
|
1496
|
+
R = r / 12.92;
|
1511
1497
|
} else {
|
1512
|
-
R = ((
|
1498
|
+
R = ((r + 0.055) / 1.055) ** 2.4;
|
1513
1499
|
}
|
1514
|
-
if (
|
1515
|
-
G =
|
1500
|
+
if (g <= 0.03928) {
|
1501
|
+
G = g / 12.92;
|
1516
1502
|
} else {
|
1517
|
-
G = ((
|
1503
|
+
G = ((g + 0.055) / 1.055) ** 2.4;
|
1518
1504
|
}
|
1519
|
-
if (
|
1520
|
-
B =
|
1505
|
+
if (b <= 0.03928) {
|
1506
|
+
B = b / 12.92;
|
1521
1507
|
} else {
|
1522
|
-
B = ((
|
1508
|
+
B = ((b + 0.055) / 1.055) ** 2.4;
|
1523
1509
|
}
|
1524
1510
|
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
|
1525
1511
|
}
|
@@ -1529,7 +1515,7 @@
|
|
1529
1515
|
* @returns {number} a number in the [0, 255] range
|
1530
1516
|
*/
|
1531
1517
|
get brightness() {
|
1532
|
-
const { r, g, b } = this;
|
1518
|
+
const { r, g, b } = this.toRgb();
|
1533
1519
|
return (r * 299 + g * 587 + b * 114) / 1000;
|
1534
1520
|
}
|
1535
1521
|
|
@@ -1538,12 +1524,14 @@
|
|
1538
1524
|
* @returns {CP.RGBA} an {r,g,b,a} object with [0, 255] ranged values
|
1539
1525
|
*/
|
1540
1526
|
toRgb() {
|
1541
|
-
|
1527
|
+
let {
|
1542
1528
|
r, g, b, a,
|
1543
1529
|
} = this;
|
1544
1530
|
|
1531
|
+
[r, g, b] = [r, g, b].map((n) => roundPart(n * 255 * 100) / 100);
|
1532
|
+
a = roundPart(a * 100) / 100;
|
1545
1533
|
return {
|
1546
|
-
r, g, b, a
|
1534
|
+
r, g, b, a,
|
1547
1535
|
};
|
1548
1536
|
}
|
1549
1537
|
|
@@ -1637,7 +1625,7 @@
|
|
1637
1625
|
toHsv() {
|
1638
1626
|
const {
|
1639
1627
|
r, g, b, a,
|
1640
|
-
} = this
|
1628
|
+
} = this;
|
1641
1629
|
const { h, s, v } = rgbToHsv(r, g, b);
|
1642
1630
|
|
1643
1631
|
return {
|
@@ -1652,7 +1640,7 @@
|
|
1652
1640
|
toHsl() {
|
1653
1641
|
const {
|
1654
1642
|
r, g, b, a,
|
1655
|
-
} = this
|
1643
|
+
} = this;
|
1656
1644
|
const { h, s, l } = rgbToHsl(r, g, b);
|
1657
1645
|
|
1658
1646
|
return {
|
@@ -1737,6 +1725,7 @@
|
|
1737
1725
|
*/
|
1738
1726
|
setAlpha(alpha) {
|
1739
1727
|
const self = this;
|
1728
|
+
if (typeof alpha !== 'number') return self;
|
1740
1729
|
self.a = boundAlpha(alpha);
|
1741
1730
|
return self;
|
1742
1731
|
}
|
@@ -1903,26 +1892,23 @@
|
|
1903
1892
|
} else if (args.length === 2) {
|
1904
1893
|
[hueSteps, lightSteps] = args;
|
1905
1894
|
if ([hueSteps, lightSteps].some((n) => n < 1)) {
|
1906
|
-
throw TypeError('ColorPalette:
|
1895
|
+
throw TypeError('ColorPalette: both arguments must be higher than 0.');
|
1907
1896
|
}
|
1908
|
-
} else {
|
1909
|
-
throw TypeError('ColorPalette requires minimum 2 arguments');
|
1910
1897
|
}
|
1911
1898
|
|
1912
|
-
/** @type {
|
1899
|
+
/** @type {*} */
|
1913
1900
|
const colors = [];
|
1914
|
-
|
1915
1901
|
const hueStep = 360 / hueSteps;
|
1916
1902
|
const half = roundPart((lightSteps - (lightSteps % 2 ? 1 : 0)) / 2);
|
1917
|
-
const
|
1903
|
+
const steps1To13 = [0.25, 0.2, 0.15, 0.11, 0.09, 0.075];
|
1904
|
+
const lightSets = [[1, 2, 3], [4, 5], [6, 7], [8, 9], [10, 11], [12, 13]];
|
1905
|
+
const closestSet = lightSets.find((set) => set.includes(lightSteps));
|
1918
1906
|
|
1919
|
-
|
1920
|
-
|
1921
|
-
lightStep =
|
1922
|
-
|
1923
|
-
|
1924
|
-
lightStep = [12, 13].includes(lightSteps) ? 0.075 : lightStep;
|
1925
|
-
lightStep = lightSteps > 13 ? estimatedStep : lightStep;
|
1907
|
+
// find a lightStep that won't go beyond black and white
|
1908
|
+
// something within the [10-90] range of lightness
|
1909
|
+
const lightStep = closestSet
|
1910
|
+
? steps1To13[lightSets.indexOf(closestSet)]
|
1911
|
+
: (100 / (lightSteps + (lightSteps % 2 ? 0 : 1)) / 100);
|
1926
1912
|
|
1927
1913
|
// light tints
|
1928
1914
|
for (let i = 1; i < half + 1; i += 1) {
|
@@ -2437,7 +2423,7 @@
|
|
2437
2423
|
setAttribute(input, tabIndex, '-1');
|
2438
2424
|
}
|
2439
2425
|
|
2440
|
-
var version = "0.0.
|
2426
|
+
var version = "0.0.2alpha2";
|
2441
2427
|
|
2442
2428
|
// @ts-ignore
|
2443
2429
|
|
@@ -2480,8 +2466,6 @@
|
|
2480
2466
|
fn(input, focusinEvent, self.showPicker);
|
2481
2467
|
fn(pickerToggle, mouseclickEvent, self.togglePicker);
|
2482
2468
|
|
2483
|
-
fn(input, keydownEvent, self.keyToggle);
|
2484
|
-
|
2485
2469
|
if (menuToggle) {
|
2486
2470
|
fn(menuToggle, mouseclickEvent, self.toggleMenu);
|
2487
2471
|
}
|
@@ -2519,8 +2503,7 @@
|
|
2519
2503
|
fn(doc, pointerEvents.move, self.pointerMove);
|
2520
2504
|
fn(doc, pointerEvents.up, self.pointerUp);
|
2521
2505
|
fn(parent, focusoutEvent, self.handleFocusOut);
|
2522
|
-
|
2523
|
-
fn(win, keyupEvent, self.handleDismiss);
|
2506
|
+
fn(doc, keyupEvent, self.handleDismiss);
|
2524
2507
|
}
|
2525
2508
|
|
2526
2509
|
/**
|
@@ -2604,7 +2587,7 @@
|
|
2604
2587
|
const input = querySelector(target);
|
2605
2588
|
|
2606
2589
|
// invalidate
|
2607
|
-
if (!input) throw new TypeError(`ColorPicker target ${target} cannot be found.`);
|
2590
|
+
if (!input) throw new TypeError(`ColorPicker target "${target}" cannot be found.`);
|
2608
2591
|
self.input = input;
|
2609
2592
|
|
2610
2593
|
const parent = closest(input, colorPickerParentSelector);
|
@@ -2651,15 +2634,14 @@
|
|
2651
2634
|
});
|
2652
2635
|
|
2653
2636
|
// update and expose component labels
|
2654
|
-
const
|
2655
|
-
|
2656
|
-
? JSON.parse(componentLabels) : componentLabels || {};
|
2637
|
+
const tempComponentLabels = componentLabels && isValidJSON(componentLabels)
|
2638
|
+
? JSON.parse(componentLabels) : componentLabels;
|
2657
2639
|
|
2658
2640
|
/** @type {Record<string, string>} */
|
2659
|
-
self.componentLabels = ObjectAssign(
|
2641
|
+
self.componentLabels = ObjectAssign(colorPickerLabels, tempComponentLabels);
|
2660
2642
|
|
2661
2643
|
/** @type {Color} */
|
2662
|
-
self.color = new Color('
|
2644
|
+
self.color = new Color(input.value || '#fff', format);
|
2663
2645
|
|
2664
2646
|
/** @type {CP.ColorFormats} */
|
2665
2647
|
self.format = format;
|
@@ -2668,7 +2650,7 @@
|
|
2668
2650
|
if (colorKeywords instanceof Array) {
|
2669
2651
|
self.colorKeywords = colorKeywords;
|
2670
2652
|
} else if (typeof colorKeywords === 'string' && colorKeywords.length) {
|
2671
|
-
self.colorKeywords = colorKeywords.split(',');
|
2653
|
+
self.colorKeywords = colorKeywords.split(',').map((x) => x.trim());
|
2672
2654
|
}
|
2673
2655
|
|
2674
2656
|
// set colour presets
|
@@ -2697,7 +2679,6 @@
|
|
2697
2679
|
self.handleFocusOut = self.handleFocusOut.bind(self);
|
2698
2680
|
self.changeHandler = self.changeHandler.bind(self);
|
2699
2681
|
self.handleDismiss = self.handleDismiss.bind(self);
|
2700
|
-
self.keyToggle = self.keyToggle.bind(self);
|
2701
2682
|
self.handleKnobs = self.handleKnobs.bind(self);
|
2702
2683
|
|
2703
2684
|
// generate markup
|
@@ -2789,76 +2770,83 @@
|
|
2789
2770
|
return inputValue !== '' && new Color(inputValue).isValid;
|
2790
2771
|
}
|
2791
2772
|
|
2773
|
+
/** Returns the colour appearance, usually the closest colour name for the current value. */
|
2774
|
+
get appearance() {
|
2775
|
+
const {
|
2776
|
+
colorLabels, hsl, hsv, format,
|
2777
|
+
} = this;
|
2778
|
+
|
2779
|
+
const hue = roundPart(hsl.h * 360);
|
2780
|
+
const saturationSource = format === 'hsl' ? hsl.s : hsv.s;
|
2781
|
+
const saturation = roundPart(saturationSource * 100);
|
2782
|
+
const lightness = roundPart(hsl.l * 100);
|
2783
|
+
const hsvl = hsv.v * 100;
|
2784
|
+
|
2785
|
+
let colorName;
|
2786
|
+
|
2787
|
+
// determine color appearance
|
2788
|
+
if (lightness === 100 && saturation === 0) {
|
2789
|
+
colorName = colorLabels.white;
|
2790
|
+
} else if (lightness === 0) {
|
2791
|
+
colorName = colorLabels.black;
|
2792
|
+
} else if (saturation === 0) {
|
2793
|
+
colorName = colorLabels.grey;
|
2794
|
+
} else if (hue < 15 || hue >= 345) {
|
2795
|
+
colorName = colorLabels.red;
|
2796
|
+
} else if (hue >= 15 && hue < 45) {
|
2797
|
+
colorName = hsvl > 80 && saturation > 80 ? colorLabels.orange : colorLabels.brown;
|
2798
|
+
} else if (hue >= 45 && hue < 75) {
|
2799
|
+
const isGold = hue > 46 && hue < 54 && hsvl < 80 && saturation > 90;
|
2800
|
+
const isOlive = hue >= 54 && hue < 75 && hsvl < 80;
|
2801
|
+
colorName = isGold ? colorLabels.gold : colorLabels.yellow;
|
2802
|
+
colorName = isOlive ? colorLabels.olive : colorName;
|
2803
|
+
} else if (hue >= 75 && hue < 155) {
|
2804
|
+
colorName = hsvl < 68 ? colorLabels.green : colorLabels.lime;
|
2805
|
+
} else if (hue >= 155 && hue < 175) {
|
2806
|
+
colorName = colorLabels.teal;
|
2807
|
+
} else if (hue >= 175 && hue < 195) {
|
2808
|
+
colorName = colorLabels.cyan;
|
2809
|
+
} else if (hue >= 195 && hue < 255) {
|
2810
|
+
colorName = colorLabels.blue;
|
2811
|
+
} else if (hue >= 255 && hue < 270) {
|
2812
|
+
colorName = colorLabels.violet;
|
2813
|
+
} else if (hue >= 270 && hue < 295) {
|
2814
|
+
colorName = colorLabels.magenta;
|
2815
|
+
} else if (hue >= 295 && hue < 345) {
|
2816
|
+
colorName = colorLabels.pink;
|
2817
|
+
}
|
2818
|
+
return colorName;
|
2819
|
+
}
|
2820
|
+
|
2792
2821
|
/** Updates `ColorPicker` visuals. */
|
2793
2822
|
updateVisuals() {
|
2794
2823
|
const self = this;
|
2795
2824
|
const {
|
2796
|
-
|
2825
|
+
controlPositions, visuals,
|
2797
2826
|
} = self;
|
2798
2827
|
const [v1, v2, v3] = visuals;
|
2799
|
-
const {
|
2800
|
-
const hue =
|
2801
|
-
|
2802
|
-
: controlPositions.c2y / offsetHeight;
|
2803
|
-
// @ts-ignore - `hslToRgb` is assigned to `Color` as static method
|
2804
|
-
const { r, g, b } = Color.hslToRgb(hue, 1, 0.5);
|
2828
|
+
const { offsetHeight } = v1;
|
2829
|
+
const hue = controlPositions.c2y / offsetHeight;
|
2830
|
+
const { r, g, b } = new Color({ h: hue, s: 1, l: 0.5 }).toRgb();
|
2805
2831
|
const whiteGrad = 'linear-gradient(rgb(255,255,255) 0%, rgb(255,255,255) 100%)';
|
2806
2832
|
const alpha = 1 - controlPositions.c3y / offsetHeight;
|
2807
2833
|
const roundA = roundPart((alpha * 100)) / 100;
|
2808
2834
|
|
2809
|
-
|
2810
|
-
|
2811
|
-
|
2812
|
-
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
|
2817
|
-
|
2818
|
-
|
2819
|
-
|
2820
|
-
|
2821
|
-
|
2822
|
-
|
2823
|
-
setElementStyle(v2, { background: hueGradient });
|
2824
|
-
} else {
|
2825
|
-
const saturation = roundPart((controlPositions.c2y / offsetHeight) * 100);
|
2826
|
-
const fill0 = new Color({
|
2827
|
-
r: 255, g: 0, b: 0, a: alpha,
|
2828
|
-
}).saturate(-saturation).toRgbString();
|
2829
|
-
const fill1 = new Color({
|
2830
|
-
r: 255, g: 255, b: 0, a: alpha,
|
2831
|
-
}).saturate(-saturation).toRgbString();
|
2832
|
-
const fill2 = new Color({
|
2833
|
-
r: 0, g: 255, b: 0, a: alpha,
|
2834
|
-
}).saturate(-saturation).toRgbString();
|
2835
|
-
const fill3 = new Color({
|
2836
|
-
r: 0, g: 255, b: 255, a: alpha,
|
2837
|
-
}).saturate(-saturation).toRgbString();
|
2838
|
-
const fill4 = new Color({
|
2839
|
-
r: 0, g: 0, b: 255, a: alpha,
|
2840
|
-
}).saturate(-saturation).toRgbString();
|
2841
|
-
const fill5 = new Color({
|
2842
|
-
r: 255, g: 0, b: 255, a: alpha,
|
2843
|
-
}).saturate(-saturation).toRgbString();
|
2844
|
-
const fill6 = new Color({
|
2845
|
-
r: 255, g: 0, b: 0, a: alpha,
|
2846
|
-
}).saturate(-saturation).toRgbString();
|
2847
|
-
const fillGradient = `linear-gradient(to right,
|
2848
|
-
${fill0} 0%, ${fill1} 16.67%, ${fill2} 33.33%, ${fill3} 50%,
|
2849
|
-
${fill4} 66.67%, ${fill5} 83.33%, ${fill6} 100%)`;
|
2850
|
-
const lightGrad = `linear-gradient(rgba(255,255,255,${roundA}) 0%, rgba(255,255,255,0) 50%),
|
2851
|
-
linear-gradient(rgba(0,0,0,0) 50%, rgba(0,0,0,${roundA}) 100%)`;
|
2852
|
-
|
2853
|
-
setElementStyle(v1, { background: `${lightGrad},${fillGradient},${whiteGrad}` });
|
2854
|
-
const {
|
2855
|
-
r: gr, g: gg, b: gb,
|
2856
|
-
} = new Color({ r, g, b }).greyscale().toRgb();
|
2835
|
+
const fill = new Color({
|
2836
|
+
h: hue, s: 1, l: 0.5, a: alpha,
|
2837
|
+
}).toRgbString();
|
2838
|
+
const hueGradient = `linear-gradient(
|
2839
|
+
rgb(255,0,0) 0%, rgb(255,255,0) 16.67%,
|
2840
|
+
rgb(0,255,0) 33.33%, rgb(0,255,255) 50%,
|
2841
|
+
rgb(0,0,255) 66.67%, rgb(255,0,255) 83.33%,
|
2842
|
+
rgb(255,0,0) 100%)`;
|
2843
|
+
setElementStyle(v1, {
|
2844
|
+
background: `linear-gradient(rgba(0,0,0,0) 0%, rgba(0,0,0,${roundA}) 100%),
|
2845
|
+
linear-gradient(to right, rgba(255,255,255,${roundA}) 0%, ${fill} 100%),
|
2846
|
+
${whiteGrad}`,
|
2847
|
+
});
|
2848
|
+
setElementStyle(v2, { background: hueGradient });
|
2857
2849
|
|
2858
|
-
setElementStyle(v2, {
|
2859
|
-
background: `linear-gradient(rgb(${r},${g},${b}) 0%, rgb(${gr},${gg},${gb}) 100%)`,
|
2860
|
-
});
|
2861
|
-
}
|
2862
2850
|
setElementStyle(v3, {
|
2863
2851
|
background: `linear-gradient(rgba(${r},${g},${b},1) 0%,rgba(${r},${g},${b},0) 100%)`,
|
2864
2852
|
});
|
@@ -3008,13 +2996,13 @@
|
|
3008
2996
|
const [v1, v2, v3] = visuals;
|
3009
2997
|
const [c1, c2, c3] = controlKnobs;
|
3010
2998
|
/** @type {HTMLElement} */
|
3011
|
-
const visual =
|
3012
|
-
? target : querySelector('.visual-control', target.parentElement);
|
2999
|
+
const visual = controlKnobs.includes(target) ? target.previousElementSibling : target;
|
3013
3000
|
const visualRect = getBoundingClientRect(visual);
|
3001
|
+
const html = getDocumentElement(v1);
|
3014
3002
|
const X = type === 'touchstart' ? touches[0].pageX : pageX;
|
3015
3003
|
const Y = type === 'touchstart' ? touches[0].pageY : pageY;
|
3016
|
-
const offsetX = X -
|
3017
|
-
const offsetY = Y -
|
3004
|
+
const offsetX = X - html.scrollLeft - visualRect.left;
|
3005
|
+
const offsetY = Y - html.scrollTop - visualRect.top;
|
3018
3006
|
|
3019
3007
|
if (target === v1 || target === c1) {
|
3020
3008
|
self.dragElement = visual;
|
@@ -3074,10 +3062,11 @@
|
|
3074
3062
|
if (!dragElement) return;
|
3075
3063
|
|
3076
3064
|
const controlRect = getBoundingClientRect(dragElement);
|
3077
|
-
const
|
3078
|
-
const
|
3079
|
-
const
|
3080
|
-
const
|
3065
|
+
const win = getDocumentElement(v1);
|
3066
|
+
const X = type === touchmoveEvent ? touches[0].pageX : pageX;
|
3067
|
+
const Y = type === touchmoveEvent ? touches[0].pageY : pageY;
|
3068
|
+
const offsetX = X - win.scrollLeft - controlRect.left;
|
3069
|
+
const offsetY = Y - win.scrollTop - controlRect.top;
|
3081
3070
|
|
3082
3071
|
if (dragElement === v1) {
|
3083
3072
|
self.changeControl1(offsetX, offsetY);
|
@@ -3104,19 +3093,19 @@
|
|
3104
3093
|
if (![keyArrowUp, keyArrowDown, keyArrowLeft, keyArrowRight].includes(code)) return;
|
3105
3094
|
e.preventDefault();
|
3106
3095
|
|
3107
|
-
const {
|
3096
|
+
const { controlKnobs, visuals } = self;
|
3108
3097
|
const { offsetWidth, offsetHeight } = visuals[0];
|
3109
3098
|
const [c1, c2, c3] = controlKnobs;
|
3110
3099
|
const { activeElement } = getDocument(c1);
|
3111
3100
|
const currentKnob = controlKnobs.find((x) => x === activeElement);
|
3112
|
-
const yRatio = offsetHeight /
|
3101
|
+
const yRatio = offsetHeight / 360;
|
3113
3102
|
|
3114
3103
|
if (currentKnob) {
|
3115
3104
|
let offsetX = 0;
|
3116
3105
|
let offsetY = 0;
|
3117
3106
|
|
3118
3107
|
if (target === c1) {
|
3119
|
-
const xRatio = offsetWidth /
|
3108
|
+
const xRatio = offsetWidth / 100;
|
3120
3109
|
|
3121
3110
|
if ([keyArrowLeft, keyArrowRight].includes(code)) {
|
3122
3111
|
self.controlPositions.c1x += code === keyArrowRight ? xRatio : -xRatio;
|
@@ -3166,7 +3155,7 @@
|
|
3166
3155
|
if (activeElement === input || (activeElement && inputs.includes(activeElement))) {
|
3167
3156
|
if (activeElement === input) {
|
3168
3157
|
if (isNonColorValue) {
|
3169
|
-
colorSource = '
|
3158
|
+
colorSource = currentValue === 'transparent' ? 'rgba(0,0,0,0)' : 'rgb(0,0,0)';
|
3170
3159
|
} else {
|
3171
3160
|
colorSource = currentValue;
|
3172
3161
|
}
|
@@ -3217,9 +3206,7 @@
|
|
3217
3206
|
changeControl1(X, Y) {
|
3218
3207
|
const self = this;
|
3219
3208
|
let [offsetX, offsetY] = [0, 0];
|
3220
|
-
const {
|
3221
|
-
format, controlPositions, visuals,
|
3222
|
-
} = self;
|
3209
|
+
const { controlPositions, visuals } = self;
|
3223
3210
|
const { offsetHeight, offsetWidth } = visuals[0];
|
3224
3211
|
|
3225
3212
|
if (X > offsetWidth) offsetX = offsetWidth;
|
@@ -3228,29 +3215,19 @@
|
|
3228
3215
|
if (Y > offsetHeight) offsetY = offsetHeight;
|
3229
3216
|
else if (Y >= 0) offsetY = Y;
|
3230
3217
|
|
3231
|
-
const hue =
|
3232
|
-
? offsetX / offsetWidth
|
3233
|
-
: controlPositions.c2y / offsetHeight;
|
3218
|
+
const hue = controlPositions.c2y / offsetHeight;
|
3234
3219
|
|
3235
|
-
const saturation =
|
3236
|
-
? 1 - controlPositions.c2y / offsetHeight
|
3237
|
-
: offsetX / offsetWidth;
|
3220
|
+
const saturation = offsetX / offsetWidth;
|
3238
3221
|
|
3239
3222
|
const lightness = 1 - offsetY / offsetHeight;
|
3240
3223
|
const alpha = 1 - controlPositions.c3y / offsetHeight;
|
3241
3224
|
|
3242
|
-
const colorObject = format === 'hsl'
|
3243
|
-
? {
|
3244
|
-
h: hue, s: saturation, l: lightness, a: alpha,
|
3245
|
-
}
|
3246
|
-
: {
|
3247
|
-
h: hue, s: saturation, v: lightness, a: alpha,
|
3248
|
-
};
|
3249
|
-
|
3250
3225
|
// new color
|
3251
3226
|
const {
|
3252
3227
|
r, g, b, a,
|
3253
|
-
} = new Color(
|
3228
|
+
} = new Color({
|
3229
|
+
h: hue, s: saturation, v: lightness, a: alpha,
|
3230
|
+
});
|
3254
3231
|
|
3255
3232
|
ObjectAssign(self.color, {
|
3256
3233
|
r, g, b, a,
|
@@ -3277,7 +3254,7 @@
|
|
3277
3254
|
changeControl2(Y) {
|
3278
3255
|
const self = this;
|
3279
3256
|
const {
|
3280
|
-
|
3257
|
+
controlPositions, visuals,
|
3281
3258
|
} = self;
|
3282
3259
|
const { offsetHeight, offsetWidth } = visuals[0];
|
3283
3260
|
|
@@ -3286,26 +3263,17 @@
|
|
3286
3263
|
if (Y > offsetHeight) offsetY = offsetHeight;
|
3287
3264
|
else if (Y >= 0) offsetY = Y;
|
3288
3265
|
|
3289
|
-
const hue =
|
3290
|
-
|
3291
|
-
: offsetY / offsetHeight;
|
3292
|
-
const saturation = format === 'hsl'
|
3293
|
-
? 1 - offsetY / offsetHeight
|
3294
|
-
: controlPositions.c1x / offsetWidth;
|
3266
|
+
const hue = offsetY / offsetHeight;
|
3267
|
+
const saturation = controlPositions.c1x / offsetWidth;
|
3295
3268
|
const lightness = 1 - controlPositions.c1y / offsetHeight;
|
3296
3269
|
const alpha = 1 - controlPositions.c3y / offsetHeight;
|
3297
|
-
const colorObject = format === 'hsl'
|
3298
|
-
? {
|
3299
|
-
h: hue, s: saturation, l: lightness, a: alpha,
|
3300
|
-
}
|
3301
|
-
: {
|
3302
|
-
h: hue, s: saturation, v: lightness, a: alpha,
|
3303
|
-
};
|
3304
3270
|
|
3305
3271
|
// new color
|
3306
3272
|
const {
|
3307
3273
|
r, g, b, a,
|
3308
|
-
} = new Color(
|
3274
|
+
} = new Color({
|
3275
|
+
h: hue, s: saturation, v: lightness, a: alpha,
|
3276
|
+
});
|
3309
3277
|
|
3310
3278
|
ObjectAssign(self.color, {
|
3311
3279
|
r, g, b, a,
|
@@ -3392,18 +3360,18 @@
|
|
3392
3360
|
setControlPositions() {
|
3393
3361
|
const self = this;
|
3394
3362
|
const {
|
3395
|
-
|
3363
|
+
visuals, color, hsv,
|
3396
3364
|
} = self;
|
3397
3365
|
const { offsetHeight, offsetWidth } = visuals[0];
|
3398
3366
|
const alpha = color.a;
|
3399
|
-
const hue =
|
3367
|
+
const hue = hsv.h;
|
3400
3368
|
|
3401
|
-
const saturation =
|
3402
|
-
const lightness =
|
3369
|
+
const saturation = hsv.s;
|
3370
|
+
const lightness = hsv.v;
|
3403
3371
|
|
3404
|
-
self.controlPositions.c1x =
|
3372
|
+
self.controlPositions.c1x = saturation * offsetWidth;
|
3405
3373
|
self.controlPositions.c1y = (1 - lightness) * offsetHeight;
|
3406
|
-
self.controlPositions.c2y =
|
3374
|
+
self.controlPositions.c2y = hue * offsetHeight;
|
3407
3375
|
self.controlPositions.c3y = (1 - alpha) * offsetHeight;
|
3408
3376
|
}
|
3409
3377
|
|
@@ -3411,78 +3379,40 @@
|
|
3411
3379
|
updateAppearance() {
|
3412
3380
|
const self = this;
|
3413
3381
|
const {
|
3414
|
-
componentLabels,
|
3415
|
-
|
3382
|
+
componentLabels, color, parent,
|
3383
|
+
hsv, hex, format, controlKnobs,
|
3416
3384
|
} = self;
|
3417
3385
|
const {
|
3418
3386
|
appearanceLabel, hexLabel, valueLabel,
|
3419
3387
|
} = componentLabels;
|
3420
|
-
|
3388
|
+
let { r, g, b } = color.toRgb();
|
3421
3389
|
const [knob1, knob2, knob3] = controlKnobs;
|
3422
|
-
const hue = roundPart(
|
3390
|
+
const hue = roundPart(hsv.h * 360);
|
3423
3391
|
const alpha = color.a;
|
3424
|
-
const
|
3425
|
-
const
|
3426
|
-
const
|
3427
|
-
const hsvl = hsv.v * 100;
|
3428
|
-
let colorName;
|
3429
|
-
|
3430
|
-
// determine color appearance
|
3431
|
-
if (lightness === 100 && saturation === 0) {
|
3432
|
-
colorName = colorLabels.white;
|
3433
|
-
} else if (lightness === 0) {
|
3434
|
-
colorName = colorLabels.black;
|
3435
|
-
} else if (saturation === 0) {
|
3436
|
-
colorName = colorLabels.grey;
|
3437
|
-
} else if (hue < 15 || hue >= 345) {
|
3438
|
-
colorName = colorLabels.red;
|
3439
|
-
} else if (hue >= 15 && hue < 45) {
|
3440
|
-
colorName = hsvl > 80 && saturation > 80 ? colorLabels.orange : colorLabels.brown;
|
3441
|
-
} else if (hue >= 45 && hue < 75) {
|
3442
|
-
const isGold = hue > 46 && hue < 54 && hsvl < 80 && saturation > 90;
|
3443
|
-
const isOlive = hue >= 54 && hue < 75 && hsvl < 80;
|
3444
|
-
colorName = isGold ? colorLabels.gold : colorLabels.yellow;
|
3445
|
-
colorName = isOlive ? colorLabels.olive : colorName;
|
3446
|
-
} else if (hue >= 75 && hue < 155) {
|
3447
|
-
colorName = hsvl < 68 ? colorLabels.green : colorLabels.lime;
|
3448
|
-
} else if (hue >= 155 && hue < 175) {
|
3449
|
-
colorName = colorLabels.teal;
|
3450
|
-
} else if (hue >= 175 && hue < 195) {
|
3451
|
-
colorName = colorLabels.cyan;
|
3452
|
-
} else if (hue >= 195 && hue < 255) {
|
3453
|
-
colorName = colorLabels.blue;
|
3454
|
-
} else if (hue >= 255 && hue < 270) {
|
3455
|
-
colorName = colorLabels.violet;
|
3456
|
-
} else if (hue >= 270 && hue < 295) {
|
3457
|
-
colorName = colorLabels.magenta;
|
3458
|
-
} else if (hue >= 295 && hue < 345) {
|
3459
|
-
colorName = colorLabels.pink;
|
3460
|
-
}
|
3392
|
+
const saturation = roundPart(hsv.s * 100);
|
3393
|
+
const lightness = roundPart(hsv.v * 100);
|
3394
|
+
const colorName = self.appearance;
|
3461
3395
|
|
3462
3396
|
let colorLabel = `${hexLabel} ${hex.split('').join(' ')}`;
|
3463
3397
|
|
3464
|
-
if (format === '
|
3465
|
-
colorLabel = `HSL: ${hue}°, ${saturation}%, ${lightness}%`;
|
3466
|
-
setAttribute(knob1, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3467
|
-
setAttribute(knob1, ariaValueText, `${hue}° & ${lightness}%`);
|
3468
|
-
setAttribute(knob1, ariaValueNow, `${hue}`);
|
3469
|
-
setAttribute(knob2, ariaValueText, `${saturation}%`);
|
3470
|
-
setAttribute(knob2, ariaValueNow, `${saturation}`);
|
3471
|
-
} else if (format === 'hwb') {
|
3398
|
+
if (format === 'hwb') {
|
3472
3399
|
const { hwb } = self;
|
3473
3400
|
const whiteness = roundPart(hwb.w * 100);
|
3474
3401
|
const blackness = roundPart(hwb.b * 100);
|
3475
3402
|
colorLabel = `HWB: ${hue}°, ${whiteness}%, ${blackness}%`;
|
3476
|
-
setAttribute(knob1, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3477
3403
|
setAttribute(knob1, ariaValueText, `${whiteness}% & ${blackness}%`);
|
3478
3404
|
setAttribute(knob1, ariaValueNow, `${whiteness}`);
|
3405
|
+
setAttribute(knob2, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3479
3406
|
setAttribute(knob2, ariaValueText, `${hue}%`);
|
3480
3407
|
setAttribute(knob2, ariaValueNow, `${hue}`);
|
3481
3408
|
} else {
|
3409
|
+
[r, g, b] = [r, g, b].map(roundPart);
|
3410
|
+
colorLabel = format === 'hsl' ? `HSL: ${hue}°, ${saturation}%, ${lightness}%` : colorLabel;
|
3482
3411
|
colorLabel = format === 'rgb' ? `RGB: ${r}, ${g}, ${b}` : colorLabel;
|
3483
|
-
|
3412
|
+
|
3484
3413
|
setAttribute(knob1, ariaValueText, `${lightness}% & ${saturation}%`);
|
3485
3414
|
setAttribute(knob1, ariaValueNow, `${lightness}`);
|
3415
|
+
setAttribute(knob2, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3486
3416
|
setAttribute(knob2, ariaValueText, `${hue}°`);
|
3487
3417
|
setAttribute(knob2, ariaValueNow, `${hue}`);
|
3488
3418
|
}
|
@@ -3577,37 +3507,13 @@
|
|
3577
3507
|
}
|
3578
3508
|
}
|
3579
3509
|
|
3580
|
-
/**
|
3581
|
-
* The `Space` & `Enter` keys specific event listener.
|
3582
|
-
* Toggle visibility of the `ColorPicker` / the presets menu, showing one will hide the other.
|
3583
|
-
* @param {KeyboardEvent} e
|
3584
|
-
* @this {ColorPicker}
|
3585
|
-
*/
|
3586
|
-
keyToggle(e) {
|
3587
|
-
const self = this;
|
3588
|
-
const { menuToggle } = self;
|
3589
|
-
const { activeElement } = getDocument(menuToggle);
|
3590
|
-
const { code } = e;
|
3591
|
-
|
3592
|
-
if ([keyEnter, keySpace].includes(code)) {
|
3593
|
-
if ((menuToggle && activeElement === menuToggle) || !activeElement) {
|
3594
|
-
e.preventDefault();
|
3595
|
-
if (!activeElement) {
|
3596
|
-
self.togglePicker(e);
|
3597
|
-
} else {
|
3598
|
-
self.toggleMenu();
|
3599
|
-
}
|
3600
|
-
}
|
3601
|
-
}
|
3602
|
-
}
|
3603
|
-
|
3604
3510
|
/**
|
3605
3511
|
* Toggle the `ColorPicker` dropdown visibility.
|
3606
|
-
* @param {Event} e
|
3512
|
+
* @param {Event=} e
|
3607
3513
|
* @this {ColorPicker}
|
3608
3514
|
*/
|
3609
3515
|
togglePicker(e) {
|
3610
|
-
e.preventDefault();
|
3516
|
+
if (e) e.preventDefault();
|
3611
3517
|
const self = this;
|
3612
3518
|
const { colorPicker } = self;
|
3613
3519
|
|
@@ -3628,8 +3534,13 @@
|
|
3628
3534
|
}
|
3629
3535
|
}
|
3630
3536
|
|
3631
|
-
/**
|
3632
|
-
|
3537
|
+
/**
|
3538
|
+
* Toggles the visibility of the `ColorPicker` presets menu.
|
3539
|
+
* @param {Event=} e
|
3540
|
+
* @this {ColorPicker}
|
3541
|
+
*/
|
3542
|
+
toggleMenu(e) {
|
3543
|
+
if (e) e.preventDefault();
|
3633
3544
|
const self = this;
|
3634
3545
|
const { colorMenu } = self;
|
3635
3546
|
|
@@ -3655,6 +3566,10 @@
|
|
3655
3566
|
const relatedBtn = openPicker ? pickerToggle : menuToggle;
|
3656
3567
|
const animationDuration = openDropdown && getElementTransitionDuration(openDropdown);
|
3657
3568
|
|
3569
|
+
// if (!self.isValid) {
|
3570
|
+
self.value = self.color.toString(true);
|
3571
|
+
// }
|
3572
|
+
|
3658
3573
|
if (openDropdown) {
|
3659
3574
|
removeClass(openDropdown, 'show');
|
3660
3575
|
setAttribute(relatedBtn, ariaExpanded, 'false');
|
@@ -3668,9 +3583,6 @@
|
|
3668
3583
|
}, animationDuration);
|
3669
3584
|
}
|
3670
3585
|
|
3671
|
-
if (!self.isValid) {
|
3672
|
-
self.value = self.color.toString();
|
3673
|
-
}
|
3674
3586
|
if (!focusPrevented) {
|
3675
3587
|
focus(pickerToggle);
|
3676
3588
|
}
|