massi-world

this website of mine
Log | Files | Refs

swatchbuckler.ts (3377B)


      1 import * as d3 from "d3-color";
      2 
      3 const INC = 0.4;
      4 const RANGE = 4.1;
      5 
      6 // copied from https://gist.github.com/jfsiii/5641126
      7 //// from http://www.w3.org/TR/WCAG20/#relativeluminancedef
      8 function luminance({ r, g, b }) {
      9   var RsRGB = r / 255;
     10   var GsRGB = g / 255;
     11   var BsRGB = b / 255;
     12 
     13   var R =
     14     RsRGB <= 0.03928 ? RsRGB / 12.92 : Math.pow((RsRGB + 0.055) / 1.055, 2.4);
     15   var G =
     16     GsRGB <= 0.03928 ? GsRGB / 12.92 : Math.pow((GsRGB + 0.055) / 1.055, 2.4);
     17   var B =
     18     BsRGB <= 0.03928 ? BsRGB / 12.92 : Math.pow((BsRGB + 0.055) / 1.055, 2.4);
     19 
     20   // For the sRGB colorspace, the relative luminance of a color is defined as:
     21   var L = 0.2126 * R + 0.7152 * G + 0.0722 * B;
     22   return L;
     23 }
     24 
     25 function contrast(lumA: number, lumB: number) {
     26   if (lumA < lumB) {
     27     let tmp = lumA;
     28     lumA = lumB;
     29     lumB = tmp;
     30   }
     31   return (lumA + 0.05) / (lumB + 0.05);
     32 }
     33 
     34 function makeCssVariables(colors: string[]) {
     35   return colors.map((c, idx) => `--mono-tint-${idx}: ${c};`).join("\n");
     36 }
     37 
     38 function makeColors() {
     39   const parentEl = document.getElementById("renderzone") as HTMLDivElement;
     40   const colorEl = document.getElementById("midcolor") as HTMLInputElement;
     41   const midColor = d3.lch(colorEl.value);
     42   const minContrast = Number(
     43     (document.getElementById("mincontrast") as HTMLInputElement).value,
     44   );
     45   const heading = (document.getElementById("msg") as HTMLInputElement).value;
     46 
     47   if (Number.isNaN(midColor.h)) {
     48     colorEl.style.background = "salmon";
     49     function handlePress() {
     50       colorEl.style.background = "white";
     51     }
     52     colorEl.addEventListener("keydown", handlePress, { once: true });
     53     return;
     54   }
     55 
     56   parentEl.innerHTML = "";
     57 
     58   const tints = [];
     59   for (let i = -1 * RANGE; i <= RANGE; i += INC) {
     60     const bg = d3.lch(midColor).brighter(i).formatHex();
     61     if (bg == "#000000" || bg == "#ffffff") {
     62       continue;
     63     }
     64     const bgLum = luminance(d3.rgb(bg));
     65     const sign = bgLum > 0.5 ? 1 : -1;
     66 
     67     tints.push(bg);
     68 
     69     for (let j = sign * -1 * RANGE; sign * j <= RANGE; j += sign * INC) {
     70       const fg = d3.lch(midColor).brighter(j).formatHex();
     71       const swatchContrast = contrast(luminance(d3.rgb(fg)), bgLum);
     72       if (fg == "#000000" || fg == "#ffffff" || swatchContrast < minContrast) {
     73         continue;
     74       }
     75       const el = document.createElement("div");
     76       el.classList.add("renderblock", "rounded");
     77       el.style.backgroundColor = bg;
     78       el.style.color = fg;
     79       el.innerHTML = `<h1>${heading}</h1>
     80                         <h2>bg: ${bg}</h2>
     81                         <h3>fg: ${fg}</h3>
     82                         <p>contrast ratio: ${swatchContrast.toPrecision(4)}</p>`;
     83       const b = document.createElement("button");
     84       b.innerText = "copy css";
     85       b.style.color = bg;
     86       b.style.backgroundColor = fg;
     87       b.addEventListener("click", () => {
     88         navigator.clipboard.writeText(
     89           `background-color: ${bg};\ncolor: ${fg};`,
     90         );
     91       });
     92       el.appendChild(b);
     93       parentEl.appendChild(el);
     94     }
     95   }
     96 
     97   console.log(makeCssVariables(tints));
     98 }
     99 
    100 document.addEventListener("DOMContentLoaded", () => {
    101   makeColors();
    102   document.addEventListener("keypress", (e) => {
    103     if (e.keyCode === 13) {
    104       makeColors();
    105     }
    106   });
    107   const buttonEl = document.getElementById("thebutton") as HTMLButtonElement;
    108   buttonEl.addEventListener("click", () => {
    109     makeColors();
    110   });
    111 });