Copy link to clipboard
Copied
Hi there!
I have this situation where I want to have a text that changes its color between white and black depending on the background shape layer. Let's say:
If background is yellow, text is black
If background is red, text is white
I'm pretty sure I could do it with an if/else statement, but I'm not sure how to make it work on After Effects.
Thank you!
In that case, if you know all the exact hex values, you could do something like this, where you check against a list of colors where you want white, and if it's not one of those you get black (same set up as before):
whites = [0x4266F5, 0xAD7DF9, 0x3B6F88, 0x2F8343, 0xA51A3D, 0xA10400, 0xEF464A];
function colorToHex(theColor){
var r = Math.round(theColor[0]*255);
var g = Math.round(theColor[1]*255);
var b = Math.round(theColor[2]*255);
return (r*65536 + g*256 + b)
}
bg = thisComp.layer
...
Copy link to clipboard
Copied
The trick is to figure out how to dectect yellow vs. red. One way, I guess, would be to check the value of the green channel. So you could create black text, add a Fill Color Animator and set it to white, and add something like this to the Amount property of the Range Selector:
bg = thisComp.layer("Background").content("Rectangle 1").content("Fill 1").color;
bg[1] > .25 ? 0 : 100
Copy link to clipboard
Copied
Hi Dan!
I tried that and it is indeed working! What I see is that in order to define a bit better which colors make the text white or black, I have to manipulate de .25 part, isn't it?
Thank you so much!
Copy link to clipboard
Copied
Yes, when you pick up the background color, you end up with the red, green, and blue channel values as floating point values between 0.0 and 1.0. So it can get tricky if you're looking for an exact hex value, for example. In the red vs. yellow example, I picked .25 for the green channel because red wouldn't have much (if any) green, but .5 might be better, because that would be half way between pure red and pure yellow. But if you're looking for a specific hex value, you might need a more complex expression that checks for a small range of values within each color channel. I could probably give you a better answer if you have a specific example in mind.
Copy link to clipboard
Copied
Down below you can find the HEX values I am using and the color that the text should be.
#4266F5 - White
#AD7DF9 - White
#3B6F88 - White
#2F8343 - White
#A51A3D - White
#A10400 - White
#EF464A - White
#77A8FA - Black
#FF6F3C - Black
#FF9A33 - Black
#FFC41F - Black
#91C949 - Black
#36C188 - Black
#64CEE1 - Black
Thing is that, with the expression you already wrote but using 0.52 instead, all background colors match with their text color except of #FF6F3C, which is White instead of Black.
bg = thisComp.layer("Pill").content("Rectangle 1").content("Fill 1").color;
bg[1] > .52 ? 0 : 100
I'm not sure if something like "if color is (all the HEX Values that need to have white text), text = white // else = black" could be done in this situation 🧐
Thank you for your time, Dan! 🙌🏻
Copy link to clipboard
Copied
In that case, if you know all the exact hex values, you could do something like this, where you check against a list of colors where you want white, and if it's not one of those you get black (same set up as before):
whites = [0x4266F5, 0xAD7DF9, 0x3B6F88, 0x2F8343, 0xA51A3D, 0xA10400, 0xEF464A];
function colorToHex(theColor){
var r = Math.round(theColor[0]*255);
var g = Math.round(theColor[1]*255);
var b = Math.round(theColor[2]*255);
return (r*65536 + g*256 + b)
}
bg = thisComp.layer("Background").content("Rectangle 1").content("Fill 1").color;
hexColor = colorToHex(bg);
white = false;
for (i = 0; i < whites.length; i++){
if (hexColor == whites[i]){
white = true;
break;
}
}
white ? 100 : 0
Copy link to clipboard
Copied
This totally fixed my problem! Thank you so much for your time, Dan. Appreciate it 🙌🏻
Copy link to clipboard
Copied
While you can use an Expression and I see Dan has provided one, you don't need to do anything as complicated. You can do exactly what you're asking by using a transfer mode.
Use White Text and a White shape with a white background but set the text's and shape's tranfer mode to Difference. You can then use an adjustment layer to change the background colours and a second one with it's track matte set to the text to change the colours of the text:
Copy link to clipboard
Copied
Hi ShiveringCactus!
Appreciate your answer, I'll make sure to give it a try whenever I have to go through the same issue again. In this case, I was looking for an expression as it's not for a project of mine, but a MOGRT.
I wanted to turn this into a MOGRT so editors can use it without overcomplicating their workflow and having to explain new things for every new asset, even though maybe this overcomplicated my process a bit, but that's my job I guess haha
Copy link to clipboard
Copied
I have done similar things by using the Luminance value of the sampled background to switch fill colors. I convert the RGBA sample you get from sampleImage(point) to HSL, then just query the 3rd variable in the generated array. You could do the same with Hue if you like. It might simplify things if you knew a hue range.
Here's a simple expression that changes from white to gray when the background sample layer gets darker.
ref = thisComp.layer("Sample Me");
s = ref.sampleImage([960, 540]);
l = rgbToHsl(s);
if (l[2] < .5)
[1, 1, 1, 1]
else
[.3, .3, .3, 1]