Color equivalency calculator
This Javascript file has three different calculations for color equivalency. These can be helpful if you want a color to have the optical appearance as a specific color when semi-transparent.
matchAlphaByColor
returns an alpha value (0-1) to match colorToMatch
relative to backgroundColor. This is most reliable with grayscale, it tends to be somewhat unreliable for colors w/ any significant saturation.
matchColorAtAlpha
returns the color at alpha
opacity that matches colorToMatch
set on backgroundColor
getRGBforTransparentColor
returns the RGB value at 100% opacity to match colorToMatch
at colorToMatchAlpha
opacity set on backgroundColor
Instructions
Copy the code below into a file on your machine. Let’s name it colors.js
Install Node.js
Edit BACKGROUND_COLOR
, COLOR_TO_MATCH
and COLOR_TO_CHANGE
to fit your needs
Fire up a Terminal window and cd
to the directory where you saved the colors.js
file
Run node colors.js
in your terminal
Read out the results returned in the terminal
/*
* Change these variables for your specific needs
*/
const BACKGROUND_COLOR = {r: 34, g: 114, b: 37}
const COLOR_TO_MATCH = {r: 46, g: 153, b: 50}
const COLOR_TO_CHANGE = {r: 126, g: 216, b: 129}
/*
* Returns the alpha of `colorToChange` to match colorToMatch relative to `backgroundColor`
* This is most reliable with grayscale, it tends to be somewhat unreliable for colors w/ any significant saturation
*/
function matchAlphaByColor(backgroundColor, colorToMatch, colorToChange) {
let alphaR = (colorToMatch.r-backgroundColor.r) / (colorToChange.r-backgroundColor.r)
let alphaG = (colorToMatch.g-backgroundColor.g) / (colorToChange.g-backgroundColor.g)
let alphaB = (colorToMatch.b-backgroundColor.b) / (colorToChange.b-backgroundColor.b)
alphaR = isNaN(alphaR) ? 0 : alphaR
alphaG = isNaN(alphaG) ? 0 : alphaG
alphaB = isNaN(alphaB) ? 0 : alphaB
let blendR = (colorToChange.r/(colorToChange.r+colorToChange.g+colorToChange.b) + backgroundColor.r/(backgroundColor.r+backgroundColor.g+backgroundColor.b))/2
let blendG = (colorToChange.g/(colorToChange.r+colorToChange.g+colorToChange.b) + backgroundColor.g/(backgroundColor.r+backgroundColor.g+backgroundColor.b))/2
let blendB = (colorToChange.b/(colorToChange.r+colorToChange.g+colorToChange.b) + backgroundColor.b/(backgroundColor.r+backgroundColor.g+backgroundColor.b))/2
alphaR *= blendR
alphaG *= blendG
alphaB *= blendB
return alphaR + alphaG + alphaB;;
}
/*
* Returns the color at `alpha` opacity that matches `colorToMatch` set on `backgroundColor`
*/
function matchColorAtAlpha(backgroundColor, colorToMatch, alpha) {
let r = (colorToMatch.r - backgroundColor.r + backgroundColor.r*alpha)/alpha
let g = (colorToMatch.g - backgroundColor.g + backgroundColor.g*alpha)/alpha
let b = (colorToMatch.b - backgroundColor.b + backgroundColor.b*alpha)/alpha
return {r:r, g:g, b:b, a:alpha}
}
/*
* Returns the RGB value at 100% opacity to match `colorToMatch` at `colorToMatchAlpha` opacity set on `backgroundColor`
*/
function matchTransparentColor(backgroundColor, colorToMatch, colorToMatchAlpha) {
let r = ((colorToMatch.r - backgroundColor.r)*colorToMatchAlpha + backgroundColor.r)
let g = ((colorToMatch.g - backgroundColor.g)*colorToMatchAlpha + backgroundColor.g)
let b = ((colorToMatch.b - backgroundColor.b)*colorToMatchAlpha + backgroundColor.b)
return {r:r, g:g, b:b}
}
console.log('Matching alpha for ' + COLOR_TO_MATCH.r + ', ' + COLOR_TO_MATCH.g + ', ' + COLOR_TO_MATCH.b + ' set on ' + BACKGROUND_COLOR.r + ', ' + BACKGROUND_COLOR.g + ', ' + BACKGROUND_COLOR.g + ':', matchAlphaByColor(BACKGROUND_COLOR, COLOR_TO_MATCH, COLOR_TO_CHANGE))
console.log('\n------------------\n');
console.log('Matching color for ' + COLOR_TO_MATCH.r + ', ' + COLOR_TO_MATCH.g + ', ' + COLOR_TO_MATCH.b + ' set on ' + BACKGROUND_COLOR.r + ', ' + BACKGROUND_COLOR.g + ', ' + BACKGROUND_COLOR.g + ' at 75% opacity:', matchColorAtAlpha(BACKGROUND_COLOR, COLOR_TO_MATCH, .75))
console.log('\n');
console.log('Matching color for ' + COLOR_TO_MATCH.r + ', ' + COLOR_TO_MATCH.g + ', ' + COLOR_TO_MATCH.b + ' set on ' + BACKGROUND_COLOR.r + ', ' + BACKGROUND_COLOR.g + ', ' + BACKGROUND_COLOR.g + ' at 50% opacity:', matchColorAtAlpha(BACKGROUND_COLOR, COLOR_TO_MATCH, .5))
console.log('\n------------------\n');
console.log('Matching color for ' + COLOR_TO_MATCH.r + ', ' + COLOR_TO_MATCH.g + ', ' + COLOR_TO_MATCH.b + ' at 75% opacity set on ' + BACKGROUND_COLOR.r + ', ' + BACKGROUND_COLOR.g + ', ' + BACKGROUND_COLOR.g + ':', matchTransparentColor(BACKGROUND_COLOR, COLOR_TO_MATCH, .75))
console.log('\n');
console.log('Matching color for ' + COLOR_TO_MATCH.r + ', ' + COLOR_TO_MATCH.g + ', ' + COLOR_TO_MATCH.b + ' at 50% opacity set on ' + BACKGROUND_COLOR.r + ', ' + BACKGROUND_COLOR.g + ', ' + BACKGROUND_COLOR.g + ':', matchTransparentColor(BACKGROUND_COLOR, COLOR_TO_MATCH, .50))