|
| 1 | +# Color Grid Layout Documentation |
| 2 | + |
| 3 | +## Systematic 3×3 Color Selection Grid |
| 4 | + |
| 5 | +### Visual Layout |
| 6 | + |
| 7 | +``` |
| 8 | +┌──────────────────────┬──────────────────────┬──────────────────────┐ |
| 9 | +│ Darker, -a* │ Darker, -b* │ Darker, +a* │ |
| 10 | +│ L: -20 │ L: -20 │ L: -20 │ |
| 11 | +│ a: -2.3 │ a: 0 │ a: +2.3 │ |
| 12 | +│ b: 0 │ b: -2.3 │ b: 0 │ |
| 13 | +│ (less red) │ (less yellow) │ (more red) │ |
| 14 | +├──────────────────────┼──────────────────────┼──────────────────────┤ |
| 15 | +│ Same L, -a* │ ★ ORIGINAL ★ │ Same L, +a* │ |
| 16 | +│ L: 0 │ L: 0 │ L: 0 │ |
| 17 | +│ a: -2.3 │ a: 0 │ a: +2.3 │ |
| 18 | +│ b: 0 │ b: 0 │ b: 0 │ |
| 19 | +│ (less red) │ (unchanged) │ (more red) │ |
| 20 | +├──────────────────────┼──────────────────────┼──────────────────────┤ |
| 21 | +│ Lighter, -a* │ Lighter, +b* │ Lighter, +a* │ |
| 22 | +│ L: +20 │ L: +20 │ L: +20 │ |
| 23 | +│ a: -2.3 │ a: 0 │ a: +2.3 │ |
| 24 | +│ b: 0 │ b: +2.3 │ b: 0 │ |
| 25 | +│ (less red) │ (more yellow) │ (more red) │ |
| 26 | +└──────────────────────┴──────────────────────┴──────────────────────┘ |
| 27 | +``` |
| 28 | + |
| 29 | +### Color Space Dimensions |
| 30 | + |
| 31 | +#### CIELAB Color Space |
| 32 | +The CIELAB (or L\*a\*b\*) color space is designed to be perceptually uniform: |
| 33 | +- **L\* (Lightness):** 0 (black) to 100 (white) |
| 34 | +- **a\*:** Green (-) to Red (+) |
| 35 | +- **b\*:** Blue (-) to Yellow (+) |
| 36 | + |
| 37 | +#### Parameters |
| 38 | + |
| 39 | +| Parameter | Value | Description | |
| 40 | +|-----------|-------|-------------| |
| 41 | +| **JND** | 2.3 | Just Noticeable Difference in Delta E (perceptual threshold) | |
| 42 | +| **L\* Step** | 10 | Lightness change per step | |
| 43 | +| **L\* Range** | ±20 | Total lightness variation (2 steps) | |
| 44 | +| **a\* Shift** | ±2.3 | Red-green dimension shift (1 JND) | |
| 45 | +| **b\* Shift** | ±2.3 | Yellow-blue dimension shift (1 JND) | |
| 46 | + |
| 47 | +### Design Rationale |
| 48 | + |
| 49 | +1. **Center Position (Position 4):** Always shows the original color for easy reference |
| 50 | +2. **Horizontal Axis (Positions 3, 4, 5):** Explores red/green dimension at constant lightness |
| 51 | +3. **Vertical Axis (Positions 1, 4, 7):** Explores yellow/blue dimension with lightness changes |
| 52 | +4. **Diagonal Corners:** Combine lightness changes with red/green shifts |
| 53 | +5. **Perceptual Uniformity:** All shifts are based on JND, ensuring consistent perceptual differences |
| 54 | + |
| 55 | +### Example Transformation |
| 56 | + |
| 57 | +Starting with a blue color: `#3A7DFF` |
| 58 | + |
| 59 | +**LAB values:** L=52, a=13, b=-60 |
| 60 | + |
| 61 | +**Generated alternatives:** |
| 62 | +- Position 0: L=32, a=10.7, b=-60 (darker, less red) |
| 63 | +- Position 1: L=32, a=13, b=-62.3 (darker, less yellow/more blue) |
| 64 | +- Position 2: L=32, a=15.3, b=-60 (darker, more red) |
| 65 | +- Position 3: L=52, a=10.7, b=-60 (same L, less red) |
| 66 | +- **Position 4: L=52, a=13, b=-60 (ORIGINAL)** |
| 67 | +- Position 5: L=52, a=15.3, b=-60 (same L, more red) |
| 68 | +- Position 6: L=72, a=10.7, b=-60 (lighter, less red) |
| 69 | +- Position 7: L=72, a=13, b=-57.7 (lighter, more yellow/less blue) |
| 70 | +- Position 8: L=72, a=15.3, b=-60 (lighter, more red) |
| 71 | + |
| 72 | +### Adjusting JND |
| 73 | + |
| 74 | +To modify the perceptual difference between alternatives, change the `JND_LAB` constant: |
| 75 | + |
| 76 | +```typescript |
| 77 | +// More subtle differences (harder to distinguish) |
| 78 | +const JND_LAB = 1.5; |
| 79 | + |
| 80 | +// More obvious differences (easier to distinguish) |
| 81 | +const JND_LAB = 4.0; |
| 82 | + |
| 83 | +// Current setting (standard perceptual threshold) |
| 84 | +const JND_LAB = 2.3; |
| 85 | +``` |
| 86 | + |
| 87 | +### Gamut Considerations |
| 88 | + |
| 89 | +**Problem:** Not all LAB colors can be displayed in sRGB (the color space of most displays). |
| 90 | + |
| 91 | +**Solution:** The `clampChroma` function automatically finds the nearest displayable color: |
| 92 | +- Maintains the same L\* and hue |
| 93 | +- Reduces chroma (saturation) until color is displayable |
| 94 | +- Preserves perceptual relationships as much as possible |
| 95 | + |
| 96 | +**When it matters:** |
| 97 | +- Very saturated colors at extreme lightness values |
| 98 | +- Colors near the edges of sRGB gamut |
| 99 | +- Vivid reds, blues, and greens are most affected |
| 100 | + |
| 101 | +### Research Applications |
| 102 | + |
| 103 | +This systematic grid enables: |
| 104 | +1. **Perceptual studies:** Compare JND values across different base colors |
| 105 | +2. **Preference mapping:** Identify which color space dimensions drive preferences |
| 106 | +3. **Visualization quality:** Test how color changes affect chart readability |
| 107 | +4. **Color palette design:** Systematically explore alternatives to palette colors |
| 108 | + |
| 109 | +### Implementation Details |
| 110 | + |
| 111 | +The color transformation pipeline: |
| 112 | +1. Parse hex color → LAB color space |
| 113 | +2. Apply dimensional shifts (L, a, b) |
| 114 | +3. Clamp L to valid range [0, 100] |
| 115 | +4. Clamp chroma to sRGB gamut |
| 116 | +5. Convert back to hex color |
| 117 | +6. Handle errors gracefully (return original if conversion fails) |
| 118 | + |
| 119 | +### References |
| 120 | + |
| 121 | +- **Delta E:** CIE 2000 color difference formula (ΔE\*₀₀) |
| 122 | +- **JND Standard:** Approximately 2.3 ΔE units (varies by context) |
| 123 | +- **CIELAB:** Commission Internationale de l'Éclairage (1976) |
| 124 | +- **Color Library:** Culori v4.0.2 (https://culorijs.org/) |
0 commit comments