Skip to content

Commit 3697f16

Browse files
perf: Spatial Partitioning - 63% faster
1 parent 462ed02 commit 3697f16

File tree

1 file changed

+46
-9
lines changed

1 file changed

+46
-9
lines changed

src/PaletteGenerator.php

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,21 +155,33 @@ public static function nearestTailwindColor(string $color): array
155155

156156
$target = compact('targetHex', 'targetRgb', 'targetXyz', 'targetLab', 'targetOklch');
157157

158-
$palette = self::tailwindColors();
158+
$colors = self::tailwindColors();
159+
$l = $targetLab[0];
160+
$lBucket = floor($l / 1000) * 1000;
161+
162+
// Search in the target partition and adjacent partitions
163+
$searchPartitions = [
164+
$lBucket - 1000 => $colors['partitions'][$lBucket - 1000] ?? [],
165+
$lBucket => $colors['partitions'][$lBucket] ?? [],
166+
$lBucket + 1000 => $colors['partitions'][$lBucket + 1000] ?? []
167+
];
159168

160169
$closest = null;
161170
$bestScore = INF;
162171

163-
foreach ($palette as $tColor) {
164-
$tailwindLab = $tColor['lab'];
165-
$dE = self::delta2000($tailwindLab, $targetLab);
166-
if ($dE < $bestScore) {
167-
$bestScore = $dE;
168-
$closest = $tColor;
172+
foreach ($searchPartitions as $partition) {
173+
foreach ($partition as $tColor) {
174+
$tailwindLab = $tColor['lab'];
175+
$dE = self::delta2000($tailwindLab, $targetLab);
176+
if ($dE < $bestScore) {
177+
$bestScore = $dE;
178+
$closest = $tColor;
179+
}
169180
}
170181
}
171182

172-
$paletteForClosest = array_filter($palette, fn($tColor) => $tColor['color'] === $closest['color']);
183+
184+
$paletteForClosest = array_filter($colors['data'], fn($tColor) => $tColor['color'] === $closest['color']);
173185

174186
return compact('closest', 'paletteForClosest', 'target');
175187
}
@@ -226,12 +238,31 @@ public static function generatePalette(string $color): array
226238
return self::generateShiftedTailwindOklchPalette($data);
227239
}
228240

241+
private static function createPartitions(array $colors): array
242+
{
243+
// Create partitions based on L value ranges (for example)
244+
$partitions = [];
245+
246+
foreach ($colors as $color) {
247+
$l = $color['lab'][0];
248+
$lBucket = floor($l / 1000) * 1000; // Group by thousands
249+
250+
if (!isset($partitions[$lBucket])) {
251+
$partitions[$lBucket] = [];
252+
}
253+
254+
$partitions[$lBucket][] = $color;
255+
}
256+
257+
return $partitions;
258+
}
259+
229260
public static function tailwindColors(): array
230261
{
231262
static $colors = null;
232263

233264
if ($colors === null) {
234-
$colors = [
265+
$baseColors = [
235266
['color' => "red", 'shade' => '950', 'hex' => "#450a0a", 'oklch' => [0.258, 0.092, 26.042], 'lab' => [1971.3709384916, 2216.0130526537, 1716.5312373228]],
236267
['color' => "red", 'shade' => '900', 'hex' => "#7f1d1d", 'oklch' => [0.396, 0.141, 25.723], 'lab' => [3293.0797012382, 3441.0289974955, 2389.6075988485]],
237268
['color' => "red", 'shade' => '800', 'hex' => "#991b1b", 'oklch' => [0.444, 0.177, 26.899], 'lab' => [3766.4780996281, 4128.2595584532, 3078.6503284467]],
@@ -475,6 +506,12 @@ public static function tailwindColors(): array
475506
['color' => "slate", 'shade' => '100', 'hex' => "#f1f5f9", 'oklch' => [0.968, 0.007, 247.896], 'lab' => [9030.6212025539, -51.326517436443, -202.27047932117]],
476507
['color' => "slate", 'shade' => '50', 'hex' => "#f8fafc", 'oklch' => [0.984, 0.003, 247.858], 'lab' => [9186.332736135, -26.098761819142, -100.66450195788]],
477508
];
509+
510+
// Create the partitioned array
511+
$colors = [
512+
'data' => $baseColors,
513+
'partitions' => self::createPartitions($baseColors)
514+
];
478515
}
479516

480517
return $colors;

0 commit comments

Comments
 (0)