Skip to content

Instantly share code, notes, and snippets.

@chrisoverstreet
Created May 1, 2023 15:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisoverstreet/93aae33340e76f672722d269b7b30465 to your computer and use it in GitHub Desktop.
Save chrisoverstreet/93aae33340e76f672722d269b7b30465 to your computer and use it in GitHub Desktop.
import { z } from 'zod';
const DEFAULT_HEX_OPTIONS = ['#000000', '#FFFFFF'];
const hexColorSchema = z.string().regex(/^#[0-9A-F]{6}$/i);
// https://www.w3.org/TR/AERT/#color-contrast
export function bestContrastingColor(backgroundHexColor: string, ...hexOptions: string[]) {
hexColorSchema.parse(backgroundHexColor);
let bestColor = hexOptions[0] ?? DEFAULT_HEX_OPTIONS[0];
let largestColorDifference = 0;
(hexOptions.length ? hexOptions : DEFAULT_HEX_OPTIONS).forEach((hexOption) => {
hexColorSchema.parse(hexOption);
const colorDifference = calculateColorDifference(backgroundHexColor, hexOption);
if (colorDifference > largestColorDifference) {
largestColorDifference = colorDifference;
bestColor = hexOption;
}
});
return bestColor;
}
function calculateColorDifference(color1: string, color2: string) {
const red1 = parseInt(color1.substring(0, 2), 16);
const green1 = parseInt(color1.substring(2, 4), 16);
const blue1 = parseInt(color1.substring(4, 6), 16);
const red2 = parseInt(color2.substring(0, 2), 16);
const green2 = parseInt(color2.substring(2, 4), 16);
const blue2 = parseInt(color2.substring(4, 6), 16);
return (
Math.max(red1, red2) -
Math.min(red1, red2) +
(Math.max(green1, green2) - Math.min(green1, green2)) +
(Math.max(blue1, blue2) - Math.min(blue1, blue2))
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment