Last active
March 13, 2023 15:41
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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