@sardine/colour 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Sardine
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # colour
2
+ It does things to colours!
@@ -0,0 +1,2 @@
1
+ import{bigSquare as a,deltaHue_d as b,hue_d as c,meanHue_d as d,toRadians as e}from"./util/index.js";export function ciede2000(f,g){const h=f.L,i=f.a,j=f.b,k=g.L,l=g.a,m=g.b,n=Math.sqrt(Math.pow(i,2)+Math.pow(j,2)),o=Math.sqrt(Math.pow(l,2)+Math.pow(m,2)),p=.5*(1-a((n+o)/2)),q=i*(1+p),r=l*(1+p),s=Math.sqrt(Math.pow(q,2)+Math.pow(j,2)),t=Math.sqrt(Math.pow(r,2)+Math.pow(m,2)),u=(s+t)/2,v=t-s,w=c(j,q),x=c(m,r),y=b({C1:n,C2:o,h1_d:w,h2_d:x}),z=2*Math.sqrt(s*t)*Math.sin(e(y)/2),A=d({C1:n,C2:o,h1_d:w,h2_d:x}),B=(h+k)/2,C=1-.17*Math.cos(e(A-30))+.24*Math.cos(e(2*A))+.32*Math.cos(e(3*A+6))-.2*Math.cos(e(4*A-63)),D=.045*u+1,E=1+.015*u*C,F=-2*a(u)*Math.sin(e(2*(30*Math.exp(-Math.pow((A-275)/25,2)))));return Math.sqrt(Math.pow((k-h)/(1*(1+.015*Math.pow(B-50,2)/Math.sqrt(20+Math.pow(B-50,2)))),2)+Math.pow(v/(1*D),2)+Math.pow(z/(1*E),2)+F*(v/(1*D))*(z/(1*E)))}
2
+ //# sourceMappingURL=CIEDE2000.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/CIEDE2000.ts"],"sourcesContent":["import { bigSquare, deltaHue_d, hue_d, meanHue_d, toRadians } from \"./util/index.js\";\nimport type { LabColour } from \"./converters\";\n\n/**\n * Mesures the colour difference between two colours in the Lab space\n *\n * Math taken from:\n *\n * https://en.wikipedia.org/wiki/Color_difference#CIEDE2000\n * http://www2.ece.rochester.edu/~gsharma/ciede2000/ciede2000noteCRNA.pdf\n * @param colour1 First colour to be compared\n * @param colour2 First colour to be compared\n */\nexport function ciede2000(colour1: LabColour, colour2: LabColour): number {\n /**\n * Glossary\n * L - Lightness as defined by L*a*b*\n * a - Describes the green–red opponent colors as defined by L*a*b*\n * b - Describes the blue–yellow opponent colors as defined by L*a*b*\n * C - Chroma as defined by CIE94\n *\n * Math notation\n * _d - Derivative\n * Δ - Difference between values\n * ̅ - Mean value\n */\n\n /** Lightness for colour 1 */\n const L1 = colour1.L;\n\n /** green–red colour opponent for colour 1 */\n const a1 = colour1.a;\n\n /** blue–yellow colour opponent for colour 1 */\n const b1 = colour1.b;\n\n /** Lightness for colour 2 */\n const L2 = colour2.L;\n\n /** green–red colour opponent for colour 1 */\n const a2 = colour2.a;\n\n /** blue–yellow colour opponent for colour 1 */\n const b2 = colour2.b;\n\n /** Weighting factor for Luminance */\n const kL = 1;\n\n /** Weighting factor for Chroma */\n const kC = 1;\n\n /** Weighting factor for Hue */\n const kH = 1;\n\n /** Chroma for colour 1 */\n const C1 = Math.sqrt(Math.pow(a1, 2) + Math.pow(b1, 2));\n\n /** Chroma for colour 2 */\n const C2 = Math.sqrt(Math.pow(a2, 2) + Math.pow(b2, 2));\n\n /** Derivative of the Lightness difference */\n const ΔL_d = L2 - L1;\n\n /** Chroma mean value */\n const C̅ = (C1 + C2) / 2;\n\n const G = 0.5 * (1 - bigSquare(C̅));\n\n /** Derivative of a1 */\n const a1_d = a1 * (1 + G);\n\n /** Derivative of a2 */\n const a2_d = a2 * (1 + G);\n\n /** Derivative of C1 */\n const C1_d = Math.sqrt(Math.pow(a1_d, 2) + Math.pow(b1, 2));\n\n /** Derivative of C2 */\n const C2_d = Math.sqrt(Math.pow(a2_d, 2) + Math.pow(b2, 2));\n\n /** Derivative of Chroma mean */\n const C̅_d = (C1_d + C2_d) / 2;\n\n /** Derivative of the mean difference of Chroma */\n const ΔC̅_d = C2_d - C1_d;\n\n /** Derivative of colour 1 Hue */\n const h1_d = hue_d(b1, a1_d);\n\n /** Derivative of colour 2 Hue */\n const h2_d = hue_d(b2, a2_d);\n\n /** Hue difference */\n const Δh_d = deltaHue_d({ C1, C2, h1_d, h2_d });\n\n const ΔH_d = 2 * Math.sqrt(C1_d * C2_d) * Math.sin(toRadians(Δh_d) / 2);\n\n /** Derivative of mean hue */\n const H̅_d = meanHue_d({ C1, C2, h1_d, h2_d });\n\n /** Lightness Mean value*/\n const L̅ = (L1 + L2) / 2;\n\n /** Compensation for neutral colors (the primed values in the L*C*h differences) */\n const T =\n 1 -\n 0.17 * Math.cos(toRadians(H̅_d - 30)) +\n 0.24 * Math.cos(toRadians(2 * H̅_d)) +\n 0.32 * Math.cos(toRadians(3 * H̅_d + 6)) -\n 0.2 * Math.cos(toRadians(4 * H̅_d - 63));\n\n /** Compensation for lightness */\n const SL =\n 1 + (0.015 * Math.pow(L̅ - 50, 2)) / Math.sqrt(20 + Math.pow(L̅ - 50, 2));\n\n /** Compensation for chroma */\n const SC = 0.045 * C̅_d + 1;\n\n /** Compensation for hue */\n const SH = 1 + 0.015 * C̅_d * T;\n\n const rotation = 30 * Math.exp(-Math.pow((H̅_d - 275) / 25, 2));\n\n /** A hue rotation term, to deal with the problematic blue region (hue angles in the neighborhood of 275°) */\n const RT = -2 * bigSquare(C̅_d) * Math.sin(toRadians(rotation * 2));\n\n /** Colour difference */\n const ΔE = Math.sqrt(\n Math.pow(ΔL_d / (kL * SL), 2) +\n Math.pow(ΔC̅_d / (kC * SC), 2) +\n Math.pow(ΔH_d / (kH * SH), 2) +\n RT * (ΔC̅_d / (kC * SC)) * (ΔH_d / (kH * SH))\n );\n\n return ΔE;\n}\n"],"names":["bigSquare","deltaHue_d","hue_d","meanHue_d","toRadians","ciede2000","colour1","colour2","L1","L","a1","a","b1","b","L2","a2","b2","C1","Math","sqrt","pow","C2","G","a1_d","a2_d","C1_d","C2_d","C̅_d","ΔC̅_d","h1_d","h2_d","Δh_d","ΔH_d","sin","H̅_d","L̅","T","cos","SC","SH","RT","exp"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{ciede2000 as a}from"./CIEDE2000.js";import{convertRGBtoLab as b}from"./converters.js";export const RGBdistance=(c,d)=>{const e=b(c),f=b(d);return a(e,f)}
2
+ //# sourceMappingURL=RGBdistance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/RGBdistance.ts"],"sourcesContent":["import { ciede2000 } from \"./CIEDE2000.js\";\nimport { convertRGBtoLab } from \"./converters.js\";\nimport type { RGBColour } from \"./converters.js\";\n\nexport const RGBdistance = (colour1: RGBColour, colour2: RGBColour): number => {\n const c1 = convertRGBtoLab(colour1);\n const c2 = convertRGBtoLab(colour2);\n\n return ciede2000(c1, c2);\n};\n"],"names":["ciede2000","convertRGBtoLab","RGBdistance","colour1","colour2","c1","c2"],"mappings":"AAAA,MAAM,CAAGA,SAAS,IAATA,CAAS,KAAQ,CAAgB,gBAC1C,MAAM,CAAGC,eAAe,IAAfA,CAAe,KAAQ,CAAiB,iBAGjD,MAAM,CAAC,KAAK,CAACC,WAAW,EAAIC,CAAkB,CAAEC,CAAkB,GAAa,CAAC,AAC9E,KAAK,CAACC,CAAE,CAAGJ,CAAe,CAACE,CAAO,EAC5BG,CAAE,CAAGL,CAAe,CAACG,CAAO,EAElC,MAAM,CAACJ,CAAS,CAACK,CAAE,CAAEC,CAAE,CACzB,CAAC"}
@@ -0,0 +1,137 @@
1
+ declare module "util/index" {
2
+ export interface HueHelper {
3
+ /** Chroma for colour 1 */
4
+ C1: number;
5
+ /** Chroma for colour 2 */
6
+ C2: number;
7
+ /** Derivative of colour 1 Hue */
8
+ h1_d: number;
9
+ /** Derivative of colour 2 Hue */
10
+ h2_d: number;
11
+ }
12
+ /**
13
+ * Calculates the Hue derivative
14
+ * @param x A numeric expression representing the cartesian x-coordinate.
15
+ * @param y A numeric expression representing the cartesian y-coordinate.
16
+ */
17
+ export function hue_d(x: number, y: number): number;
18
+ /**
19
+ * Calculates the difference between two Hue derivatives
20
+ * @param HueHelper param
21
+ */
22
+ export function deltaHue_d({ C1, C2, h1_d, h2_d }: HueHelper): number;
23
+ /**
24
+ * Calculates the mean between two Hue derivatives
25
+ * @param HueHelper param
26
+ */
27
+ export function meanHue_d({ C1, C2, h1_d, h2_d }: HueHelper): number;
28
+ /**
29
+ * Converts a number in degrees to radians
30
+ * @param n Number in degrees to be converted
31
+ */
32
+ export const toRadians: (n: number) => number;
33
+ /**
34
+ * Calculates a recurring square root
35
+ * @param n Input number
36
+ */
37
+ export const bigSquare: (n: number) => number;
38
+ /**
39
+ * Normalise black and white colorimetry as specified in IEC 61966-2-1
40
+ * @param n number to be normalised
41
+ */
42
+ export function reverseTransformation(n: number): number;
43
+ /**
44
+ * The division of the f function domain into two parts was done to prevent an infinite slope at n = 0
45
+ * @param n Number to be constrained
46
+ */
47
+ export function constrainLab(n: number): number;
48
+ }
49
+ declare module "converters" {
50
+ /**
51
+ * The RGB colour model represents a broad array of colours by describing the Red, Green and Blue channels.
52
+ */
53
+ export interface RGBColour {
54
+ /** A number between 0 and 255 to describe the Red colour channel */
55
+ R: number;
56
+ /** A number between 0 and 255 to describe the Green colour channel */
57
+ G: number;
58
+ /** A number between 0 and 255 to describe the Blue colour channel */
59
+ B: number;
60
+ /** A optional number between 0 and 1 to describe the Alpha colour channel */
61
+ A?: number;
62
+ }
63
+ /**
64
+ * L*a*b* space is three-dimensional and covers the entire range of human colour perception
65
+ */
66
+ export interface LabColour {
67
+ /** A number between 0 and 100 to describe the colour's lightness. (0 - black, 100 - white) */
68
+ L: number;
69
+ /** A number between -128 and 127 to describe the green–red opponent colors, with negative values toward green and positive values toward red */
70
+ a: number;
71
+ /** A number between -128 and 127 to describe blue–yellow opponents, with negative numbers toward blue and positive toward yellow */
72
+ b: number;
73
+ }
74
+ /**
75
+ * The CIE XYZ colour space is a device independent colour representation
76
+ */
77
+ export interface XYZColour {
78
+ /** X is a mix of response curves chosen to be nonnegative */
79
+ X: number;
80
+ /** Y as luminance */
81
+ Y: number;
82
+ /** Z is quasi-equal to blue */
83
+ Z: number;
84
+ }
85
+ /**
86
+ * Converts sRGB colour space to XYZ.
87
+ * Math comes from https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation
88
+ * @param {RGBColour} colour sRGB colour
89
+ * @return {XYZColour} XYZ colour
90
+ */
91
+ export function convertRGBtoXYZ(colour: RGBColour): XYZColour;
92
+ /**
93
+ * Converts XYZ colour space to Lab
94
+ * Math comes from https://en.wikipedia.org/wiki/CIELAB_color_space#From_CIEXYZ_to_CIELAB[11]
95
+ * @param colour XYZ colour
96
+ * @return {LabColour} Lab colour
97
+ */
98
+ export function convertXYZtoLab(colour: XYZColour): LabColour;
99
+ /**
100
+ * Indirectly converts RGB to Lab.
101
+ * First converts RGB to XYZ,
102
+ * Then converts XYZ to Lab
103
+ * @param {RGBColour} colour sRGB colour
104
+ * @return {LabColour} Lab colour
105
+ */
106
+ export function convertRGBtoLab(colour: RGBColour): LabColour;
107
+ }
108
+ declare module "CIEDE2000" {
109
+ import type { LabColour } from "converters";
110
+ /**
111
+ * Mesures the colour difference between two colours in the Lab space
112
+ *
113
+ * Math taken from:
114
+ *
115
+ * https://en.wikipedia.org/wiki/Color_difference#CIEDE2000
116
+ * http://www2.ece.rochester.edu/~gsharma/ciede2000/ciede2000noteCRNA.pdf
117
+ * @param colour1 First colour to be compared
118
+ * @param colour2 First colour to be compared
119
+ */
120
+ export function ciede2000(colour1: LabColour, colour2: LabColour): number;
121
+ }
122
+ declare module "RGBdistance" {
123
+ import type { RGBColour } from "converters";
124
+ export const RGBdistance: (colour1: RGBColour, colour2: RGBColour) => number;
125
+ }
126
+ declare module "findNearestColours" {
127
+ import type { RGBColour } from "converters";
128
+ export function findNearestColours(colours: RGBColour[], palette: RGBColour[]): RGBColour[];
129
+ }
130
+ declare module "index" {
131
+ export { ciede2000 } from "CIEDE2000";
132
+ export { convertRGBtoXYZ, convertRGBtoLab, convertXYZtoLab, } from "converters";
133
+ export { RGBdistance } from "RGBdistance";
134
+ }
135
+ declare module "tests/CIEDE2000.test" { }
136
+ declare module "tests/converters.test" { }
137
+ declare module "tests/util.test" { }
@@ -0,0 +1,2 @@
1
+ import{constrainLab as a,reverseTransformation as b}from"./util/index.js";export function convertRGBtoXYZ(a){const{R:c,G:d,B:e}=a,f=100*b(c/255),g=100*b(d/255),h=100*b(e/255);return{X:.4124*f+.3576*g+.1805*h,Y:.2126*f+.7152*g+.0722*h,Z:.0193*f+.1192*g+.9505*h}}export function convertXYZtoLab(b){const{X:c,Y:d,Z:e}=b,f=a(c/95.047),g=a(d/100),h=a(e/108.883);return{L:116*g-16,a:500*(f-g),b:200*(g-h)}}export function convertRGBtoLab(a){const b=convertRGBtoXYZ(a);return convertXYZtoLab(b)}
2
+ //# sourceMappingURL=converters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/converters.ts"],"sourcesContent":["import { constrainLab, reverseTransformation } from \"./util/index.js\";\n\n/**\n * The RGB colour model represents a broad array of colours by describing the Red, Green and Blue channels.\n */\n export interface RGBColour {\n /** A number between 0 and 255 to describe the Red colour channel */\n R: number;\n /** A number between 0 and 255 to describe the Green colour channel */\n G: number;\n /** A number between 0 and 255 to describe the Blue colour channel */\n B: number;\n /** A optional number between 0 and 1 to describe the Alpha colour channel */\n A?: number;\n}\n\n/**\n * L*a*b* space is three-dimensional and covers the entire range of human colour perception\n */\nexport interface LabColour {\n /** A number between 0 and 100 to describe the colour's lightness. (0 - black, 100 - white) */\n L: number;\n /** A number between -128 and 127 to describe the green–red opponent colors, with negative values toward green and positive values toward red */\n a: number;\n /** A number between -128 and 127 to describe blue–yellow opponents, with negative numbers toward blue and positive toward yellow */\n b: number;\n}\n\n/**\n * The CIE XYZ colour space is a device independent colour representation\n */\nexport interface XYZColour {\n /** X is a mix of response curves chosen to be nonnegative */\n X: number;\n /** Y as luminance */\n Y: number;\n /** Z is quasi-equal to blue */\n Z: number;\n}\n\n/**\n * Converts sRGB colour space to XYZ.\n * Math comes from https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation\n * @param {RGBColour} colour sRGB colour\n * @return {XYZColour} XYZ colour\n */\nexport function convertRGBtoXYZ(colour: RGBColour): XYZColour {\n const { R, G, B } = colour;\n\n //sRGB values in the range 0 to 1\n const rR: number = R / 255;\n const rG: number = G / 255;\n const rB: number = B / 255;\n\n const _R = reverseTransformation(rR) * 100;\n const _G = reverseTransformation(rG) * 100;\n const _B = reverseTransformation(rB) * 100;\n\n // Magic numbers are pre-calculated sRGB D65 constants\n const X = _R * 0.4124 + _G * 0.3576 + _B * 0.1805;\n const Y = _R * 0.2126 + _G * 0.7152 + _B * 0.0722;\n const Z = _R * 0.0193 + _G * 0.1192 + _B * 0.9505;\n\n return { X, Y, Z };\n}\n\n/**\n * Converts XYZ colour space to Lab\n * Math comes from https://en.wikipedia.org/wiki/CIELAB_color_space#From_CIEXYZ_to_CIELAB[11]\n * @param colour XYZ colour\n * @return {LabColour} Lab colour\n */\nexport function convertXYZtoLab(colour: XYZColour): LabColour {\n const { X, Y, Z } = colour;\n\n // Magic numbers are normalised for relative luminance from the D65 standard\n const _X = X / 95.047;\n const _Y = Y / 100;\n const _Z = Z / 108.883;\n\n const fX = constrainLab(_X);\n const fY = constrainLab(_Y);\n const fZ = constrainLab(_Z);\n\n const L = 116 * fY - 16;\n const a = 500 * (fX - fY);\n const b = 200 * (fY - fZ);\n\n return { L, a, b };\n}\n\n/**\n * Indirectly converts RGB to Lab.\n * First converts RGB to XYZ,\n * Then converts XYZ to Lab\n * @param {RGBColour} colour sRGB colour\n * @return {LabColour} Lab colour\n */\nexport function convertRGBtoLab(colour: RGBColour): LabColour {\n const XYZColour = convertRGBtoXYZ(colour);\n return convertXYZtoLab(XYZColour);\n}\n"],"names":["constrainLab","reverseTransformation","convertRGBtoXYZ","colour","R","G","B","_R","_G","_B","X","Y","Z","convertXYZtoLab","fX","fY","fZ","L","a","b","convertRGBtoLab","XYZColour"],"mappings":"AAAA,MAAM,CAAGA,YAAY,IAAZA,CAAY,CAAEC,qBAAqB,IAArBA,CAAqB,KAAQ,CAAiB,iBA8CrE,MAAM,UAAUC,eAAe,CAACC,CAAiB,CAAa,CAAC,AAC7D,KAAK,AAAC,CAAC,AAACC,CAAC,CAADA,CAAC,CAAEC,CAAC,CAADA,CAAC,CAAEC,CAAC,CAADA,CAAC,AAAC,CAAC,CAAGH,CAAM,CAOpBI,CAAE,CAA+B,GAAG,CAA/BN,CAAqB,CAJbG,CAAC,CAAG,GAAG,EAKpBI,CAAE,CAA+B,GAAG,CAA/BP,CAAqB,CAJbI,CAAC,CAAG,GAAG,EAKpBI,CAAE,CAA+B,GAAG,CAA/BR,CAAqB,CAJbK,CAAC,CAAG,GAAG,EAW1B,MAAM,AAAC,CAAC,AAACI,CAAC,CAJK,KAAM,CAAXH,CAAE,CAAiB,KAAM,CAAXC,CAAE,CAAiB,KAAM,CAAXC,CAAE,CAI5BE,CAAC,CAHE,KAAM,CAAXJ,CAAE,CAAiB,KAAM,CAAXC,CAAE,CAAiB,KAAM,CAAXC,CAAE,CAGzBG,CAAC,CAFD,KAAM,CAAXL,CAAE,CAAiB,KAAM,CAAXC,CAAE,CAAiB,KAAM,CAAXC,CAAE,AAEvB,CAAC,AACpB,CAAC,AAQD,MAAM,UAAUI,eAAe,CAACV,CAAiB,CAAa,CAAC,AAC7D,KAAK,AAAC,CAAC,AAACO,CAAC,CAADA,CAAC,CAAEC,CAAC,CAADA,CAAC,CAAEC,CAAC,CAADA,CAAC,AAAC,CAAC,CAAGT,CAAM,CAOpBW,CAAE,CAAGd,CAAY,CAJZU,CAAC,CAAG,MAAM,EAKfK,CAAE,CAAGf,CAAY,CAJZW,CAAC,CAAG,GAAG,EAKZK,CAAE,CAAGhB,CAAY,CAJZY,CAAC,CAAG,OAAO,EAUtB,MAAM,AAAC,CAAC,AAACK,CAAC,CAJA,GAAG,CAAGF,CAAE,CAAG,EAAE,CAIXG,CAAC,CAHH,GAAG,EAAIJ,CAAE,CAAGC,CAAE,EAGTI,CAAC,CAFN,GAAG,EAAIJ,CAAE,CAAGC,CAAE,CAEP,CAAC,AACpB,CAAC,AASD,MAAM,UAAUI,eAAe,CAACjB,CAAiB,CAAa,CAAC,AAC7D,KAAK,CAACkB,CAAS,CAAGnB,eAAe,CAACC,CAAM,EACxC,MAAM,CAACU,eAAe,CAACQ,CAAS,CAClC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{RGBdistance as a}from"./RGBdistance.js";export function findNearestColours(b,c){const d=[],e=new WeakMap();for(const f of b)if(e.has(f))d.push(e.get(f));else{const g=[];for(let h=0;h<c.length;h++){const i=c[h],j=a(f,i);g.push(j)}const k=g.findIndex(a=>a===Math.min(...g)),l=c[k];d.push(l),e.set(f,l)}return d}
2
+ //# sourceMappingURL=findNearestColours.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/findNearestColours.ts"],"sourcesContent":["import { RGBdistance } from \"./RGBdistance.js\";\nimport type { RGBColour } from \"./converters\";\n\nexport function findNearestColours(\n colours: RGBColour[],\n palette: RGBColour[]\n): RGBColour[] {\n const setColour: RGBColour[] = [];\n const colourWeakMap = new WeakMap();\n for (const colour of colours) {\n if (colourWeakMap.has(colour)) {\n setColour.push(colourWeakMap.get(colour));\n } else {\n const distanceMap: number[] = [];\n for (let i = 0; i < palette.length; i++) {\n const brickColour = palette[i] as RGBColour;\n const distance = RGBdistance(colour, brickColour);\n distanceMap.push(distance);\n }\n const closestIndex = distanceMap.findIndex(el => el === Math.min(...distanceMap));\n const closest = palette[closestIndex] as RGBColour;\n setColour.push(closest);\n colourWeakMap.set(colour, closest);\n }\n }\n return setColour;\n}\n"],"names":["RGBdistance","findNearestColours","colours","palette","setColour","colourWeakMap","WeakMap","colour","has","push","get","distanceMap","i","length","brickColour","distance","closestIndex","findIndex","el","Math","min","closest","set"],"mappings":"AAAA,MAAM,CAAGA,WAAW,IAAXA,CAAW,KAAQ,CAAkB,kBAG9C,MAAM,UAAUC,kBAAkB,CAChCC,CAAoB,CACpBC,CAAoB,CACP,CAAC,AACd,KAAK,CAACC,CAAS,CAAgB,CAAC,CAAC,CAC3BC,CAAa,CAAG,GAAG,CAACC,OAAO,GACjC,GAAG,CAAE,KAAK,CAACC,CAAM,IAAIL,CAAO,CAC1B,EAAE,CAAEG,CAAa,CAACG,GAAG,CAACD,CAAM,EAC1BH,CAAS,CAACK,IAAI,CAACJ,CAAa,CAACK,GAAG,CAACH,CAAM,OAClC,CAAC,AACN,KAAK,CAACI,CAAW,CAAc,CAAC,CAAC,CACjC,GAAG,CAAE,GAAG,CAACC,CAAC,CAAG,CAAC,CAAEA,CAAC,CAAGT,CAAO,CAACU,MAAM,CAAED,CAAC,GAAI,CAAC,AACxC,KAAK,CAACE,CAAW,CAAGX,CAAO,CAACS,CAAC,EACvBG,CAAQ,CAAGf,CAAW,CAACO,CAAM,CAAEO,CAAW,EAChDH,CAAW,CAACF,IAAI,CAACM,CAAQ,CAC3B,CAAC,AACD,KAAK,CAACC,CAAY,CAAGL,CAAW,CAACM,SAAS,CAACC,CAAE,EAAIA,CAAE,GAAKC,IAAI,CAACC,GAAG,IAAIT,CAAW,GACzEU,CAAO,CAAGlB,CAAO,CAACa,CAAY,EACpCZ,CAAS,CAACK,IAAI,CAACY,CAAO,EACtBhB,CAAa,CAACiB,GAAG,CAACf,CAAM,CAAEc,CAAO,CACnC,CAAC,AAEH,MAAM,CAACjB,CAAS,AAClB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export{ciede2000}from"./CIEDE2000.js";export{convertRGBtoXYZ,convertRGBtoLab,convertXYZtoLab}from"./converters.js";export{RGBdistance}from"./RGBdistance.js"
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { ciede2000 } from \"./CIEDE2000.js\";\nexport {\n convertRGBtoXYZ,\n convertRGBtoLab,\n convertXYZtoLab,\n} from \"./converters.js\";\nexport { RGBdistance } from \"./RGBdistance.js\";\n"],"names":["ciede2000","convertRGBtoXYZ","convertRGBtoLab","convertXYZtoLab","RGBdistance"],"mappings":"AAAA,MAAM,CAAGA,SAAS,KAAQ,CAAgB,gBAC1C,MAAM,CACJC,eAAe,CACfC,eAAe,CACfC,eAAe,KACV,CAAiB,iBACxB,MAAM,CAAGC,WAAW,KAAQ,CAAkB"}
@@ -0,0 +1,2 @@
1
+ export function hue_d(a,b){if(0===a&&0===b)return 0;const c=Math.atan2(a,b)*(180/Math.PI);return c>=0?c:c+360}export function deltaHue_d({C1:a,C2:b,h1_d:c,h2_d:d}){return a*b==0?0:180>=Math.abs(d-c)?d-c:d-c>180?d-c-360:d-c< -180?d-c+360:0}export function meanHue_d({C1:a,C2:b,h1_d:c,h2_d:d}){return a*b==0?d+c:180>=Math.abs(c-d)?(d+c)/2:Math.abs(c-d)>180&&c+d<360?(d+c+360)/2:Math.abs(c-d)>180&&c+d>=360?(d+c-360)/2:0}export const toRadians=a=>a*(Math.PI/180);export const bigSquare=a=>Math.sqrt(Math.pow(a,7)/(Math.pow(a,7)+6103515625));export function reverseTransformation(a){return a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92}export function constrainLab(a){const b=6/29;return a>Math.pow(b,3)?Math.cbrt(a):a/(3*Math.pow(b,2))+4/29}
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/index.ts"],"sourcesContent":["export interface HueHelper {\n /** Chroma for colour 1 */\n C1: number;\n /** Chroma for colour 2 */\n C2: number;\n /** Derivative of colour 1 Hue */\n h1_d: number;\n /** Derivative of colour 2 Hue */\n h2_d: number;\n}\n\n/**\n * Calculates the Hue derivative\n * @param x A numeric expression representing the cartesian x-coordinate.\n * @param y A numeric expression representing the cartesian y-coordinate.\n */\nexport function hue_d(x: number, y: number): number {\n // early exit if both values are 0\n if (x === 0 && y === 0) {\n return 0;\n }\n /** The angle in degrees */\n const angle = Math.atan2(x, y) * (180 / Math.PI);\n if (angle >= 0) {\n return angle;\n }\n return angle + 360;\n}\n\n/**\n * Calculates the difference between two Hue derivatives\n * @param HueHelper param\n */\nexport function deltaHue_d({ C1, C2, h1_d, h2_d }: HueHelper): number {\n if (C1 * C2 === 0) {\n return 0;\n }\n if (Math.abs(h2_d - h1_d) <= 180) {\n return h2_d - h1_d;\n }\n if (h2_d - h1_d > 180) {\n return h2_d - h1_d - 360;\n }\n if (h2_d - h1_d < -180) {\n return h2_d - h1_d + 360;\n }\n // it should never reach this point\n return 0;\n}\n\n/**\n * Calculates the mean between two Hue derivatives\n * @param HueHelper param\n */\nexport function meanHue_d({ C1, C2, h1_d, h2_d }: HueHelper): number {\n if (C1 * C2 === 0) {\n return h2_d + h1_d;\n }\n if (Math.abs(h1_d - h2_d) <= 180) {\n return (h2_d + h1_d) / 2;\n }\n if (Math.abs(h1_d - h2_d) > 180 && h1_d + h2_d < 360) {\n return (h2_d + h1_d + 360) / 2;\n }\n if (Math.abs(h1_d - h2_d) > 180 && h1_d + h2_d >= 360) {\n return (h2_d + h1_d - 360) / 2;\n }\n // it should never reach this point\n return 0;\n}\n\n/**\n * Converts a number in degrees to radians\n * @param n Number in degrees to be converted\n */\nexport const toRadians = (n: number): number => n * (Math.PI / 180);\n\n/**\n * Calculates a recurring square root\n * @param n Input number\n */\nexport const bigSquare = (n: number): number =>\n Math.sqrt(Math.pow(n, 7) / (Math.pow(n, 7) + Math.pow(25, 7)));\n\n/**\n * Normalise black and white colorimetry as specified in IEC 61966-2-1\n * @param n number to be normalised\n */\nexport function reverseTransformation(n: number) {\n let u: number;\n\n if (n > 0.04045) {\n u = Math.pow((n + 0.055) / 1.055, 2.4);\n } else {\n u = n / 12.92;\n }\n\n return u;\n}\n\n/**\n * The division of the f function domain into two parts was done to prevent an infinite slope at n = 0\n * @param n Number to be constrained\n */\nexport function constrainLab(n: number): number {\n const delta = 6 / 29;\n const deltaCube = Math.pow(delta, 3);\n let t: number;\n\n if (n > deltaCube) {\n t = Math.cbrt(n);\n } else {\n t = n / (3 * Math.pow(delta, 2)) + 4 / 29;\n }\n\n return t;\n}\n"],"names":["hue_d","x","y","angle","Math","atan2","PI","deltaHue_d","C1","C2","h1_d","h2_d","abs","meanHue_d","toRadians","n","bigSquare","sqrt","pow","reverseTransformation","constrainLab","delta","cbrt"],"mappings":"AAgBA,MAAM,UAAUA,KAAK,CAACC,CAAS,CAAEC,CAAS,CAAU,CAAC,AAEnD,EAAE,CAAQ,CAAC,GAAPD,CAAC,EAAgB,CAAC,GAAPC,CAAC,CACd,MAAM,CAAC,CAAC,CAGV,KAAK,CAACC,CAAK,CAAGC,IAAI,CAACC,KAAK,CAACJ,CAAC,CAAEC,CAAC,GAAK,GAAG,CAAGE,IAAI,CAACE,EAAE,SAC3CH,CAAK,EAAI,CAAC,CACLA,CAAK,CAEPA,CAAK,CAAG,GAAG,AACpB,CAAC,AAMD,MAAM,UAAUI,UAAU,CAAC,CAAC,AAACC,EAAE,CAAFA,CAAE,CAAEC,EAAE,CAAFA,CAAE,CAAEC,IAAI,CAAJA,CAAI,CAAEC,IAAI,CAAJA,CAAI,AAAY,CAAC,CAAU,CAAC,OACjEH,CAAE,CAAGC,CAAE,EAAK,CAAC,CACR,CAAC,CAEmB,GAAG,EAA5BL,IAAI,CAACQ,GAAG,CAACD,CAAI,CAAGD,CAAI,EACfC,CAAI,CAAGD,CAAI,CAEhBC,CAAI,CAAGD,CAAI,CAAG,GAAG,CACZC,CAAI,CAAGD,CAAI,CAAG,GAAG,CAEtBC,CAAI,CAAGD,CAAI,EAAG,IAAI,CACbC,CAAI,CAAGD,CAAI,CAAG,GAAG,CAGnB,CAAC,AACV,CAAC,AAMD,MAAM,UAAUG,SAAS,CAAC,CAAC,AAACL,EAAE,CAAFA,CAAE,CAAEC,EAAE,CAAFA,CAAE,CAAEC,IAAI,CAAJA,CAAI,CAAEC,IAAI,CAAJA,CAAI,AAAY,CAAC,CAAU,CAAC,OAChEH,CAAE,CAAGC,CAAE,EAAK,CAAC,CACRE,CAAI,CAAGD,CAAI,CAES,GAAG,EAA5BN,IAAI,CAACQ,GAAG,CAACF,CAAI,CAAGC,CAAI,GACdA,CAAI,CAAGD,CAAI,EAAI,CAAC,CAEtBN,IAAI,CAACQ,GAAG,CAACF,CAAI,CAAGC,CAAI,EAAI,GAAG,EAAID,CAAI,CAAGC,CAAI,CAAG,GAAG,EAC1CA,CAAI,CAAGD,CAAI,CAAG,GAAG,EAAI,CAAC,CAE5BN,IAAI,CAACQ,GAAG,CAACF,CAAI,CAAGC,CAAI,EAAI,GAAG,EAAID,CAAI,CAAGC,CAAI,EAAI,GAAG,EAC3CA,CAAI,CAAGD,CAAI,CAAG,GAAG,EAAI,CAAC,CAGzB,CAAC,AACV,CAAC,AAMD,MAAM,CAAC,KAAK,CAACI,SAAS,CAAIC,CAAS,EAAaA,CAAC,EAAIX,IAAI,CAACE,EAAE,CAAG,GAAG,EAMlE,MAAM,CAAC,KAAK,CAACU,SAAS,CAAID,CAAS,EACjCX,IAAI,CAACa,IAAI,CAACb,IAAI,CAACc,GAAG,CAACH,CAAC,CAAE,CAAC,GAAKX,IAAI,CAACc,GAAG,CAACH,CAAC,CAAE,CAAC,EAAIX,UAAe,GAM9D,MAAM,UAAUe,qBAAqB,CAACJ,CAAS,CAAE,CAAC,AAShD,MAAM,CANFA,CAAC,CAAG,MAAO,CACTX,IAAI,CAACc,GAAG,EAAEH,CAAC,CAAG,IAAK,EAAI,KAAK,CAAE,GAAG,EAEjCA,CAAC,CAAG,KAAK,AAIjB,CAAC,AAMD,MAAM,UAAUK,YAAY,CAACL,CAAS,CAAU,CAAC,AAC/C,KAAK,CAACM,CAAK,CAAG,CAAC,CAAG,EAAE,CAUpB,MAAM,CANFN,CAAC,CAHaX,IAAI,CAACc,GAAG,CAACG,CAAK,CAAE,CAAC,EAI7BjB,IAAI,CAACkB,IAAI,CAACP,CAAC,EAEXA,CAAC,EAAI,CAAC,CAAGX,IAAI,CAACc,GAAG,CAACG,CAAK,CAAE,CAAC,GAAK,CAAC,CAAG,EAAE,AAI7C,CAAC"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@sardine/colour",
3
+ "version": "1.0.0",
4
+ "description": "It does things to colours",
5
+ "module": "./dist/index.js",
6
+ "type": "module",
7
+ "types": "./dist/colour.d.ts",
8
+ "scripts": {
9
+ "build": "rm -rf ./dist && npx swc ./src -d ./dist",
10
+ "test": "npm run build && c8 ava",
11
+ "types:emit": "npx tsc --declaration --emitDeclarationOnly --outFile ./dist/colour.d.ts",
12
+ "types:check": "npx tsc --noEmit",
13
+ "publish:next": "npm run build && npm run types:emit && npm publish --tag next",
14
+ "publish:latest": "npm run build && npm run types:emit && npm publish"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/sardinedev/colour.git"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "!dist/tests"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "keywords": [
28
+ "color",
29
+ "colour"
30
+ ],
31
+ "author": "Hugo Nogueira",
32
+ "license": "MIT",
33
+ "bugs": {
34
+ "url": "https://github.com/sardinedev/colour/issues"
35
+ },
36
+ "homepage": "https://github.com/sardinedev/colour#readme",
37
+ "engines": {
38
+ "node": ">= 14"
39
+ },
40
+ "devDependencies": {
41
+ "@swc/cli": "^0.1.55",
42
+ "@swc/core": "^1.2.136",
43
+ "ava": "^4.0.1",
44
+ "c8": "^7.11.0",
45
+ "typescript": "^4.5.5"
46
+ }
47
+ }