I know this has been asked before, but I need a little more help than the other answers on SO provide.
I currently have a foreach loop that iterates over records in my DB. Each row contains a unique "id" primary attribute (1,2,3,4,5,etc.).
In my loop, I need to generate a UNIQUE RGB value for each record based on its ID. The resulting RGB value will be applied to the HTML element's text bound to that record. The generated color must be unique to the record itself (via "id"), which is why I am not using the loop iterator.
I have already created a working function to do this for me, but I need one more thing - I need the rgb value to have a contrast ratio greater than 4:5:1 on a white background. The function I have generates colors that are too bright, making the text hard to read. How can I modify my function to produce darker colors that contrast well on a white background?
function makeRgbFromValue(int $value){
$hash = md5($value);
return implode(", ", [
hexdec(substr($hash, 0, 2)), // r
hexdec(substr($hash, 2, 2)), // g
hexdec(substr($hash, 4, 2)) // b
]);
}
// Example output: "100, 201, 20"
// My html, using Laravel Blade syntax:
@foreach($categories as $cat)
<a
href="/blog/channels/{{ $cat->slug }}"
style="color: rgb(
{{ makeRgbFromValue($cat->id) }}
)"
>
{{ $cat->name }}
</a>
@endforeach
Maybe this isnt possible... but I'm hoping one of you Math geniuses can help me out :)
You can calculate brightness:
function lumdiff($R1,$G1,$B1,$R2,$G2,$B2){
$L1 = 0.2126 * pow($R1/255, 2.2) +
0.7152 * pow($G1/255, 2.2) +
0.0722 * pow($B1/255, 2.2);
$L2 = 0.2126 * pow($R2/255, 2.2) +
0.7152 * pow($G2/255, 2.2) +
0.0722 * pow($B2/255, 2.2);
if($L1 > $L2){
return ($L1+0.05) / ($L2+0.05);
}else{
return ($L2+0.05) / ($L1+0.05);
}
}
The returned value should be bigger than 5 for best readability. Function was found here
But you should get another chars from a hash to get another color, so collision more probable.
function makeRgbFromValue($value){
$hash = md5($value);
$brightness = 0;
$shift = 0;
while($brightness < 5 && $shift<26) {
$color = [
hexdec(substr($hash, $shift, 2)), // r
hexdec(substr($hash, $shift+2, 2)), // g
hexdec(substr($hash, $shift+4, 2)) // b
];
$brightness = lumdiff($color[0], $color[1], $color[2], 255,255,255);
$shift++;
}
return implode(", ", $color);
}
I believe that a color will be found in 25 cycles :)
While it's a pain to translate, HSV is probably a better color space for this. I like to pick a set Saturation [0.75 is nice] and then play with the Hue and Value.
Lifting the HSV/RGB conversion function from this gist:
function HSV_TO_RGB ($H, $S, $V) {
$RGB = array();
if($S == 0) {
$R = $G = $B = $V * 255;
} else {
$var_H = $H * 6;
$var_i = floor( $var_H );
$var_1 = $V * ( 1 - $S );
$var_2 = $V * ( 1 - $S * ( $var_H - $var_i ) );
$var_3 = $V * ( 1 - $S * (1 - ( $var_H - $var_i ) ) );
if ($var_i == 0) { $var_R = $V ; $var_G = $var_3 ; $var_B = $var_1 ; }
else if ($var_i == 1) { $var_R = $var_2 ; $var_G = $V ; $var_B = $var_1 ; }
else if ($var_i == 2) { $var_R = $var_1 ; $var_G = $V ; $var_B = $var_3 ; }
else if ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2 ; $var_B = $V ; }
else if ($var_i == 4) { $var_R = $var_3 ; $var_G = $var_1 ; $var_B = $V ; }
else { $var_R = $V ; $var_G = $var_1 ; $var_B = $var_2 ; }
$R = $var_R * 255;
$G = $var_G * 255;
$B = $var_B * 255;
}
$RGB['R'] = $R;
$RGB['G'] = $G;
$RGB['B'] = $B;
return $RGB;
}
And then:
$fmt = '<span style="background-color: #%s" title="%s">%s</span>' . "\n";
$fill = str_repeat(' ', 5);
$S = 0.75;
for($i=0; $i<25; $i++) {
$hash = md5(mt_rand());
$H = hexdec(substr($hash, 0, 2))/255;
$V = ( hexdec(substr($hash, 2, 2))/255 ) / 2 + 0.5; // pick from the brighter half
$rgb = implode('', array_map(
function($a){
return str_pad(dechex(intval($a)), 2, '0', STR_PAD_LEFT);
}, HSV_TO_RGB($H, $S, $V)));
printf($fmt, $rgb, sprintf("HSV(%0.2f,%0.2f,%0.2f)", $H, $S, $V), $fill);
}
Gives us something like:
Firebase Cloud Functions: PubSub, "res.on is not a function"
TypeError: Cannot read properties of undefined (reading 'createMessageComponentCollector')
You need to provide consent for the application to access your Bing Ads accountsCopy and paste this authorization endpoint into a web browser and sign in with a Microsoft account with access to a Bing Ads account: https://login
I am trying to generate a table of user input data to SQL database to be generated into table, placed into PDF file and sent as an attachment to with an email
I'm trying to get the name value from this promise from firebase firestore database:
Sorry for the vague title, but I'm not exactly sure what to call thisI'm making an assignment planner using HTML and JavaScript, and I've ran into a bit of a problem while trying to make a feature to snap your text to the nearest line