a11y-theme-builder icon indicating copy to clipboard operation
a11y-theme-builder copied to clipboard

[SDK] update the light and dark mode generating process

Open lwnoble opened this issue 1 year ago • 10 comments

Problem/Concern

  • link to problem content

Proposed Solution

Please use the following logic for building shades:

  • I simplified the process of creating the light and dark shades in order to get true 100-900 shades
  • if the shade (i) is 0 then I find the true (050) value
  • For darkmode I then I darken each color using the new function mixColors (see below)
     // build darker tones of color varients //
      function buildShades(mode, theme, color, shade) {
        var i = 0;
        var prime = shade
        var rgbArray = hextoRGBArray(color);
        // calculate how many light shades need to get built //
        var lightColors = (prime/100) + 1;
        // calculate how many dark shades need to get built //
        var darkColors = ((900-prime)/100) + 1
        console.log('shade:' + shade + ' lightColor: ' + lightColors + ' darkColors: ' + darkColors)
BEGIN NEW
        if (lightColors > 1)  {
          var lightscale  = chroma.scale([( '#FFFFFF') ,color]).correctLightness(true).colors(lightColors);
        } else {
END NEW
          lightscale = [color]
        }
BEGIN NEW
        if (darkColors > 1) {
          var endColor  = mixColors('#000000',color.toString(),.9);
          var darkscale = chroma.scale([color,endColor]).correctLightness(true).colors(darkColors);
        } else {
END NEW
          darkscale = [color]
        }
        if (lightscale.length > 0) {
          lightscale.splice(-1)
        }
        var colorScale = $.merge(lightscale, darkscale);

        console.log(colorScale)
        while (i < 10) {
          //var newRGB = adjustLightness(rgbArray,shade,lightness,mode)
BEGIN NEW
          if (i == 0) {
            var f = chroma.scale([( '#FFFFFF') ,color]);
            var scale = 100/(prime * 2)
            newRGB  = (f(scale)).toString();
          } else {
            var newRGB = colorScale [i]
            // adjust saturation of each color to create triangel effect - most saturated color are 600 and 700 //
            newRGB = triangle(color,i,prime, newRGB)
          }
END NEW
          var shade = i * 100
            if (getContrast(newRGB) == '#ffffff') {
              text_color = [255,255,255]; // white
            } else {
              text_color = [18,18,18]; // black
            }
            // get the contrast ration of the color against the suggested text color //
            var contrastRation = contrast(rgbArray, text_color); // 1.0736196319018405
            // convert the color to hex //
            newRGB = rgb2hex(newRGB)

            // based on the mode light or dark - run the appropriate check to see if the color and on color meet the contrats ratio of 4.5 or if the shade needs to be lighted or darked //
            if (mode == 'dark') {
BEGIN NEW
              newRGB = mixColors('#000000',newRGB,.15);
END NEW
              checkDM(theme+'-dark-'+shade, newRGB)
            } else {
              checkContrast(theme+'-'+mode+'-'+shade, newRGB, mode)
            }
            //
            // loop through each shade //
            i++;
        }
      }

I created this new function to mix two colors - one with an opacity to create an hex value.

    const mixColors = (c1, c2, opacity) => {
      const pn = n => ('0' + n.toString(16)).slice(-2);
        const [r0, g0, b0, r1, g1, b1] = [
        parseInt(c1.slice(1, 3), 16),
        parseInt(c1.slice(3, 5), 16),
        parseInt(c1.slice(5, 7), 16),
        parseInt(c2.slice(1, 3), 16),
        parseInt(c2.slice(3, 5), 16),
        parseInt(c2.slice(5, 7), 16),
      ];
        const [r, g, b] = [
        Math.round(r0 * opacity + r1 * (1 - opacity)),
        Math.round(g0 * opacity + g1 * (1 - opacity)),
        Math.round(b0 * opacity + b1 * (1 - opacity)),
      ];
      return `#${pn(r)}${pn(g)}${pn(b)}`;
    };

      // update saturation triangle - highest saturated shade at 6 //
      function triangle(color,i,prime, newRGB) {
      var primeHcl = chroma(color).hcl();
        var hcl = chroma(newRGB).hcl();
        prime = prime/100
        var change = i/prime
        if (i <= 6) {
          var change = i/prime
        } else {
          var change = (11 - i)/prime
        }
        var s = primeHcl[1]
        var newHCL = chroma.hcl(hcl[0], s * change, hcl[2]).hex();
        var s = primeHcl[1]
        var newHCL = chroma.hcl(hcl[0], s * change, hcl[2]).hex();
        return(newHCL)
      }

This creates a consistent scale of colors in both light and dark mode.

lwnoble avatar Sep 06 '23 20:09 lwnoble