♻️ Rework color conversion
This commit is contained in:
parent
0f01b73c22
commit
185ba23520
4 changed files with 105 additions and 38 deletions
7
package-lock.json
generated
7
package-lock.json
generated
|
@ -9,7 +9,6 @@
|
|||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"colortranslator": "^4.1.0",
|
||||
"jsonc-parser": "^3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -674,12 +673,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/colortranslator": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/colortranslator/-/colortranslator-4.1.0.tgz",
|
||||
"integrity": "sha512-bwa5awaMnQ6dpm9D3nbsFwUr6x6FrTKmxPdolNtSYfxCNR7ZM93GG1OF5Y3Sy1LvYdalb3riKC9uTn0X5NB36g==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
"typescript-eslint": "^8.16.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"colortranslator": "^4.1.0",
|
||||
"jsonc-parser": "^3.3.1"
|
||||
}
|
||||
}
|
|
@ -5,9 +5,12 @@
|
|||
import * as vscode from "vscode";
|
||||
import { getCursorPath, getRawCursorPath, getStartEnd } from "./utils/cursor";
|
||||
import { getValueFromPath, pathToJSONPath } from "./utils/json";
|
||||
import { ColorTranslator } from "colortranslator";
|
||||
import * as path from "path";
|
||||
import { findHexColor } from "./utils/color";
|
||||
import {
|
||||
findHexColorName,
|
||||
mapCompleteToVScode,
|
||||
vsCodeToHex,
|
||||
} from "./utils/color";
|
||||
|
||||
/**
|
||||
* Icon definition provider
|
||||
|
@ -110,29 +113,18 @@ export const colorProvider = vscode.languages.registerColorProvider(
|
|||
let outputColor: string;
|
||||
|
||||
// Convert the color to a hex string
|
||||
outputColor = new ColorTranslator(
|
||||
`rgba(${color.red * 255}, ${color.green * 255}, ${color.blue * 255}, ${
|
||||
color.alpha
|
||||
})`
|
||||
).HEXA;
|
||||
|
||||
console.log(`First output color: ${outputColor}`);
|
||||
outputColor = vsCodeToHex(color);
|
||||
|
||||
// If the color is fully opaque (AKA it ends with FF), we can remove the alpha channel
|
||||
outputColor = outputColor.endsWith("FF")
|
||||
outputColor = outputColor.endsWith("ff")
|
||||
? outputColor.substring(0, 7)
|
||||
: outputColor;
|
||||
|
||||
console.log(`Output color after alpha check: ${outputColor}`);
|
||||
|
||||
// See if we can find a color name
|
||||
const colorName = findHexColor(outputColor);
|
||||
const colorName = findHexColorName(outputColor);
|
||||
if (colorName) {
|
||||
outputColor = colorName.name;
|
||||
}
|
||||
|
||||
console.log(`Output color after color name check: ${outputColor}`);
|
||||
|
||||
// If we have a pair like #AABBCC, we can shorten that to #ABC
|
||||
if (
|
||||
outputColor[1] === outputColor[2] &&
|
||||
|
@ -142,7 +134,7 @@ export const colorProvider = vscode.languages.registerColorProvider(
|
|||
outputColor = `#${outputColor[1]}${outputColor[3]}${outputColor[5]}`;
|
||||
}
|
||||
|
||||
console.log(`Color after shortening: ${outputColor}`);
|
||||
console.log("Output color from picker:", outputColor);
|
||||
|
||||
return [
|
||||
{
|
||||
|
@ -182,25 +174,18 @@ export const colorProvider = vscode.languages.registerColorProvider(
|
|||
if (regex.exec(path)) {
|
||||
const colorValue = getValueFromPath(text, pathToJSONPath(path));
|
||||
|
||||
let colorRgba;
|
||||
try {
|
||||
colorRgba = new ColorTranslator(colorValue).RGBAObject;
|
||||
} catch (error) {
|
||||
console.error("Error translating color value:", error);
|
||||
const colorOuput = mapCompleteToVScode(colorValue);
|
||||
|
||||
if (!colorOuput) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Output color: ${colorRgba.R}, ${colorRgba.G}, ${colorRgba.B}, ${colorRgba.A}`
|
||||
`Output color: ${colorOuput.red}, ${colorOuput.green}, ${colorOuput.blue}, ${colorOuput.alpha}`
|
||||
);
|
||||
|
||||
colors.push({
|
||||
color: new vscode.Color(
|
||||
colorRgba.R / 255,
|
||||
colorRgba.G / 255,
|
||||
colorRgba.B / 255,
|
||||
colorRgba.A ?? 1
|
||||
),
|
||||
color: colorOuput,
|
||||
range: getStartEnd(text, pathToJSONPath(path)),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* Some utilities to works with colors, mainly color names
|
||||
*/
|
||||
|
||||
import { Color as vscodeColor } from "vscode";
|
||||
|
||||
/**
|
||||
* Representation of a color, contains hex and rgb values
|
||||
*/
|
||||
|
@ -34,11 +36,99 @@ interface Color {
|
|||
|
||||
/**
|
||||
* Find a color by its hex value
|
||||
*
|
||||
* @param hex Hex color
|
||||
* @returns Color object, if found
|
||||
*/
|
||||
export function findHexColor(hex: string): Color | undefined {
|
||||
export function findHexColorName(hex: string): Color | undefined {
|
||||
return colors.find((color) => color.hex === hex.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a color by its name
|
||||
*
|
||||
* @param name Color name
|
||||
* @returns Color object, if found
|
||||
*/
|
||||
export function findHexColor(name: string): Color | undefined {
|
||||
return colors.find((color) => color.name === name.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a VSCode color to a hex string
|
||||
*
|
||||
* @param color VSCode color
|
||||
* @returns Hex representation of the color
|
||||
*/
|
||||
export function vsCodeToHex(color: vscodeColor): string {
|
||||
const red = Math.round(color.red * 255)
|
||||
.toString(16)
|
||||
.padStart(2, "0");
|
||||
const green = Math.round(color.green * 255)
|
||||
.toString(16)
|
||||
.padStart(2, "0");
|
||||
const blue = Math.round(color.blue * 255)
|
||||
.toString(16)
|
||||
.padStart(2, "0");
|
||||
const alpha = Math.round(color.alpha * 255)
|
||||
.toString(16)
|
||||
.padStart(2, "0");
|
||||
return `#${red}${green}${blue}${alpha}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a color from a MapComplete JSON to a VSCode color
|
||||
*
|
||||
* Supports HEX (3, 6 or 8 characters) and color names
|
||||
*
|
||||
* @param color Color from MapComplete JSON
|
||||
*/
|
||||
export function mapCompleteToVScode(color: string): vscodeColor | undefined {
|
||||
// First check if we have a hex color
|
||||
if (color.startsWith("#")) {
|
||||
// Check if we have 3, 6 or 8 defined characters
|
||||
switch (color.length) {
|
||||
case 4:
|
||||
return new vscodeColor(
|
||||
parseInt(color[1] + color[1], 16) / 255,
|
||||
parseInt(color[2] + color[2], 16) / 255,
|
||||
parseInt(color[3] + color[3], 16) / 255,
|
||||
1
|
||||
);
|
||||
case 7:
|
||||
return new vscodeColor(
|
||||
parseInt(color.substring(1, 2), 16) / 255,
|
||||
parseInt(color.substring(3, 2), 16) / 255,
|
||||
parseInt(color.substring(5, 2), 16) / 255,
|
||||
1
|
||||
);
|
||||
case 9:
|
||||
return new vscodeColor(
|
||||
parseInt(color.substring(1, 2), 16) / 255,
|
||||
parseInt(color.substring(3, 2), 16) / 255,
|
||||
parseInt(color.substring(5, 2), 16) / 255,
|
||||
parseInt(color.substring(7, 2), 16) / 255
|
||||
);
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
} else {
|
||||
// Look for a color name
|
||||
const namedColor = findHexColor(color);
|
||||
|
||||
if (namedColor) {
|
||||
return new vscodeColor(
|
||||
namedColor.r / 255,
|
||||
namedColor.g / 255,
|
||||
namedColor.b / 255,
|
||||
1
|
||||
);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List of all named colors
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue