sourcehypertextpublictoastershadershader.js

let colourCount = 0;

const parseHex = rawHex => {
	const hex = rawHex.match(/[0-9a-fA-F]{6}/)[0];

	return [0, 2, 4].map(digit => parseInt(hex.slice(digit, digit + 2), 16));
};

const writeHex = shade =>
	`#${shade
		.map(c => c.toString(16).padStart(2, "0").toUpperCase())
		.join("")}`;

const writeRgb = shade => `rgb(${shade.join(", ")})`;

const darken = (shade, factor) => {
	return shade.map(c =>
		round((c / 255) ** (1 + factor * 0.4) * 255 * 0.75 ** factor)
	);
};

const lighten = (shade, factor) => {
	return shade.map(c =>
		round(255 * (1 - (1 - c / 255) ** (1 + factor * 0.4) * 0.75 ** factor))
	);
};

const textColour = (red, blue, green) => {
	const luminance = (0.2126 * red + 0.7152 * green + 0.0722 * blue) / 255;

	if (luminance < 0.5) {
		return "light-text";
	}
	return "dark-text";
};

const chip = (shade, text = "", forbidden = false) => {
	return `<li class="${textColour(...shade)}${forbidden ? " forbidden" : ""}">
	<span class="chip hex-chip" style="background-color: ${writeHex(
		shade
	)};">${writeHex(shade)}</span>
	<span class="chip rgb-chip" style="background-color: ${writeHex(
		shade
	)};">${writeRgb(shade)}</span>
	${text}
	</li>`;
};

const toggleForbidden = () => {
	$("html").dataset.forbidden =
		$("html").dataset.forbidden == "shown" ? "hidden" : "shown";
};

const toggleChipStyle = () => {
	$("html").dataset.chip = $("html").dataset.chip == "rgb" ? "hex" : "rgb";
};

const addColour = () => {
	const colour = parseHex($("#hexform").value);
	if (!colour) return;

	const shades = [
		lighten(colour, 3),
		lighten(colour, 2),
		lighten(colour, 1),
		colour,
		darken(colour, 1),
		darken(colour, 2),
		darken(colour, 3)
	];

	$("#toasttable").innerHTML += `<tr>
		<td class="forbidden" style="width: 5px; background-color: ${writeHex(
			shades[0]
		)};"></td>
		<td style="width: 7px; background-color: ${writeHex(shades[1])};"></td>
		<td style="width: 10px; background-color: ${writeHex(shades[2])};"></td>
		<td style="width: 14px; background-color: ${writeHex(shades[3])};"></td>
		<td style="width: 10px; background-color: ${writeHex(shades[4])};"></td>
		<td style="width: 7px; background-color: ${writeHex(shades[5])};"></td>
		<td class="forbidden" style="width: 5px; background-color: ${writeHex(
			shades[6]
		)};"></td>
		<td style="width: 351px; background-color: ${writeHex(shades[0])};"></td>
	</tr>`;

	colourCount += 1;

	$("#toastlist").innerHTML += `<b>Colour #${colourCount}</b>
	<ul>
		${chip(shades[0], "Lightestest (<i>forbidden</i>)", true)}
		${chip(shades[1], "Lightest")}
		${chip(shades[2], "Lighter")}
		${chip(shades[3], "<b>Base colour</b>")}
		${chip(shades[4], "Darker")}
		${chip(shades[5], "Darkest")}
		${chip(shades[6], "Darkestest (<i>forbidden</i>)", true)}
	</ul>`;
};