-
Notifications
You must be signed in to change notification settings - Fork 0
/
convert.js
134 lines (117 loc) · 3.98 KB
/
convert.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// CSV source URL
const csvURL = 'https://technochicken.github.io/ral_classic.csv';
let ralTable = {}; // Will store RAL code mappings
// Fetch and parse the CSV
function loadRALData() {
Papa.parse(csvURL, {
download: true,
header: true,
complete: function(results) {
ralTable = processCSVData(results.data);
}
});
}
// Convert CSV data to an easy lookup object
function processCSVData(data) {
const lookupTable = {};
data.forEach(row => {
const ralCode = row.RAL ? row.RAL.trim() : null;
const hexValue = row.HEX ? row.HEX.trim() : null;
const rgbValue = row.RGB ? row.RGB.split('-').map(Number) : null;
// Only process rows that have valid RAL and HEX values
if (ralCode && hexValue && rgbValue) {
lookupTable[ralCode] = {
hex: hexValue,
name: row.German ? row.German.trim() : "Unknown",
rgb: rgbValue
};
}
});
return lookupTable;
}
// Utility function to normalize hex input (#fff, fff, #ffffff, ffffff -> #ffffff)
function normalizeHex(hex) {
hex = hex.replace('#', '');
if (hex.length === 3) {
hex = hex.split('').map(c => c + c).join('');
}
return `#${hex}`;
}
// Utility function to convert hex to RGB array [R, G, B]
function hexToRgb(hex) {
hex = normalizeHex(hex).substring(1); // Remove #
const bigint = parseInt(hex, 16);
return [(bigint >> 16) & 255, (bigint >> 8) & 255, bigint & 255];
}
// Calculate Euclidean distance between two RGB arrays
function calculateDistance(rgb1, rgb2) {
return Math.sqrt(
Math.pow(rgb2[0] - rgb1[0], 2) +
Math.pow(rgb2[1] - rgb1[1], 2) +
Math.pow(rgb2[2] - rgb1[2], 2)
);
}
// Class for converting RAL, HEX, and Names, and finding the closest color
class RALConverter {
// Convert RAL code to HEX
static ralToHex(ral) {
if (ralTable[ral]) {
return ralTable[ral].hex;
} else {
return { error: "RAL code not found." };
}
}
// Convert HEX to RAL and name
static hexToRal(hex) {
hex = normalizeHex(hex);
const rgb = hexToRgb(hex);
let closestRAL = null;
let minDistance = Infinity;
let closestName = null;
// Loop through each RAL entry and find the closest color
for (const [ralCode, data] of Object.entries(ralTable)) {
const distance = calculateDistance(rgb, data.rgb);
if (distance < minDistance) {
minDistance = distance;
closestRAL = ralCode;
closestName = data.name;
}
}
return {
ral: closestRAL,
name: closestName,
similarity: (100 - (minDistance / (Math.sqrt(3 * Math.pow(255, 2))) * 100)).toFixed(2) // Similarity percentage
};
}
// Convert RAL code to RAL name
static ralToName(ral) {
if (ralTable[ral]) {
return ralTable[ral].name;
} else {
return { error: "RAL code not found." };
}
}
// Convert HEX to RGB
static hexToRgb(hex) {
return hexToRgb(normalizeHex(hex));
}
}
// Attach the class to the global `window` object
window.RALConverter = RALConverter;
// Load the CSV data on page load
loadRALData();
// Find the closest RAL color and display in HTML
function findClosestRal() {
const hexValue = document.getElementById("hexInput").value;
const result = RALConverter.hexToRal(hexValue);
document.getElementById("closestRalResult").innerText =
result.error ? result.error :
`Closest RAL: ${result.ral}, Name: ${result.name}, Similarity: ${result.similarity}%`;
}
// Convert RAL to HEX and display in HTML
function convertRalToHex() {
const ralValue = document.getElementById("ralInput").value;
const result = RALConverter.ralToHex(ralValue);
document.getElementById("ralToHexResult").innerText =
result.error ? result.error : `HEX: ${result}`;
}