a11y-theme-builder
a11y-theme-builder copied to clipboard
[SDK] update the light and dark mode generating process
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.