@fils/color 0.0.9 → 0.1.0

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.
@@ -21,6 +21,7 @@ export function drawColorPickerBar(canvas, x, y, width, height) {
21
21
  const h = height !== undefined ? height : canvas.height;
22
22
  const ctx = canvas.getContext('2d');
23
23
  for (let i = 0; i < w; i++) {
24
+ // const rad = (i * Math.PI) / 180;
24
25
  const dx = _x + i;
25
26
  const angle = 360 * i / w;
26
27
  ctx.fillStyle = `hsl(${angle}, 100%, 50%)`;
@@ -42,7 +43,7 @@ export function drawColorPickerSL(canvas, angle, x, y, width, height) {
42
43
  s: j,
43
44
  b: i
44
45
  });
45
- ctx.fillStyle = hex;
46
+ ctx.fillStyle = hex; //`hsl(${angle}, ${j}%, ${100-i}%)`;
46
47
  ctx.fillRect(_x + w * j / 100, _y + h - h * i / 100, sw, sh);
47
48
  }
48
49
  }
package/lib/utils.d.ts CHANGED
@@ -26,3 +26,15 @@ export declare function hsbToHex(color: HSBColor): string;
26
26
  export declare function rgbToString(color: RGBColor): string;
27
27
  export declare function hsbToString(color: HSBColor): string;
28
28
  export declare function fixHex(color: string): string;
29
+ export type LABColor = {
30
+ l: number;
31
+ a: number;
32
+ b: number;
33
+ };
34
+ export declare function rgbToLab(color: RGBColor): LABColor;
35
+ export declare function colorDistance(color1: RGBColor, color2: RGBColor): number;
36
+ export declare function findClosestColor(target: RGBColor, palette: RGBColor[]): {
37
+ color: RGBColor;
38
+ distance: number;
39
+ index: number;
40
+ };
package/lib/utils.js CHANGED
@@ -22,7 +22,7 @@ export function rgbToHsl(color) {
22
22
  const min = Math.min(r, g, b);
23
23
  let h, s, l = (max + min) / 2;
24
24
  if (max == min) {
25
- h = s = 0;
25
+ h = s = 0; // achromatic
26
26
  }
27
27
  else {
28
28
  let d = max - min;
@@ -63,9 +63,10 @@ export function hslToRgb(color) {
63
63
  let r, g, b;
64
64
  const h = color.h, s = color.s, l = color.l;
65
65
  if (s == 0) {
66
- r = g = b = l;
66
+ r = g = b = l; // achromatic
67
67
  }
68
68
  else {
69
+ // eslint-disable-next-line no-inner-declarations
69
70
  let q = color.l < 0.5 ? l * (1 + s) : l + s - l * s;
70
71
  let p = 2 * l - q;
71
72
  r = hue2rgb(p, q, h + 1 / 3);
@@ -143,6 +144,7 @@ export function fixHex(color) {
143
144
  while (fixedColor.length < 7) {
144
145
  fixedColor += "F";
145
146
  }
147
+ // Replace invalid characters with their closest valid hexadecimal equivalent using a regular expression
146
148
  fixedColor = fixedColor.replace(/[^A-F0-9]/g, (c) => {
147
149
  switch (c) {
148
150
  case "#":
@@ -174,3 +176,59 @@ export function fixHex(color) {
174
176
  });
175
177
  return fixedColor;
176
178
  }
179
+ // RGB to LAB conversion (via XYZ)
180
+ export function rgbToLab(color) {
181
+ // Convert RGB to linear RGB
182
+ let r = color.r / 255;
183
+ let g = color.g / 255;
184
+ let b = color.b / 255;
185
+ // Apply sRGB gamma correction
186
+ r = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
187
+ g = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
188
+ b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
189
+ // Convert to XYZ using sRGB matrix (D65 illuminant)
190
+ let x = (r * 0.4124564 + g * 0.3575761 + b * 0.1804375) * 100;
191
+ let y = (r * 0.2126729 + g * 0.7151522 + b * 0.0721750) * 100;
192
+ let z = (r * 0.0193339 + g * 0.1191920 + b * 0.9503041) * 100;
193
+ // Normalize for D65 white point
194
+ x /= 95.047;
195
+ y /= 100.000;
196
+ z /= 108.883;
197
+ // Convert XYZ to LAB
198
+ x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x + 16 / 116);
199
+ y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y + 16 / 116);
200
+ z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z + 16 / 116);
201
+ return {
202
+ l: (116 * y) - 16,
203
+ a: 500 * (x - y),
204
+ b: 200 * (y - z)
205
+ };
206
+ }
207
+ // Simple ΔE*ab color difference (good enough for most cases)
208
+ export function colorDistance(color1, color2) {
209
+ const lab1 = rgbToLab(color1);
210
+ const lab2 = rgbToLab(color2);
211
+ const deltaL = lab1.l - lab2.l;
212
+ const deltaA = lab1.a - lab2.a;
213
+ const deltaB = lab1.b - lab2.b;
214
+ return Math.sqrt(deltaL * deltaL + deltaA * deltaA + deltaB * deltaB);
215
+ }
216
+ // Find closest color in palette
217
+ export function findClosestColor(target, palette) {
218
+ let minDistance = Infinity;
219
+ let closestColor = palette[0];
220
+ let closestIndex = 0;
221
+ palette.forEach((paletteColor, index) => {
222
+ const distance = colorDistance(target, paletteColor);
223
+ if (distance < minDistance) {
224
+ minDistance = distance;
225
+ closestColor = paletteColor;
226
+ closestIndex = index;
227
+ }
228
+ });
229
+ return {
230
+ color: closestColor,
231
+ distance: minDistance,
232
+ index: closestIndex
233
+ };
234
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fils/color",
3
- "version": "0.0.9",
3
+ "version": "0.1.0",
4
4
  "description": "Color Package written in TypeScript",
5
5
  "main": "lib/main.js",
6
6
  "repository": "git@github.com:fil-studio/fils.git",
@@ -10,14 +10,12 @@
10
10
  "private": false,
11
11
  "scripts": {
12
12
  "prepare": "yarn build",
13
- "build": "tsc --build tsconfig.color.json"
13
+ "build": "tsc"
14
14
  },
15
15
  "files": [
16
- "lib",
17
- "examples",
18
- "README.md"
16
+ "lib"
19
17
  ],
20
18
  "devDependencies": {
21
- "typescript": "^4.8.4"
19
+ "typescript": "^5.9.3"
22
20
  }
23
21
  }