Skip to content

Commit 4a77a49

Browse files
committed
Vendor snapshot-rev4.json, generate SCSS snapshot from 4096 reference colors
- Download and vendor snapshot-rev4.json from hsluv/hsluv main branch - Rewrite snapshot.mjs to read colors from vendored JSON and compute SCSS snapshot values via Sass compilation - Generate _snapshot.scss with all 4096 colors (up from 16) - Add .prettierignore for generated snapshot file - Fix SassNumber unit detection (deg) for proper SCSS output
1 parent 21cb416 commit 4a77a49

4 files changed

Lines changed: 57427 additions & 1077 deletions

File tree

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test/data/_snapshot.scss

snapshot.mjs

Lines changed: 99 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -6,130 +6,126 @@ import * as sass from "sass";
66
const __filename = fileURLToPath(import.meta.url);
77
const __dirname = path.dirname(__filename);
88

9-
const samples = [
10-
"#1100ff",
11-
"#0066aa",
12-
"#cc33cc",
13-
"#0022dd",
14-
"#0066ee",
15-
"#bbbb11",
16-
"#5566dd",
17-
"#55eeaa",
18-
"#ee7700",
19-
"#33bbaa",
20-
"#44aa77",
21-
"#dd6699",
22-
"#99ee22",
23-
"#ff22aa",
24-
"#99aa11",
25-
"#dd1122",
26-
];
27-
28-
function hexToRgb(hex) {
29-
return {
30-
r: parseInt(hex.slice(1, 3), 16),
31-
g: parseInt(hex.slice(3, 5), 16),
32-
b: parseInt(hex.slice(5, 7), 16),
33-
};
34-
}
9+
const colors = JSON.parse(
10+
fs.readFileSync(
11+
path.join(__dirname, "test", "data", "snapshot-rev4.json"),
12+
"utf8"
13+
)
14+
);
3515

36-
function sassInspect($map) {
37-
const entries = [];
38-
if ($map.contents) {
39-
$map.contents.forEach((v, k) => {
40-
const key = k instanceof sass.SassString ? k.text : k.toString();
41-
entries.push(`'${key}': ${v}`);
42-
});
43-
}
44-
return new sass.SassString("(" + entries.join(", ") + ")");
45-
}
16+
const hexes = Object.keys(colors);
4617

18+
const BATCH_SIZE = 200;
4719
const debugOutput = {};
4820

49-
const result = sass.compileString(
50-
`
21+
for (let batchStart = 0; batchStart < hexes.length; batchStart += BATCH_SIZE) {
22+
const batch = hexes.slice(batchStart, batchStart + BATCH_SIZE);
23+
24+
const sassSrc = `
5125
@use 'conversions' as conv;
5226
@use 'conversions/lch' as lch;
5327
@use 'conversions/luv' as luv;
5428
@use 'conversions/xyz' as xyz;
5529
@use 'conversions/rgb' as rgb;
5630
57-
@function map-inspect($map) {
58-
@return map-inspect-custom($map);
59-
}
60-
61-
${samples
62-
.map((color) => {
63-
const rgb = hexToRgb(color);
64-
const hex = color.slice(1);
31+
${batch
32+
.map((hex) => {
33+
const [r, g, b] = colors[hex].rgb;
34+
const suffix = hex.slice(1);
35+
const rr = Math.round(r * 255);
36+
const rg = Math.round(g * 255);
37+
const rb = Math.round(b * 255);
6538
return `
66-
@debug "${color}-hsluv " + map-inspect(conv.rgb-hsluv(('r': ${rgb.r}, 'g': ${rgb.g}, 'b': ${rgb.b})));
67-
@debug "${color}-hpluv " + map-inspect(conv.rgb-hpluv(('r': ${rgb.r}, 'g': ${rgb.g}, 'b': ${rgb.b})));
68-
69-
$hsluv${hex}: conv.rgb-hsluv(('r': ${rgb.r}, 'g': ${rgb.g}, 'b': ${rgb.b}));
70-
$hpluv${hex}: conv.rgb-hpluv(('r': ${rgb.r}, 'g': ${rgb.g}, 'b': ${rgb.b}));
71-
72-
$lch-from-hsluv${hex}: lch.from-hsluv($hsluv${hex});
73-
$lch-from-hpluv${hex}: lch.from-hpluv($hpluv${hex});
74-
$luv${hex}: luv.from-lch($lch-from-hsluv${hex});
75-
$xyz${hex}: xyz.from-luv($luv${hex});
76-
$rgb-from-xyz${hex}: rgb.from-xyz($xyz${hex});
77-
78-
$xyz-back${hex}: rgb.to-xyz(('r': ${rgb.r}, 'g': ${rgb.g}, 'b': ${rgb.b}));
79-
$luv-back${hex}: xyz.to-luv($xyz-back${hex});
80-
$lch-back${hex}: luv.to-lch($luv-back${hex});
81-
$hsluv-back${hex}: lch.to-hsluv($lch-back${hex});
82-
$hpluv-back${hex}: lch.to-hpluv($lch-back${hex});
83-
84-
@debug "${color}-lch " + map-inspect($lch-from-hsluv${hex});
85-
@debug "${color}-luv " + map-inspect($luv${hex});
86-
@debug "${color}-xyz " + map-inspect($xyz${hex});
87-
@debug "${color}-rgb " + map-inspect($rgb-from-xyz${hex});
88-
@debug "${color}-xyz-back " + map-inspect($xyz-back${hex});
89-
@debug "${color}-luv-back " + map-inspect($luv-back${hex});
90-
@debug "${color}-lch-back " + map-inspect($lch-back${hex});
91-
@debug "${color}-hsluv-back " + map-inspect($hsluv-back${hex});
92-
@debug "${color}-hpluv-back " + map-inspect($hpluv-back${hex});
93-
@debug "${color}-lch-from-hpluv " + map-inspect($lch-from-hpluv${hex});
39+
$hsluv${suffix}: conv.rgb-hsluv(('r': ${rr}, 'g': ${rg}, 'b': ${rb}));
40+
$hpluv${suffix}: conv.rgb-hpluv(('r': ${rr}, 'g': ${rg}, 'b': ${rb}));
41+
$lch${suffix}: lch.from-hsluv($hsluv${suffix});
42+
$lch-from-hpluv${suffix}: lch.from-hpluv($hpluv${suffix});
43+
$luv${suffix}: luv.from-lch($lch${suffix});
44+
$xyz${suffix}: xyz.from-luv($luv${suffix});
45+
$rgb${suffix}: rgb.from-xyz($xyz${suffix});
46+
$xyz-back${suffix}: rgb.to-xyz(('r': ${rr}, 'g': ${rg}, 'b': ${rb}));
47+
$luv-back${suffix}: xyz.to-luv($xyz-back${suffix});
48+
$lch-back${suffix}: luv.to-lch($luv-back${suffix});
49+
$hsluv-back${suffix}: lch.to-hsluv($lch-back${suffix});
50+
$hpluv-back${suffix}: lch.to-hpluv($lch-back${suffix});
51+
52+
@if not _snapshot-output("hsluv${suffix}", $hsluv${suffix}) {}
53+
@if not _snapshot-output("hpluv${suffix}", $hpluv${suffix}) {}
54+
@if not _snapshot-output("lch${suffix}", $lch${suffix}) {}
55+
@if not _snapshot-output("lch-from-hpluv${suffix}", $lch-from-hpluv${suffix}) {}
56+
@if not _snapshot-output("luv${suffix}", $luv${suffix}) {}
57+
@if not _snapshot-output("xyz${suffix}", $xyz${suffix}) {}
58+
@if not _snapshot-output("rgb${suffix}", $rgb${suffix}) {}
59+
@if not _snapshot-output("xyz-back${suffix}", $xyz-back${suffix}) {}
60+
@if not _snapshot-output("luv-back${suffix}", $luv-back${suffix}) {}
61+
@if not _snapshot-output("lch-back${suffix}", $lch-back${suffix}) {}
62+
@if not _snapshot-output("hsluv-back${suffix}", $hsluv-back${suffix}) {}
63+
@if not _snapshot-output("hpluv-back${suffix}", $hpluv-back${suffix}) {}
9464
`;
9565
})
9666
.join("\n")}
97-
`,
98-
{
67+
`;
68+
69+
const result = sass.compileString(sassSrc, {
9970
loadPaths: [path.join(__dirname, "src")],
10071
functions: {
101-
"map-inspect-custom($map)": (args) => sassInspect(args[0]),
102-
},
103-
logger: {
104-
debug: (msg) => {
105-
const spaceIdx = msg.indexOf(" ");
106-
const key = msg.slice(0, spaceIdx);
107-
const val = msg.slice(spaceIdx + 1).trim();
108-
debugOutput[key] = val;
72+
"_snapshot-output($key, $value)": (args) => {
73+
const key = args[0].assertString().text;
74+
debugOutput[key] = sassValueToScss(args[1]);
75+
return sass.sassNull;
10976
},
110-
warn: () => {},
11177
},
78+
});
79+
80+
const progress = Math.min(batchStart + BATCH_SIZE, hexes.length);
81+
console.error(`Processed ${progress}/${hexes.length} colors...`);
82+
}
83+
84+
function sassValueToScss(value) {
85+
if (value instanceof sass.SassMap) {
86+
const entries = [];
87+
value.contents.forEach((v, k) => {
88+
const key = k instanceof sass.SassString ? k.text : k.toString();
89+
entries.push(`"${key}": ${sassValueToScss(v)}`);
90+
});
91+
return "(" + entries.join(", ") + ")";
11292
}
113-
);
93+
if (value instanceof sass.SassNumber) {
94+
let str = String(value.value);
95+
if ([...value.numeratorUnits].includes("deg")) str += "deg";
96+
return str;
97+
}
98+
if (value instanceof sass.SassColor) {
99+
const r = Math.round(value.red * 255);
100+
const g = Math.round(value.green * 255);
101+
const b = Math.round(value.blue * 255);
102+
return `("r": ${r}, "g": ${g}, "b": ${b})`;
103+
}
104+
if (value instanceof sass.SassString) {
105+
return `"${value.text}"`;
106+
}
107+
return String(value);
108+
}
114109

115110
const lines = ["$values: ("];
116111

117-
samples.forEach((color, i) => {
118-
const last = i === samples.length - 1;
119-
120-
lines.push(` '${color}': (`);
121-
lines.push(` 'hsluv': ${debugOutput[color + "-hsluv"]},`);
122-
lines.push(` 'hpluv': ${debugOutput[color + "-hpluv"]},`);
123-
lines.push(` 'lch': ${debugOutput[color + "-lch"]},`);
124-
lines.push(` 'luv': ${debugOutput[color + "-luv"]},`);
125-
lines.push(` 'xyz': ${debugOutput[color + "-xyz"]},`);
126-
lines.push(` 'rgb': ${debugOutput[color + "-rgb"]},`);
127-
lines.push(` 'xyz-back': ${debugOutput[color + "-xyz-back"]},`);
128-
lines.push(` 'luv-back': ${debugOutput[color + "-luv-back"]},`);
129-
lines.push(` 'lch-back': ${debugOutput[color + "-lch-back"]},`);
130-
lines.push(` 'hsluv-back': ${debugOutput[color + "-hsluv-back"]},`);
131-
lines.push(` 'hpluv-back': ${debugOutput[color + "-hpluv-back"]},`);
132-
lines.push(` 'lch-from-hpluv': ${debugOutput[color + "-lch-from-hpluv"]}`);
112+
hexes.forEach((hex, i) => {
113+
const last = i === hexes.length - 1;
114+
const s = hex.slice(1);
115+
116+
lines.push(` "${hex}": (`);
117+
lines.push(` "hsluv": ${debugOutput["hsluv" + s]},`);
118+
lines.push(` "hpluv": ${debugOutput["hpluv" + s]},`);
119+
lines.push(` "lch": ${debugOutput["lch" + s]},`);
120+
lines.push(` "lch-from-hpluv": ${debugOutput["lch-from-hpluv" + s]},`);
121+
lines.push(` "luv": ${debugOutput["luv" + s]},`);
122+
lines.push(` "xyz": ${debugOutput["xyz" + s]},`);
123+
lines.push(` "rgb": ${debugOutput["rgb" + s]},`);
124+
lines.push(` "xyz-back": ${debugOutput["xyz-back" + s]},`);
125+
lines.push(` "luv-back": ${debugOutput["luv-back" + s]},`);
126+
lines.push(` "lch-back": ${debugOutput["lch-back" + s]},`);
127+
lines.push(` "hsluv-back": ${debugOutput["hsluv-back" + s]},`);
128+
lines.push(` "hpluv-back": ${debugOutput["hpluv-back" + s]}`);
133129
lines.push(` )${last ? "" : ","}`);
134130
});
135131

@@ -138,5 +134,5 @@ lines.push(");\n");
138134
const outputPath = path.join(__dirname, "test", "data", "_snapshot.scss");
139135
fs.writeFileSync(outputPath, lines.join("\n"), "utf8");
140136
console.log(
141-
`Snapshot written to ${outputPath} (${Object.keys(debugOutput).length} values)`
137+
`Snapshot written to ${outputPath} (${hexes.length} colors)`
142138
);

0 commit comments

Comments
 (0)