// Set up the hue slider. const slider = document.getElementById("hue-selector"); const output = document.getElementById("hue"); const box = document.getElementById("hue-box"); output.innerHTML = slider.value; // Display the default slider value // If we have a query parameter, select that. const urlParams = new URLSearchParams(window.location.search); const hueParam = urlParams.get("hue"); if (hueParam) { window.setTimeout(() => setHue(hueParam)); } // Update the current slider value (each time you drag the slider handle) slider.oninput = function () { setHue(this.value); }; window.setTimeout(() => update(), 250); // Color Theme var autoColorTheme = document.getElementById("auto-color-scheme"); var lightColorTheme = document.getElementById("light-color-scheme"); var darkColorTheme = document.getElementById("dark-color-scheme"); autoColorTheme.onclick = function () { document.documentElement.removeAttribute("data-prefers-color-scheme"); }; lightColorTheme.onclick = function () { document.documentElement.setAttribute("data-prefers-color-scheme", "light"); }; darkColorTheme.onclick = function () { document.documentElement.setAttribute("data-prefers-color-scheme", "dark"); }; // Prefers Contrast var autoContrast = document.getElementById("auto-contrast-selector"); var moreContrast = document.getElementById("more-contrast-selector"); var lessContrast = document.getElementById("less-contrast-selector"); autoContrast.onclick = function () { document.documentElement.removeAttribute("data-prefers-contrast"); }; moreContrast.onclick = function () { document.documentElement.setAttribute("data-prefers-contrast", "more"); }; lessContrast.onclick = function () { document.documentElement.setAttribute("data-prefers-contrast", "less"); }; // Translating colors. We use a canvas to paint the color and then get the // RGB from there for programs that need it (Inkscape and Gimp). // // https://stackoverflow.com/a/76469049 const canvas = document.createElement("canvas"); canvas.width = canvas.height = 1; const ctx = canvas.getContext("2d", { willReadFrequently: true }); function getRgb(style) { ctx.fillStyle = style; ctx.fillRect(0, 0, 1, 1); const colors = ctx.getImageData(0, 0, 1, 1).data; const r = colors[0].toString(16).padStart(2, "0").toLowerCase(); const g = colors[1].toString(16).padStart(2, "0").toLowerCase(); const b = colors[2].toString(16).padStart(2, "0").toLowerCase(); const channels = [colors[0], colors[1], colors[2]]; return [channels.join(" "), `#${r}${g}${b}`]; } /** * Implements a simple debounce function. * * @param func * @param {number} timeout * @returns */ function debounce(func, timeout = 300) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, timeout); }; } // Used to avoid hammering the CPU while we calculate colors. const update = debounce(_update); /** * Sets the hue slider to the given color. * * @param {string} hue */ function setHue(hue) { // Set the hue on the screen. console.log("setting hue", hue); document.documentElement.style.setProperty("--color-priduck-hue", hue); output.innerHTML = hue; update(); } /** * Updates all of the boxes and copy icons. */ function _update() { // Set the history URL. console.log("setting url"); const url = new URL(location); const hue = output.innerHTML; url.searchParams.set("hue", hue); history.pushState({}, "", url); // Update the controls. const range = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; for (const c of range) { for (const b of range) { const id = `c${c}b${b}`; const cb = document.getElementById(id); const style = window.getComputedStyle(cb, null); const lch = style["background-color"]; const [colors, rgb] = getRgb(lch); cb.innerHTML = `
${id}
${lch}
${rgb}
${rgb}ff
${colors}
`; } } }