Skip to content

Instantly share code, notes, and snippets.

@BenMakesGames
Last active March 13, 2023 15:41
Show Gist options
  • Save BenMakesGames/48d38b1b22f926099c2f58b5d3e3302f to your computer and use it in GitHub Desktop.
Save BenMakesGames/48d38b1b22f926099c2f58b5d3e3302f to your computer and use it in GitHub Desktop.
Angular pipe that returns black if the given color is bright; white if it's dark. supports CSS vars.
// for Angular. a pipe that picks black if the given color is very bright, or white if it's dark. the
// threshhold and exact colors used are easily configured in the code; if you wanted to add them as
// parameters to this method, that modification should be easy enough (although for consistency in
// how you handle colors in your project, you might prefer not to give yourself the choice!)
//
// Buy Me a Coffee? :D https://ko-fi.com/A0A12KQ16
//
// example usage:
//
// <div [ngStyle]="{ 'background-color': someColor, 'color': someColor|contrastingColor }">...</div>
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'contrastingColor'
})
export class ContrastingColorPipe implements PipeTransform {
transform(value: string, args?: any): any {
let color = this.parseColor(value);
// humans perceive some colors to be brighter than others, ex: 255 green looks way brighter than 255 blue
let perceivedBrightness = color[0] * .299 + color[1] * .587 + color[2] * .114;
// I'm erring on the side of white text. THIS IS WHERE YOU'D CHANGE THE THRESHHOLD
if(perceivedBrightness < 255 * 2 / 3)
return 'var(--color-white)'; // AND THIS IS WHERE YOU'D CHANGE THE "WHITE" COLOR TO RETURN
else
return 'var(--color-black)'; // AND THE "BLACK" COLOR
}
parseColor(value: string): number[]
{
// if the value references a CSS var, get the underlying value of that var
// extra credit: do something more robust here, like accept white spaces. just be careful of regex DoS attacks.
if(value.match(/var\(--[^\)]+\)/))
{
value = value.substr(4, value.length - 5); // remove the var(...) wrapper
value = getComputedStyle(document.body).getPropertyValue(value).trim(); // it seems to end up with whitespace
}
// the following code came from https://stackoverflow.com/questions/11068240/what-is-the-most-efficient-way-to-parse-a-css-color-in-javascript
// #xxx
let m = value.match(/^#([0-9a-f]{3})$/i);
if(m) {
return [
parseInt(m[1].charAt(0),16)*0x11,
parseInt(m[1].charAt(1),16)*0x11,
parseInt(m[1].charAt(2),16)*0x11
];
}
// #xxxxxx
m = value.match(/^#([0-9a-f]{6})$/i);
if(m) {
return [
parseInt(m[1].substr(0,2),16),
parseInt(m[1].substr(2,2),16),
parseInt(m[1].substr(4,2),16)
];
}
// rgb(000, 000, 000)
let m2 = value.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
if(m2) {
return [
parseInt(m2[1]),
parseInt(m2[2]),
parseInt(m2[3])
];
}
return [ 0, 0, 0 ];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment