@xivdyetools/core 4.2.0 → 5.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.
Files changed (57) hide show
  1. package/README.md +1 -1
  2. package/dist/blending/blending.d.ts +26 -6
  3. package/dist/blending/blending.d.ts.map +1 -1
  4. package/dist/blending/blending.js +79 -32
  5. package/dist/blending/blending.js.map +1 -1
  6. package/dist/blending/conversions.d.ts +0 -12
  7. package/dist/blending/conversions.d.ts.map +1 -1
  8. package/dist/blending/conversions.js +25 -28
  9. package/dist/blending/conversions.js.map +1 -1
  10. package/dist/blending/index.d.ts +4 -1
  11. package/dist/blending/index.d.ts.map +1 -1
  12. package/dist/blending/index.js.map +1 -1
  13. package/dist/blending/types.d.ts +38 -0
  14. package/dist/blending/types.d.ts.map +1 -1
  15. package/dist/config/band-vocabulary.d.ts +9 -0
  16. package/dist/config/band-vocabulary.d.ts.map +1 -1
  17. package/dist/config/band-vocabulary.js +12 -3
  18. package/dist/config/band-vocabulary.js.map +1 -1
  19. package/dist/data/locales/de.json +16 -3
  20. package/dist/data/locales/en.json +15 -2
  21. package/dist/data/locales/fr.json +15 -2
  22. package/dist/data/locales/ja.json +17 -4
  23. package/dist/data/locales/ko.json +15 -2
  24. package/dist/data/locales/zh.json +15 -2
  25. package/dist/services/ColorService.d.ts +37 -15
  26. package/dist/services/ColorService.d.ts.map +1 -1
  27. package/dist/services/ColorService.js +70 -69
  28. package/dist/services/ColorService.js.map +1 -1
  29. package/dist/services/LocalizationService.d.ts +17 -1
  30. package/dist/services/LocalizationService.d.ts.map +1 -1
  31. package/dist/services/LocalizationService.js +21 -1
  32. package/dist/services/LocalizationService.js.map +1 -1
  33. package/dist/services/color/ColorConverter.d.ts +28 -35
  34. package/dist/services/color/ColorConverter.d.ts.map +1 -1
  35. package/dist/services/color/ColorConverter.js +70 -63
  36. package/dist/services/color/ColorConverter.js.map +1 -1
  37. package/dist/services/dye/HarmonyGenerator.d.ts +2 -2
  38. package/dist/services/dye/HarmonyGenerator.d.ts.map +1 -1
  39. package/dist/services/dye/HarmonyGenerator.js +28 -4
  40. package/dist/services/dye/HarmonyGenerator.js.map +1 -1
  41. package/dist/services/localization/TranslationProvider.d.ts +10 -0
  42. package/dist/services/localization/TranslationProvider.d.ts.map +1 -1
  43. package/dist/services/localization/TranslationProvider.js +26 -0
  44. package/dist/services/localization/TranslationProvider.js.map +1 -1
  45. package/dist/types/index.d.ts +3 -2
  46. package/dist/types/index.d.ts.map +1 -1
  47. package/dist/types/index.js +2 -2
  48. package/dist/types/index.js.map +1 -1
  49. package/package.json +3 -3
  50. package/dist/services/color/RybColorMixer.d.ts +0 -102
  51. package/dist/services/color/RybColorMixer.d.ts.map +0 -1
  52. package/dist/services/color/RybColorMixer.js +0 -362
  53. package/dist/services/color/RybColorMixer.js.map +0 -1
  54. package/dist/services/color/SpectralMixer.d.ts +0 -43
  55. package/dist/services/color/SpectralMixer.d.ts.map +0 -1
  56. package/dist/services/color/SpectralMixer.js +0 -59
  57. package/dist/services/color/SpectralMixer.js.map +0 -1
@@ -1,102 +0,0 @@
1
- /**
2
- * RYB (Red-Yellow-Blue) Subtractive Color Mixing
3
- *
4
- * Implements the Gossett-Chen algorithm from their 2006 paper
5
- * "Paint Inspired Color Mixing and Compositing for Visualization"
6
- *
7
- * Uses trilinear interpolation in a 3D color cube to convert between
8
- * RYB and RGB color spaces, enabling intuitive "paint-like" color mixing.
9
- *
10
- * Key insight: In RYB (subtractive mixing):
11
- * - Red + Yellow = Orange
12
- * - Yellow + Blue = Green
13
- * - Red + Blue = Violet
14
- *
15
- * This differs from RGB (additive mixing) where Blue + Yellow = Gray.
16
- *
17
- * @module services/color/RybColorMixer
18
- */
19
- import type { RGB, HexColor } from '@xivdyetools/types';
20
- /**
21
- * RYB color type (Red, Yellow, Blue) with values 0-255
22
- */
23
- export interface RYB {
24
- r: number;
25
- y: number;
26
- b: number;
27
- }
28
- /**
29
- * RYB Color Mixer
30
- *
31
- * Provides methods for RYB ↔ RGB conversion and paint-like color mixing.
32
- */
33
- export declare class RybColorMixer {
34
- /**
35
- * Mix two colors using RYB subtractive color mixing
36
- *
37
- * This produces results similar to mixing physical paints:
38
- * - Blue + Yellow = Green (not gray like in RGB)
39
- * - Red + Yellow = Orange
40
- * - Red + Blue = Violet
41
- *
42
- * @param hex1 First hex color
43
- * @param hex2 Second hex color
44
- * @param ratio Mix ratio (0 = all hex1, 0.5 = equal mix, 1 = all hex2). Default: 0.5
45
- * @returns Mixed color as hex
46
- *
47
- * @example
48
- * // Mix blue and yellow to get green
49
- * RybColorMixer.mixColors('#0000FF', '#FFFF00') // Returns greenish color
50
- */
51
- static mixColors(hex1: string, hex2: string, ratio?: number): HexColor;
52
- /**
53
- * Convert RYB to RGB using trilinear interpolation
54
- *
55
- * Uses the Gossett-Chen cube corner values to interpolate
56
- * any point within the RYB color space to its RGB equivalent.
57
- *
58
- * @param r Red component (0-255)
59
- * @param y Yellow component (0-255)
60
- * @param b Blue component (0-255)
61
- * @returns RGB color
62
- *
63
- * @example
64
- * // Convert RYB yellow+blue (green) to RGB
65
- * RybColorMixer.rybToRgb(0, 255, 255) // Returns { r: 0, g: 255, b: 89 }
66
- */
67
- static rybToRgb(r: number, y: number, b: number): RGB;
68
- /**
69
- * Convert RGB to RYB using Multi-Start Newton-Raphson
70
- *
71
- * Since RYB→RGB is non-linear and the cube can be complex,
72
- * we use multiple starting points to find the best global solution
73
- * (minimizing RGB error).
74
- *
75
- * @param r Red component (0-255)
76
- * @param g Green component (0-255)
77
- * @param b Blue component (0-255)
78
- * @returns RYB color
79
- *
80
- * @example
81
- * // Convert RGB green to RYB
82
- * RybColorMixer.rgbToRyb(0, 255, 0) // Returns approximately { r: 0, y: ~255, b: ~255 }
83
- */
84
- static rgbToRyb(r: number, g: number, b: number): RYB;
85
- /**
86
- * Convert hex color to RYB
87
- *
88
- * @param hex Hex color string
89
- * @returns RYB color
90
- */
91
- static hexToRyb(hex: string): RYB;
92
- /**
93
- * Convert RYB to hex color
94
- *
95
- * @param r Red component (0-255)
96
- * @param y Yellow component (0-255)
97
- * @param b Blue component (0-255)
98
- * @returns Hex color string
99
- */
100
- static rybToHex(r: number, y: number, b: number): HexColor;
101
- }
102
- //# sourceMappingURL=RybColorMixer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RybColorMixer.d.ts","sourceRoot":"","sources":["../../../src/services/color/RybColorMixer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAIxD;;GAEG;AACH,MAAM,WAAW,GAAG;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AA4CD;;;;GAIG;AACH,qBAAa,aAAa;IAKxB;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAY,GAAG,QAAQ;IAsB3E;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG;IAerD;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG;IAqLrD;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG;IAKjC;;;;;;;OAOG;IACH,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ;CA8D3D"}
@@ -1,362 +0,0 @@
1
- /**
2
- * RYB (Red-Yellow-Blue) Subtractive Color Mixing
3
- *
4
- * Implements the Gossett-Chen algorithm from their 2006 paper
5
- * "Paint Inspired Color Mixing and Compositing for Visualization"
6
- *
7
- * Uses trilinear interpolation in a 3D color cube to convert between
8
- * RYB and RGB color spaces, enabling intuitive "paint-like" color mixing.
9
- *
10
- * Key insight: In RYB (subtractive mixing):
11
- * - Red + Yellow = Orange
12
- * - Yellow + Blue = Green
13
- * - Red + Blue = Violet
14
- *
15
- * This differs from RGB (additive mixing) where Blue + Yellow = Gray.
16
- *
17
- * @module services/color/RybColorMixer
18
- */
19
- import { clamp } from '../../utils/index.js';
20
- import { ColorConverter } from './ColorConverter.js';
21
- /**
22
- * RYB Cube Corner Values (Gossett-Chen)
23
- *
24
- * These define the 8 corners of the RYB color cube and their
25
- * corresponding RGB values. The cube is indexed by [R,Y,B] coordinates.
26
- *
27
- * The blue corner is adjusted (r=0.165) to shift the hue and prevent
28
- * "flat spots" in the spectrum. Similarly, green and violet primaries
29
- * are tuned for more intuitive color mixing.
30
- */
31
- /**
32
- * RYB Cube Corner Values (Gossett-Chen - Subtractive/Paint Model)
33
- *
34
- * 0,0,0 is White (Canvas)
35
- * 1,1,1 is Black (Sludge)
36
- *
37
- * This model correctly simulates paint mixing where adding pigments subtracts light.
38
- * The corners are tuned to produce expected secondary colors:
39
- * - Red + Yellow = Orange
40
- * - Yellow + Blue = Green
41
- * - Red + Blue = Violet
42
- */
43
- const RYB_CORNERS = {
44
- '0,0,0': { r: 1.0, g: 1.0, b: 1.0 }, // White
45
- '1,0,0': { r: 1.0, g: 0.0, b: 0.0 }, // Red
46
- '0,1,0': { r: 1.0, g: 1.0, b: 0.0 }, // Yellow
47
- '0,0,1': { r: 0.163, g: 0.373, b: 0.6 }, // Blue
48
- '1,1,0': { r: 1.0, g: 0.5, b: 0.0 }, // Orange
49
- '1,0,1': { r: 0.5, g: 0.0, b: 0.5 }, // Violet
50
- '0,1,1': { r: 0.0, g: 0.66, b: 0.2 }, // Green
51
- '1,1,1': { r: 0.2, g: 0.09, b: 0.0 }, // Black
52
- };
53
- /**
54
- * RYB Color Mixer
55
- *
56
- * Provides methods for RYB ↔ RGB conversion and paint-like color mixing.
57
- */
58
- export class RybColorMixer {
59
- // ============================================================================
60
- // Public API
61
- // ============================================================================
62
- /**
63
- * Mix two colors using RYB subtractive color mixing
64
- *
65
- * This produces results similar to mixing physical paints:
66
- * - Blue + Yellow = Green (not gray like in RGB)
67
- * - Red + Yellow = Orange
68
- * - Red + Blue = Violet
69
- *
70
- * @param hex1 First hex color
71
- * @param hex2 Second hex color
72
- * @param ratio Mix ratio (0 = all hex1, 0.5 = equal mix, 1 = all hex2). Default: 0.5
73
- * @returns Mixed color as hex
74
- *
75
- * @example
76
- * // Mix blue and yellow to get green
77
- * RybColorMixer.mixColors('#0000FF', '#FFFF00') // Returns greenish color
78
- */
79
- static mixColors(hex1, hex2, ratio = 0.5) {
80
- ratio = clamp(ratio, 0, 1);
81
- // Convert hex → RGB → RYB
82
- const rgb1 = ColorConverter.hexToRgb(hex1);
83
- const rgb2 = ColorConverter.hexToRgb(hex2);
84
- const ryb1 = this.rgbToRyb(rgb1.r, rgb1.g, rgb1.b);
85
- const ryb2 = this.rgbToRyb(rgb2.r, rgb2.g, rgb2.b);
86
- // Linear interpolation in RYB space
87
- const mixedRyb = {
88
- r: ryb1.r + (ryb2.r - ryb1.r) * ratio,
89
- y: ryb1.y + (ryb2.y - ryb1.y) * ratio,
90
- b: ryb1.b + (ryb2.b - ryb1.b) * ratio,
91
- };
92
- // Convert RYB → RGB → hex
93
- const mixedRgb = this.rybToRgb(mixedRyb.r, mixedRyb.y, mixedRyb.b);
94
- return ColorConverter.rgbToHex(mixedRgb.r, mixedRgb.g, mixedRgb.b);
95
- }
96
- /**
97
- * Convert RYB to RGB using trilinear interpolation
98
- *
99
- * Uses the Gossett-Chen cube corner values to interpolate
100
- * any point within the RYB color space to its RGB equivalent.
101
- *
102
- * @param r Red component (0-255)
103
- * @param y Yellow component (0-255)
104
- * @param b Blue component (0-255)
105
- * @returns RGB color
106
- *
107
- * @example
108
- * // Convert RYB yellow+blue (green) to RGB
109
- * RybColorMixer.rybToRgb(0, 255, 255) // Returns { r: 0, g: 255, b: 89 }
110
- */
111
- static rybToRgb(r, y, b) {
112
- // Normalize to 0-1 range
113
- const rNorm = clamp(r / 255, 0, 1);
114
- const yNorm = clamp(y / 255, 0, 1);
115
- const bNorm = clamp(b / 255, 0, 1);
116
- const result = this.trilinearInterpolate(rNorm, yNorm, bNorm);
117
- return {
118
- r: Math.round(clamp(result.r * 255, 0, 255)),
119
- g: Math.round(clamp(result.g * 255, 0, 255)),
120
- b: Math.round(clamp(result.b * 255, 0, 255)),
121
- };
122
- }
123
- /**
124
- * Convert RGB to RYB using Multi-Start Newton-Raphson
125
- *
126
- * Since RYB→RGB is non-linear and the cube can be complex,
127
- * we use multiple starting points to find the best global solution
128
- * (minimizing RGB error).
129
- *
130
- * @param r Red component (0-255)
131
- * @param g Green component (0-255)
132
- * @param b Blue component (0-255)
133
- * @returns RYB color
134
- *
135
- * @example
136
- * // Convert RGB green to RYB
137
- * RybColorMixer.rgbToRyb(0, 255, 0) // Returns approximately { r: 0, y: ~255, b: ~255 }
138
- */
139
- static rgbToRyb(r, g, b) {
140
- // Normalize target RGB to 0-1
141
- const targetR = clamp(r / 255, 0, 1);
142
- const targetG = clamp(g / 255, 0, 1);
143
- const targetB = clamp(b / 255, 0, 1);
144
- // Multi-start candidates to avoid local minima
145
- const candidates = [
146
- { r: 0.5, y: 0.5, b: 0.5 }, // Center
147
- { r: 0, y: 0, b: 0 }, // White (Subtractive 000)
148
- { r: 1, y: 1, b: 1 }, // Black (Subtractive 111)
149
- { r: 1, y: 0, b: 0 }, // Red
150
- { r: 0, y: 1, b: 0 }, // Yellow
151
- { r: 0, y: 0, b: 1 }, // Blue
152
- { r: 0, y: 1, b: 1 }, // Green
153
- { r: 1, y: 1, b: 0 }, // Orange
154
- { r: 1, y: 0, b: 1 }, // Purple
155
- ];
156
- let bestRyb = { r: 0, y: 0, b: 0 };
157
- let minError = Infinity;
158
- const maxIterations = 20;
159
- const tolerance = 0.001;
160
- const epsilon = 0.001; // For numerical Jacobian
161
- for (const start of candidates) {
162
- let rybR = start.r;
163
- let rybY = start.y;
164
- let rybB = start.b;
165
- for (let i = 0; i < maxIterations; i++) {
166
- // Convert current RYB guess to RGB
167
- const currentRgb = this.trilinearInterpolate(rybR, rybY, rybB);
168
- // Calculate error
169
- const errorR = targetR - currentRgb.r;
170
- const errorG = targetG - currentRgb.g;
171
- const errorB = targetB - currentRgb.b;
172
- const currentError = Math.sqrt(errorR * errorR + errorG * errorG + errorB * errorB);
173
- // Track best solution found so far
174
- if (currentError < minError) {
175
- minError = currentError;
176
- bestRyb = { r: rybR, y: rybY, b: rybB };
177
- }
178
- if (currentError < tolerance) {
179
- // Good enough match
180
- return {
181
- r: Math.round(rybR * 255),
182
- y: Math.round(rybY * 255),
183
- b: Math.round(rybB * 255),
184
- };
185
- }
186
- // Compute numerical Jacobian and update
187
- const J = this.computeJacobian(rybR, rybY, rybB, epsilon);
188
- const delta = this.solveLinearSystem(J, errorR, errorG, errorB);
189
- // Apply damped update
190
- const damping = 0.5;
191
- rybR = clamp(rybR + delta[0] * damping, 0, 1);
192
- rybY = clamp(rybY + delta[1] * damping, 0, 1);
193
- rybB = clamp(rybB + delta[2] * damping, 0, 1);
194
- }
195
- }
196
- return {
197
- r: Math.round(bestRyb.r * 255),
198
- y: Math.round(bestRyb.y * 255),
199
- b: Math.round(bestRyb.b * 255),
200
- };
201
- }
202
- /**
203
- * Compute the 3×3 Jacobian matrix numerically using finite differences
204
- *
205
- * J[i][j] = ∂RGB[i]/∂RYB[j]
206
- *
207
- * @param r Current RYB red (0-1)
208
- * @param y Current RYB yellow (0-1)
209
- * @param b Current RYB blue (0-1)
210
- * @param epsilon Step size for finite differences
211
- * @returns 3×3 Jacobian matrix as [row][col]
212
- * @internal
213
- */
214
- static computeJacobian(r, y, b, epsilon) {
215
- const J = [
216
- [0, 0, 0],
217
- [0, 0, 0],
218
- [0, 0, 0],
219
- ];
220
- // Perturb RYB Red
221
- const rPlus = this.trilinearInterpolate(Math.min(r + epsilon, 1), y, b);
222
- const rMinus = this.trilinearInterpolate(Math.max(r - epsilon, 0), y, b);
223
- const rDenom = Math.min(r + epsilon, 1) - Math.max(r - epsilon, 0);
224
- if (rDenom > 0) {
225
- J[0][0] = (rPlus.r - rMinus.r) / rDenom;
226
- J[1][0] = (rPlus.g - rMinus.g) / rDenom;
227
- J[2][0] = (rPlus.b - rMinus.b) / rDenom;
228
- }
229
- // Perturb RYB Yellow
230
- const yPlus = this.trilinearInterpolate(r, Math.min(y + epsilon, 1), b);
231
- const yMinus = this.trilinearInterpolate(r, Math.max(y - epsilon, 0), b);
232
- const yDenom = Math.min(y + epsilon, 1) - Math.max(y - epsilon, 0);
233
- if (yDenom > 0) {
234
- J[0][1] = (yPlus.r - yMinus.r) / yDenom;
235
- J[1][1] = (yPlus.g - yMinus.g) / yDenom;
236
- J[2][1] = (yPlus.b - yMinus.b) / yDenom;
237
- }
238
- // Perturb RYB Blue
239
- const bPlus = this.trilinearInterpolate(r, y, Math.min(b + epsilon, 1));
240
- const bMinus = this.trilinearInterpolate(r, y, Math.max(b - epsilon, 0));
241
- const bDenom = Math.min(b + epsilon, 1) - Math.max(b - epsilon, 0);
242
- if (bDenom > 0) {
243
- J[0][2] = (bPlus.r - bMinus.r) / bDenom;
244
- J[1][2] = (bPlus.g - bMinus.g) / bDenom;
245
- J[2][2] = (bPlus.b - bMinus.b) / bDenom;
246
- }
247
- return J;
248
- }
249
- /**
250
- * Solve a 3×3 linear system Ax = b using Cramer's rule
251
- *
252
- * @param A 3×3 matrix
253
- * @param b1 First component of b vector
254
- * @param b2 Second component of b vector
255
- * @param b3 Third component of b vector
256
- * @returns Solution vector [x1, x2, x3]
257
- * @internal
258
- */
259
- static solveLinearSystem(A, b1, b2, b3) {
260
- // Calculate determinant of A
261
- const detA = A[0][0] * (A[1][1] * A[2][2] - A[1][2] * A[2][1]) -
262
- A[0][1] * (A[1][0] * A[2][2] - A[1][2] * A[2][0]) +
263
- A[0][2] * (A[1][0] * A[2][1] - A[1][1] * A[2][0]);
264
- // If matrix is singular, fall back to simple diagonal approximation
265
- if (Math.abs(detA) < 1e-10) {
266
- // Use diagonal elements as fallback
267
- const x1 = A[0][0] !== 0 ? b1 / A[0][0] : 0;
268
- const x2 = A[1][1] !== 0 ? b2 / A[1][1] : 0;
269
- const x3 = A[2][2] !== 0 ? b3 / A[2][2] : 0;
270
- return [x1, x2, x3];
271
- }
272
- // Cramer's rule: replace column i with b, compute det, divide by detA
273
- // x1 = det(A with col 0 replaced by b) / detA
274
- const detA1 = b1 * (A[1][1] * A[2][2] - A[1][2] * A[2][1]) -
275
- A[0][1] * (b2 * A[2][2] - A[1][2] * b3) +
276
- A[0][2] * (b2 * A[2][1] - A[1][1] * b3);
277
- // x2 = det(A with col 1 replaced by b) / detA
278
- const detA2 = A[0][0] * (b2 * A[2][2] - A[1][2] * b3) -
279
- b1 * (A[1][0] * A[2][2] - A[1][2] * A[2][0]) +
280
- A[0][2] * (A[1][0] * b3 - b2 * A[2][0]);
281
- // x3 = det(A with col 2 replaced by b) / detA
282
- const detA3 = A[0][0] * (A[1][1] * b3 - b2 * A[2][1]) -
283
- A[0][1] * (A[1][0] * b3 - b2 * A[2][0]) +
284
- b1 * (A[1][0] * A[2][1] - A[1][1] * A[2][0]);
285
- return [detA1 / detA, detA2 / detA, detA3 / detA];
286
- }
287
- /**
288
- * Convert hex color to RYB
289
- *
290
- * @param hex Hex color string
291
- * @returns RYB color
292
- */
293
- static hexToRyb(hex) {
294
- const rgb = ColorConverter.hexToRgb(hex);
295
- return this.rgbToRyb(rgb.r, rgb.g, rgb.b);
296
- }
297
- /**
298
- * Convert RYB to hex color
299
- *
300
- * @param r Red component (0-255)
301
- * @param y Yellow component (0-255)
302
- * @param b Blue component (0-255)
303
- * @returns Hex color string
304
- */
305
- static rybToHex(r, y, b) {
306
- const rgb = this.rybToRgb(r, y, b);
307
- return ColorConverter.rgbToHex(rgb.r, rgb.g, rgb.b);
308
- }
309
- // ============================================================================
310
- // Private Helpers
311
- // ============================================================================
312
- /**
313
- * Trilinear interpolation within the RYB color cube
314
- *
315
- * Given normalized RYB coordinates (0-1), interpolates between
316
- * the 8 corner RGB values to produce the output RGB color.
317
- *
318
- * @param r Normalized red (0-1)
319
- * @param y Normalized yellow (0-1)
320
- * @param b Normalized blue (0-1)
321
- * @returns Normalized RGB (0-1)
322
- * @internal
323
- */
324
- static trilinearInterpolate(r, y, b) {
325
- // Get the 8 corner values
326
- const c000 = RYB_CORNERS['0,0,0'];
327
- const c100 = RYB_CORNERS['1,0,0'];
328
- const c010 = RYB_CORNERS['0,1,0'];
329
- const c110 = RYB_CORNERS['1,1,0'];
330
- const c001 = RYB_CORNERS['0,0,1'];
331
- const c101 = RYB_CORNERS['1,0,1'];
332
- const c011 = RYB_CORNERS['0,1,1'];
333
- const c111 = RYB_CORNERS['1,1,1'];
334
- // Interpolate along R axis (between r=0 and r=1 planes)
335
- const c00 = this.lerpRgb(c000, c100, r);
336
- const c01 = this.lerpRgb(c001, c101, r);
337
- const c10 = this.lerpRgb(c010, c110, r);
338
- const c11 = this.lerpRgb(c011, c111, r);
339
- // Interpolate along Y axis
340
- const c0 = this.lerpRgb(c00, c10, y);
341
- const c1 = this.lerpRgb(c01, c11, y);
342
- // Interpolate along B axis (final result)
343
- return this.lerpRgb(c0, c1, b);
344
- }
345
- /**
346
- * Linear interpolation between two RGB colors
347
- *
348
- * @param a First color
349
- * @param b Second color
350
- * @param t Interpolation factor (0 = a, 1 = b)
351
- * @returns Interpolated color
352
- * @internal
353
- */
354
- static lerpRgb(a, b, t) {
355
- return {
356
- r: a.r + (b.r - a.r) * t,
357
- g: a.g + (b.g - a.g) * t,
358
- b: a.b + (b.b - a.b) * t,
359
- };
360
- }
361
- }
362
- //# sourceMappingURL=RybColorMixer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RybColorMixer.js","sourceRoot":"","sources":["../../../src/services/color/RybColorMixer.ts"],"names":[],"mappings":"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"}
@@ -1,43 +0,0 @@
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
- import type { HexColor } from '@xivdyetools/types';
17
- /**
18
- * Spectral Color Mixer using Kubelka-Munk theory
19
- *
20
- * Provides realistic paint/pigment color mixing by simulating
21
- * how light interacts with pigmented materials.
22
- */
23
- export declare class SpectralMixer {
24
- /**
25
- * Mix two colors using Kubelka-Munk spectral mixing
26
- *
27
- * This produces results similar to mixing physical paints:
28
- * - Blue + Yellow = Green (like mixing paints)
29
- * - More realistic tinting and shading
30
- * - Handles complementary colors naturally
31
- *
32
- * @param hex1 First hex color
33
- * @param hex2 Second hex color
34
- * @param ratio Mix ratio (0 = all hex1, 0.5 = equal mix, 1 = all hex2). Default: 0.5
35
- * @returns Mixed color as hex
36
- *
37
- * @example
38
- * // Mix blue and yellow to get green
39
- * SpectralMixer.mixColors('#0000FF', '#FFFF00') // Returns green-ish color
40
- */
41
- static mixColors(hex1: string, hex2: string, ratio?: number): HexColor;
42
- }
43
- //# sourceMappingURL=SpectralMixer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SpectralMixer.d.ts","sourceRoot":"","sources":["../../../src/services/color/SpectralMixer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD;;;;;GAKG;AACH,qBAAa,aAAa;IACxB;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAY,GAAG,QAAQ;CAoB5E"}
@@ -1,59 +0,0 @@
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
- import * as spectral from 'spectral.js';
17
- import { ColorConverter } from './ColorConverter.js';
18
- /**
19
- * Spectral Color Mixer using Kubelka-Munk theory
20
- *
21
- * Provides realistic paint/pigment color mixing by simulating
22
- * how light interacts with pigmented materials.
23
- */
24
- export class SpectralMixer {
25
- /**
26
- * Mix two colors using Kubelka-Munk spectral mixing
27
- *
28
- * This produces results similar to mixing physical paints:
29
- * - Blue + Yellow = Green (like mixing paints)
30
- * - More realistic tinting and shading
31
- * - Handles complementary colors naturally
32
- *
33
- * @param hex1 First hex color
34
- * @param hex2 Second hex color
35
- * @param ratio Mix ratio (0 = all hex1, 0.5 = equal mix, 1 = all hex2). Default: 0.5
36
- * @returns Mixed color as hex
37
- *
38
- * @example
39
- * // Mix blue and yellow to get green
40
- * SpectralMixer.mixColors('#0000FF', '#FFFF00') // Returns green-ish color
41
- */
42
- static mixColors(hex1, hex2, ratio = 0.5) {
43
- // Clamp ratio to valid range
44
- ratio = Math.max(0, Math.min(1, ratio));
45
- // Create spectral Color objects
46
- const color1 = new spectral.Color(hex1);
47
- const color2 = new spectral.Color(hex2);
48
- // Mix using Kubelka-Munk theory
49
- // The mix function takes [color, concentration] pairs
50
- // We use (1 - ratio) for color1 and ratio for color2
51
- const mixed = spectral.mix([color1, 1 - ratio], [color2, ratio]);
52
- // Convert to hex string
53
- // toString returns hex format by default with gamut mapping
54
- const hexResult = mixed.toString({ format: 'hex', method: 'map' });
55
- // Normalize to our HexColor format
56
- return ColorConverter.normalizeHex(hexResult);
57
- }
58
- }
59
- //# sourceMappingURL=SpectralMixer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SpectralMixer.js","sourceRoot":"","sources":["../../../src/services/color/SpectralMixer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,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;CACF"}