373 lines
12 KiB
JavaScript
373 lines
12 KiB
JavaScript
let app = new Vue({
|
|
el: '#app',
|
|
|
|
data: {
|
|
defaultInputs: [
|
|
"ccc",
|
|
"#db2777aa",
|
|
"rgb(64, 240, 18)",
|
|
"hsla(240, 86.9%, 50.7%, 0.8)",
|
|
],
|
|
inputBox: "ccc\n#4f46e5\n#db2777aa\n",
|
|
|
|
hexRegex: /^\#?[a-f0-9]{3,9}/i,
|
|
rgbRegex: /^rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)/i,
|
|
rgbaRegex: /^rgba\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*(0(\.[0-9])?|1(\.0)?)\s*\)/i,
|
|
hslRegex: /^hsl\(\s*\d{1,3}\s*,\s*\d{1,3}(\.[0-9])?%\s*,\s*\d{1,3}(\.[0-9])?%\s*\)/i,
|
|
hslaRegex: /^hsla\(\s*\d{1,3}\s*,\s*\d{1,3}(\.[0-9])?%\s*,\s*\d{1,3}(\.[0-9])?%\s*,\s*(0(\.[0-9])?|1(\.0)?)\s*\)/i,
|
|
|
|
convertedColors: [],
|
|
},
|
|
|
|
beforeMount: function () {
|
|
this.inputBox = this.defaultInputs.join("\n");
|
|
},
|
|
|
|
mounted: function () {
|
|
this.batchConvert();
|
|
},
|
|
|
|
methods: {
|
|
batchConvert: function () {
|
|
this.convertedColors = [];
|
|
|
|
// first attempt to split by new-line characters
|
|
let inputArray = this.inputBox.split('\n');
|
|
let count = inputArray.length;
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
// check for empty line, non hex(a)/rgb(a)/hsl(a) string
|
|
let inputLine = inputArray[i].toLowerCase().trim();
|
|
if (inputLine.length === 0) {
|
|
continue;
|
|
}
|
|
|
|
let converted = {
|
|
error: false,
|
|
raw: inputLine,
|
|
hex: "",
|
|
rgb: "",
|
|
hsl: "",
|
|
};
|
|
|
|
if (this.hexRegex.test(inputLine)) {
|
|
let hexString = inputLine;
|
|
|
|
// doing this just to add pound symbol for the table output
|
|
// if it doesn't already exist and to allow the use of
|
|
// the hex value without leading pound symbol
|
|
// for conversion to other formats.
|
|
hexString = hexString.replace('#', '');
|
|
converted.hex = "#" + hexString;
|
|
|
|
// check if it has an alpha channel, and possibly shorthand
|
|
if (hexString.length === 4 || hexString.length === 8) {
|
|
rgb = this.hexaToRgba(hexString);
|
|
converted.rgb = "rgba(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ", " + rgb.alpha + ")";
|
|
|
|
hsl = this.rgbaToHsla(rgb.red, rgb.green, rgb.blue, rgb.alpha);
|
|
converted.hsl = "hsla(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%, " + hsl.alpha + ")";
|
|
} else {
|
|
rgb = this.hexToRgb(hexString);
|
|
converted.rgb = "rgb(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ")";
|
|
|
|
hsl = this.rgbToHsl(rgb.red, rgb.green, rgb.blue);
|
|
converted.hsl = "hsl(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%)";
|
|
}
|
|
}
|
|
|
|
if (this.rgbRegex.test(inputLine)) {
|
|
// extract the values for red, green, blue.
|
|
let rgbStrArray = inputLine.split(',');
|
|
let red = rgbStrArray[0].replace('rgb(', '').trim();
|
|
let green = rgbStrArray[1].trim();
|
|
let blue = rgbStrArray[2].replace(')', '').trim();
|
|
|
|
red = Number.parseInt(red);
|
|
green = Number.parseInt(green);
|
|
blue = Number.parseInt(blue);
|
|
|
|
converted.hex = "#" + this.rgbToHex(red, green, blue);
|
|
|
|
converted.rgb = "rgb(" + red + ", " + green + ", " + blue + ")";
|
|
|
|
let hsl = this.rgbToHsl(red, green, blue);
|
|
converted.hsl = converted.hsl = "hsl(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%)";
|
|
}
|
|
|
|
if (this.rgbaRegex.test(inputLine)) {
|
|
// extract the values for red, green, blue, alpha.
|
|
let rgbaStrArray = inputLine.split(',');
|
|
let red = rgbaStrArray[0].replace('rgba(', '').trim();
|
|
let green = rgbaStrArray[1].trim();
|
|
let blue = rgbaStrArray[2].trim();
|
|
let alpha = rgbaStrArray[3].replace(')', '').trim();
|
|
|
|
red = Number.parseInt(red);
|
|
green = Number.parseInt(green);
|
|
blue = Number.parseInt(blue);
|
|
|
|
converted.hex = "#" + this.rgbaToHexa(red, green, blue, alpha);
|
|
converted.rgb = "rgba(" + red + ", " + green + ", " + blue + ", " + alpha + ")";
|
|
|
|
let hsl = this.rgbToHsl(red, green, blue);
|
|
converted.hsl = "hsla(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%, " + alpha + ")";
|
|
}
|
|
|
|
if (this.hslRegex.test(inputLine)) {
|
|
// extract the values for hue, saturation, lightness.
|
|
let hslStrArray = inputLine.split(',');
|
|
let hue = hslStrArray[0].replace('hsl(', '').trim();
|
|
let saturation = hslStrArray[1].replace('%', '').trim();
|
|
let lightness = hslStrArray[2].replace('%', '').replace(')', '').trim();
|
|
|
|
converted.hex = "#" + this.hslToHex(hue, saturation, lightness);
|
|
|
|
let rgb = this.hslToRgb(hue, saturation, lightness);
|
|
converted.rgb = "rgb(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ")";
|
|
|
|
converted.hsl = "hsl(" + hue + ", " + saturation + "%, " + lightness + "%)";
|
|
}
|
|
|
|
if (this.hslaRegex.test(inputLine)) {
|
|
// extract the values for hue, saturation, lightness, alpha.
|
|
let hslaStrArray = inputLine.split(',');
|
|
let hue = hslaStrArray[0].replace('hsla(', '').trim();
|
|
let saturation = hslaStrArray[1].replace('%', '').trim();
|
|
let lightness = hslaStrArray[2].replace('%', '').trim();
|
|
let alpha = hslaStrArray[3].replace(')', '').trim();
|
|
|
|
converted.hex = "#" + this.hslaToHexa(hue, saturation, lightness, alpha);
|
|
|
|
let rgb = this.hslaToRgba(hue, saturation, lightness, alpha);
|
|
converted.rgb = "rgb(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ", " + alpha + ")";
|
|
|
|
converted.hsl = "hsla(" + hue + ", " + saturation + "%, " + lightness + "%, " + alpha + ")";
|
|
}
|
|
|
|
this.convertedColors.push(converted);
|
|
}
|
|
},
|
|
|
|
// hex -> RGB
|
|
hexToRgb: function (hexString) {
|
|
let hex = 'ffffff';
|
|
if (hexString.length === 3) {
|
|
hex = '';
|
|
hex += hexString.substr(2, 1) + hexString.substr(2, 1);
|
|
hex += hexString.substr(1, 1) + hexString.substr(1, 1);
|
|
hex += hexString.substr(0, 1) + hexString.substr(0, 1);
|
|
} else {
|
|
hex = hexString;
|
|
}
|
|
|
|
let bigint = Number.parseInt(hex, 16);
|
|
let r = (bigint >> 16) & 255;
|
|
let g = (bigint >> 8) & 255;
|
|
let b = bigint & 255;
|
|
|
|
return { "red": r, "green": g, "blue": b };
|
|
},
|
|
|
|
// hexa -> RGBa
|
|
hexaToRgba: function (hexString) {
|
|
let hex = 'ffffff';
|
|
let alphaHex = 'ff';
|
|
let alpha = 1;
|
|
|
|
if (hexString.length === 4) {
|
|
alphaHex = hexString.substr(3, 1) + hexString.substr(3, 1);
|
|
hex = '';
|
|
hex += hexString.substr(2, 1) + hexString.substr(2, 1);
|
|
hex += hexString.substr(1, 1) + hexString.substr(1, 1);
|
|
hex += hexString.substr(0, 1) + hexString.substr(0, 1);
|
|
} else {
|
|
alphaHex = hexString.substr(6, 2);
|
|
hex = hexString.substr(0, 6);
|
|
}
|
|
|
|
let rgb = this.hexToRgb(hex);
|
|
alpha = Number.parseFloat((Number.parseInt(alphaHex, 16) / 255)).toFixed(1);
|
|
|
|
return { "red": rgb.red, "green": rgb.green, "blue": rgb.blue, "alpha": alpha };
|
|
},
|
|
|
|
// hex -> HSL
|
|
hexToHsl: function (hexString) {
|
|
console.error('hex to HSL not implemented yet');
|
|
},
|
|
|
|
// hexa -> HSLa
|
|
hexaToHsla: function (hexString) {
|
|
console.error('hexa to HSLa not implemented yet');
|
|
},
|
|
|
|
// RGB -> hex
|
|
rgbToHex: function (r, g, b) {
|
|
let red = r.toString(16);
|
|
let green = g.toString(16);
|
|
let blue = b.toString(16);
|
|
|
|
if (red.length === 1) { red = "0" + red; }
|
|
if (green.length === 1) { green = "0" + green; }
|
|
if (blue.length === 1) { blue = "0" + blue; }
|
|
return "" + red + green + blue;
|
|
},
|
|
|
|
// RGBa -> hexa
|
|
rgbaToHexa: function (r, g, b, a) {
|
|
let hex = this.rgbToHex(r, g, b);
|
|
let alpha = Math.round(this.sanitizeAlphaFloat(a) * 255).toString(16);
|
|
if (alpha.length == 1) { alpha = "0" + alpha; }
|
|
return hex + alpha;
|
|
},
|
|
|
|
// RGB -> HSL
|
|
rgbToHsl: function (red, green, blue) {
|
|
let hue = 0, saturation = 0, lightness = 0;
|
|
|
|
let redFrac = Number.parseFloat(red / 255),
|
|
greenFrac = Number.parseFloat(green / 255),
|
|
blueFrac = Number.parseFloat(blue / 255);
|
|
|
|
let channelMin = Math.min(redFrac, blueFrac, greenFrac),
|
|
channelMax = Math.max(redFrac, blueFrac, greenFrac),
|
|
delta = channelMax - channelMin;
|
|
|
|
if (delta === 0) { hue = 0; }
|
|
// Red is the maximum color
|
|
else if (channelMax === redFrac) {
|
|
hue = ((greenFrac - blueFrac) / delta) % 6;
|
|
}
|
|
// Green is the maximum color
|
|
else if (channelMax === greenFrac) {
|
|
hue = (blueFrac - redFrac) / delta + 2;
|
|
}
|
|
// Green is the maximum color
|
|
else {
|
|
hue = (redFrac - greenFrac) / delta + 4;
|
|
}
|
|
|
|
hue = Math.round(hue * 60);
|
|
// Make negative hues positive behind 360°
|
|
if (hue < 0) { hue += 360; }
|
|
|
|
lightness = (channelMax + channelMin) / 2;
|
|
if (delta === 0) { saturation = 0; }
|
|
else { saturation = delta / (1 - Math.abs(2 * lightness - 1)); }
|
|
|
|
lightness = +(lightness * 100).toFixed(1);
|
|
saturation = +(saturation * 100).toFixed(1);
|
|
|
|
return { "hue": hue, "saturation": saturation, "lightness": lightness };
|
|
},
|
|
|
|
// RGBa -> HSLa
|
|
rgbaToHsla: function (r, g, b, al) {
|
|
let hsl = this.rgbToHsl(r, g, b);
|
|
hsl.alpha = this.sanitizeAlphaFloat(al);
|
|
return hsl;
|
|
},
|
|
|
|
// HSL -> hex
|
|
hslToHex: function (hue, saturation, lightness) {
|
|
let rgb = this.hslToRgb(hue, saturation, lightness);
|
|
let red = rgb.red.toString(16);
|
|
let green = rgb.green.toString(16);
|
|
let blue = rgb.blue.toString(16);
|
|
|
|
if (red.length === 1) { red = "0" + red; }
|
|
if (green.length === 1) { green = "0" + green; }
|
|
if (blue.length === 1) { blue = "0" + blue; }
|
|
|
|
return "" + red + green + blue;
|
|
},
|
|
|
|
// HSLa -> hexa
|
|
hslaToHexa: function (hue, saturation, lightness, alpha) {
|
|
let rgb = this.hslToRgb(hue, saturation, lightness);
|
|
let red = rgb.red.toString(16);
|
|
let green = rgb.green.toString(16);
|
|
let blue = rgb.blue.toString(16);
|
|
let alphaHex = Math.round(this.sanitizeAlphaFloat(alpha) * 255).toString(16);
|
|
|
|
if (red.length === 1) { red = "0" + red; }
|
|
if (green.length === 1) { green = "0" + green; }
|
|
if (blue.length === 1) { blue = "0" + blue; }
|
|
|
|
return "" + red + green + blue + alphaHex;
|
|
},
|
|
|
|
// HSL -> RGB
|
|
hslToRgb: function (hue, saturation, lightness) {
|
|
if (hue === 360) { hue = 0; }
|
|
if (hue < 0) { hue += 360; }
|
|
|
|
saturation /= 100;
|
|
lightness /= 100;
|
|
|
|
let chroma = (1 - Math.abs(2 * lightness - 1)) * saturation,
|
|
xComponent = chroma * (1 - Math.abs((hue / 60) % 2 - 1)),
|
|
lightnessMatch = lightness - (chroma / 2),
|
|
red = 0,
|
|
green = 0,
|
|
blue = 0;
|
|
|
|
// set red and green if hue between 0 and 119
|
|
if (0 <= hue && hue < 60) {
|
|
red = chroma;
|
|
green = xComponent;
|
|
} else if (60 <= hue && hue < 120) {
|
|
red = xComponent;
|
|
green = chroma;
|
|
}
|
|
// set green and blue if hue between 120 and 239
|
|
else if (120 <= hue && hue < 180) {
|
|
green = chroma;
|
|
blue = xComponent;
|
|
} else if (180 <= hue && hue < 240) {
|
|
green = xComponent;
|
|
blue = chroma;
|
|
}
|
|
// set red and blue if hue between 0 and 119
|
|
else if (240 <= hue && hue < 300) {
|
|
red = xComponent;
|
|
blue = chroma;
|
|
} else if (300 <= hue && hue < 360) {
|
|
red = chroma;
|
|
blue = xComponent;
|
|
}
|
|
|
|
red = Math.round((red + lightnessMatch) * 255);
|
|
green = Math.round((green + lightnessMatch) * 255);
|
|
blue = Math.round((blue + lightnessMatch) * 255);
|
|
|
|
return { "red": red, "green": green, "blue": blue };
|
|
},
|
|
|
|
// HSLa -> RGBa
|
|
hslaToRgba: function (hue, saturation, lightness, alpha) {
|
|
let rgb = this.hslToRgb(hue, saturation, lightness);
|
|
return { "red": rgb.red, "green": rgb.green, "blue": rgb.blue, "alpha": this.sanitizeAlphaFloat(alpha) };
|
|
},
|
|
|
|
// --------------------------------
|
|
// | helper methods
|
|
// --------------------------------
|
|
|
|
// Normalize the alpha to between 0.0 and 1.0
|
|
// return single decimal place float value
|
|
sanitizeAlphaFloat: function (alphaRaw) {
|
|
let alpha = Number.parseFloat(1);
|
|
|
|
if (alphaRaw >= 0 && alphaRaw <= 1) {
|
|
alpha = Number.parseFloat(alphaRaw);
|
|
} else if (alphaRaw < 0) {
|
|
alpha = Number.parseFloat(0);
|
|
}
|
|
|
|
return alpha.toFixed(1);
|
|
}
|
|
},
|
|
});
|