@xivdyetools/core 1.12.4 → 1.12.5
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/dist/data/locales/de.json +1 -1
- package/dist/data/locales/en.json +1 -1
- package/dist/data/locales/fr.json +1 -1
- package/dist/data/locales/ja.json +1 -1
- package/dist/data/locales/ko.json +1 -1
- package/dist/data/locales/zh.json +1 -1
- package/dist/services/ColorService.d.ts +210 -1
- package/dist/services/ColorService.d.ts.map +1 -1
- package/dist/services/ColorService.js +330 -1
- package/dist/services/ColorService.js.map +1 -1
- package/dist/services/color/ColorConverter.d.ts +223 -1
- package/dist/services/color/ColorConverter.d.ts.map +1 -1
- package/dist/services/color/ColorConverter.js +456 -0
- package/dist/services/color/ColorConverter.js.map +1 -1
- package/dist/services/color/SpectralMixer.d.ts +77 -0
- package/dist/services/color/SpectralMixer.d.ts.map +1 -0
- package/dist/services/color/SpectralMixer.js +133 -0
- package/dist/services/color/SpectralMixer.js.map +1 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spectral Color Mixer
|
|
3
|
+
*
|
|
4
|
+
* Wrapper for spectral.js library that provides Kubelka-Munk theory-based
|
|
5
|
+
* realistic pigment/paint mixing. This produces results that closely match
|
|
6
|
+
* how actual paints and pigments mix in the physical world.
|
|
7
|
+
*
|
|
8
|
+
* Key characteristics:
|
|
9
|
+
* - Based on Kubelka-Munk light absorption/scattering theory
|
|
10
|
+
* - Simulates how pigments interact with light
|
|
11
|
+
* - Blue + Yellow = Green (like real paint!)
|
|
12
|
+
* - Uses spectral reflectance curves (380-750nm)
|
|
13
|
+
*
|
|
14
|
+
* @module services/color/SpectralMixer
|
|
15
|
+
*/
|
|
16
|
+
// @ts-expect-error - spectral.js has no type definitions
|
|
17
|
+
import * as spectral from 'spectral.js';
|
|
18
|
+
import { ColorConverter } from './ColorConverter.js';
|
|
19
|
+
/**
|
|
20
|
+
* Spectral Color Mixer using Kubelka-Munk theory
|
|
21
|
+
*
|
|
22
|
+
* Provides realistic paint/pigment color mixing by simulating
|
|
23
|
+
* how light interacts with pigmented materials.
|
|
24
|
+
*/
|
|
25
|
+
export class SpectralMixer {
|
|
26
|
+
/**
|
|
27
|
+
* Mix two colors using Kubelka-Munk spectral mixing
|
|
28
|
+
*
|
|
29
|
+
* This produces results similar to mixing physical paints:
|
|
30
|
+
* - Blue + Yellow = Green (like mixing paints)
|
|
31
|
+
* - More realistic tinting and shading
|
|
32
|
+
* - Handles complementary colors naturally
|
|
33
|
+
*
|
|
34
|
+
* @param hex1 First hex color
|
|
35
|
+
* @param hex2 Second hex color
|
|
36
|
+
* @param ratio Mix ratio (0 = all hex1, 0.5 = equal mix, 1 = all hex2). Default: 0.5
|
|
37
|
+
* @returns Mixed color as hex
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Mix blue and yellow to get green
|
|
41
|
+
* SpectralMixer.mixColors('#0000FF', '#FFFF00') // Returns green-ish color
|
|
42
|
+
*/
|
|
43
|
+
static mixColors(hex1, hex2, ratio = 0.5) {
|
|
44
|
+
// Clamp ratio to valid range
|
|
45
|
+
ratio = Math.max(0, Math.min(1, ratio));
|
|
46
|
+
// Create spectral Color objects
|
|
47
|
+
const color1 = new spectral.Color(hex1);
|
|
48
|
+
const color2 = new spectral.Color(hex2);
|
|
49
|
+
// Mix using Kubelka-Munk theory
|
|
50
|
+
// The mix function takes [color, concentration] pairs
|
|
51
|
+
// We use (1 - ratio) for color1 and ratio for color2
|
|
52
|
+
const mixed = spectral.mix([color1, 1 - ratio], [color2, ratio]);
|
|
53
|
+
// Convert to hex string
|
|
54
|
+
// toString returns hex format by default with gamut mapping
|
|
55
|
+
const hexResult = mixed.toString({ format: 'hex', method: 'map' });
|
|
56
|
+
// Normalize to our HexColor format
|
|
57
|
+
return ColorConverter.normalizeHex(hexResult);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Mix multiple colors using Kubelka-Munk spectral mixing
|
|
61
|
+
*
|
|
62
|
+
* @param colors Array of hex colors to mix
|
|
63
|
+
* @param weights Optional array of weights (defaults to equal weights)
|
|
64
|
+
* @returns Mixed color as hex
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* // Mix three colors
|
|
68
|
+
* SpectralMixer.mixMultiple(['#FF0000', '#00FF00', '#0000FF'])
|
|
69
|
+
*/
|
|
70
|
+
static mixMultiple(colors, weights) {
|
|
71
|
+
if (colors.length === 0) {
|
|
72
|
+
throw new Error('At least one color is required');
|
|
73
|
+
}
|
|
74
|
+
if (colors.length === 1) {
|
|
75
|
+
return ColorConverter.normalizeHex(colors[0]);
|
|
76
|
+
}
|
|
77
|
+
// Use equal weights if not provided
|
|
78
|
+
const effectiveWeights = weights ?? colors.map(() => 1 / colors.length);
|
|
79
|
+
// Normalize weights to sum to 1
|
|
80
|
+
const totalWeight = effectiveWeights.reduce((sum, w) => sum + w, 0);
|
|
81
|
+
const normalizedWeights = effectiveWeights.map((w) => w / totalWeight);
|
|
82
|
+
// Create spectral Color objects with weights
|
|
83
|
+
const colorPairs = colors.map((hex, i) => [
|
|
84
|
+
new spectral.Color(hex),
|
|
85
|
+
normalizedWeights[i],
|
|
86
|
+
]);
|
|
87
|
+
// Mix using Kubelka-Munk theory
|
|
88
|
+
const mixed = spectral.mix(...colorPairs);
|
|
89
|
+
// Convert to hex string
|
|
90
|
+
const hexResult = mixed.toString({ format: 'hex', method: 'map' });
|
|
91
|
+
return ColorConverter.normalizeHex(hexResult);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Generate a gradient palette using spectral mixing
|
|
95
|
+
*
|
|
96
|
+
* Creates a series of colors that transition smoothly between
|
|
97
|
+
* two colors using Kubelka-Munk theory for realistic blending.
|
|
98
|
+
*
|
|
99
|
+
* @param hex1 Starting color
|
|
100
|
+
* @param hex2 Ending color
|
|
101
|
+
* @param steps Number of colors in the gradient (including start and end)
|
|
102
|
+
* @returns Array of hex colors
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* // Generate a 5-step gradient from red to blue
|
|
106
|
+
* SpectralMixer.gradient('#FF0000', '#0000FF', 5)
|
|
107
|
+
*/
|
|
108
|
+
static gradient(hex1, hex2, steps) {
|
|
109
|
+
if (steps < 2) {
|
|
110
|
+
throw new Error('Gradient requires at least 2 steps');
|
|
111
|
+
}
|
|
112
|
+
const result = [];
|
|
113
|
+
for (let i = 0; i < steps; i++) {
|
|
114
|
+
const ratio = i / (steps - 1);
|
|
115
|
+
result.push(this.mixColors(hex1, hex2, ratio));
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Check if the spectral.js library is available
|
|
121
|
+
*
|
|
122
|
+
* @returns true if spectral.js is loaded and functional
|
|
123
|
+
*/
|
|
124
|
+
static isAvailable() {
|
|
125
|
+
try {
|
|
126
|
+
return typeof spectral.Color === 'function' && typeof spectral.mix === 'function';
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=SpectralMixer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpectralMixer.js","sourceRoot":"","sources":["../../../src/services/color/SpectralMixer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,yDAAyD;AACzD,OAAO,KAAK,QAAQ,MAAM,aAAa,CAAC;AAGxC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,OAAO,aAAa;IACxB;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,SAAS,CAAC,IAAY,EAAE,IAAY,EAAE,QAAgB,GAAG;QAC9D,6BAA6B;QAC7B,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;QAExC,gCAAgC;QAChC,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAExC,gCAAgC;QAChC,sDAAsD;QACtD,qDAAqD;QACrD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QAEjE,wBAAwB;QACxB,4DAA4D;QAC5D,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAEnE,mCAAmC;QACnC,OAAO,cAAc,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,CAAC,MAAgB,EAAE,OAAkB;QACrD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,cAAc,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC;QAED,oCAAoC;QACpC,MAAM,gBAAgB,GAAG,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAExE,gCAAgC;QAChC,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACpE,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC;QAEvE,6CAA6C;QAC7C,MAAM,UAAU,GAAsC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3E,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;YACvB,iBAAiB,CAAC,CAAC,CAAC;SACrB,CAAC,CAAC;QAEH,gCAAgC;QAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC;QAE1C,wBAAwB;QACxB,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAEnE,OAAO,cAAc,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAY,EAAE,IAAY,EAAE,KAAa;QACvD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,MAAM,GAAe,EAAE,CAAC;QAE9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC;YACH,OAAO,OAAO,QAAQ,CAAC,KAAK,KAAK,UAAU,IAAI,OAAO,QAAQ,CAAC,GAAG,KAAK,UAAU,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export { NoOpLogger, ConsoleLogger } from '@xivdyetools/logger/library';
|
|
|
20
20
|
/**
|
|
21
21
|
* @deprecated Removed in v2.0.0. Import directly from '@xivdyetools/types' instead.
|
|
22
22
|
*/
|
|
23
|
-
export type { RGB, HSV, LAB, HexColor, DyeId, Hue, Saturation } from '@xivdyetools/types';
|
|
23
|
+
export type { RGB, HSV, LAB, OKLAB, OKLCH, LCH, HSL, HexColor, DyeId, Hue, Saturation } from '@xivdyetools/types';
|
|
24
24
|
/**
|
|
25
25
|
* @deprecated Removed in v2.0.0. Import directly from '@xivdyetools/types' instead.
|
|
26
26
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;GAEG;AACH,YAAY,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC1D;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAMxE;;GAEG;AACH,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;GAEG;AACH,YAAY,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC1D;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAMxE;;GAEG;AACH,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAClH;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC9F;;GAEG;AACH,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEpF;;GAEG;AACH,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE1F;;GAEG;AACH,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,OAAO,EACP,MAAM,EACN,IAAI,GACL,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3F;;GAEG;AACH,YAAY,EACV,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,6BAA6B,EAC7B,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,YAAY,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,4BAA4B,EAC5B,qBAAqB,EACrB,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,YAAY,EACV,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,SAAS,EACT,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,YAAY,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,MAAM,EACN,eAAe,EACf,OAAO,EACP,OAAO,EACP,UAAU,EACV,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACzD;;GAEG;AACH,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;GAEG;AACH,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAClF;;GAEG;AACH,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xivdyetools/core",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.5",
|
|
4
4
|
"description": "Core color algorithms and dye database for XIV Dye Tools",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -77,7 +77,8 @@
|
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@xivdyetools/logger": "^1.0.2",
|
|
80
|
-
"@xivdyetools/types": "^1.6.1"
|
|
80
|
+
"@xivdyetools/types": "^1.6.1",
|
|
81
|
+
"spectral.js": "^3.0.0"
|
|
81
82
|
},
|
|
82
83
|
"lint-staged": {
|
|
83
84
|
"*.ts": [
|
|
@@ -85,4 +86,4 @@
|
|
|
85
86
|
"prettier --write"
|
|
86
87
|
]
|
|
87
88
|
}
|
|
88
|
-
}
|
|
89
|
+
}
|