Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Expression to change color of a text based on background

Explorer ,
May 19, 2023 May 19, 2023

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!

TOPICS
Expressions , How to
3.7K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , May 19, 2023 May 19, 2023

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
...
Translate
Community Expert ,
May 19, 2023 May 19, 2023

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
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 19, 2023 May 19, 2023

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!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 19, 2023 May 19, 2023

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 19, 2023 May 19, 2023

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! 🙌🏻

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 19, 2023 May 19, 2023

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
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 22, 2023 May 22, 2023

This totally fixed my problem! Thank you so much for your time, Dan. Appreciate it 🙌🏻

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 20, 2023 May 20, 2023

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:

helped.jpg

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 22, 2023 May 22, 2023

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 22, 2023 May 22, 2023
LATEST

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]

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines