Skip to main content
ShiveringCactus
Community Expert
Community Expert
November 11, 2024
Question

Tutorial: bold part of a text layer using expressions

  • November 11, 2024
  • 3 replies
  • 2180 views

About a year ago, I shared a method for After Effects to allow you to add bold to part of a text layer using Text Animators. Trouble was, it was faking bold using rather than an actual bold font. But with After Effects 2025 and the new Per Character styling via expressions, you can now do it for real.

 

I break down how to use the new expression, then I add some slider controls to make it easier to adjust. And finally, I share my latest work in progress which allows to you select words instead of characters.

 

3 replies

Participant
January 16, 2025

Exciting subject, thanks guys!
What approach would you use to detect faux bold text, to instantly color it?

ShiveringCactus
Community Expert
Community Expert
January 17, 2025

You can chain expression setStyles together, so you can have setFont("FONT",20,30).setFillColor([1,0,0],20,30)

 

setFillColor uses RGB values (0-1) in an array, so [1,0,0] is pure red (100% red, 0% green, 0% blue).

 

Your question is throwing me slightly as you're asking about Faux Bold, for that I'd use Text Animators which is a separate way to achieve a very similar result that largely avoids expressions.  I made a much earlier video about that:

https://youtu.be/TuTcekuTbeY?si=Ge-L--KyhvPWaUrQ

Participant
January 17, 2025

Thanks.
My question was :
imagine you have a texfield, that you fill with a text, then on certains words you apply faux bold via the interface.

Is there a way to detect within this text the words that are in faux bold and then color them ?

Legend
November 11, 2024

Same thing, using lines as separators:

 

lineStart = Math.max(0, Math.floor(effect("Line Start")(1)) - 1);
numLines = Math.max(1, Math.floor(effect("Num Lines")(1)));

lines = value.split(/\r/);
selectedLines = lines.slice(lineStart, lineStart + numLines).join("\r");

regex = new RegExp(`(?:.*\r){${lineStart}}`);
m = regex.exec(value);
firstCharIndex = m ? m[0].length : 0;
selectedLength = selectedLines.length;

style
    .setFauxBold(true, firstCharIndex, selectedLength)
    .setFillColor([1, 0, 0], firstCharIndex, selectedLength);

 

 

 

 

 

ShiveringCactus
Community Expert
Community Expert
November 14, 2024

@Airweb_AE  thank you.  I've now updated my video to include your expression with several shout outs to you.

 

Legend
November 15, 2024

Even though I didn't understand everything you said in the video,

I have a feeling it's positive, so thank you! 😂

Legend
November 11, 2024

To avoid issues with occurrences,

I wouldn't have used indexOf()

wordStart = Math.max(0, Math.floor(effect("Word Start")(1)) -1);
numWords = Math.max(1, Math.floor(effect("Num Words")(1)));
words = split(/\s+/);
selectedWords = words.slice(wordStart, wordStart + numWords).join(" ");
regex = new RegExp(`(?:\\s*\\S+\\s*){${wordStart}}`);
m = regex.exec(value);
firstCharIndex = m ? m[0].length : 0;
selectedLength = selectedWords.length + 1;
style
    .setFauxBold(true,firstCharIndex,selectedLength)
    .setFillColor([1,0,0],firstCharIndex,selectedLength);

 

 

ShiveringCactus
Community Expert
Community Expert
November 11, 2024

Are you kidding me?   2 hours is all it took to come up with a better option???

 

Nice one.

 

I'm a little confused by what this part is doing:

regex = new RegExp(`(?:\\s*\\S+\\s*){${wordStart}}`);
m = regex.exec(value);
firstCharIndex = m ? m[0].length : 0;

I know RegExp + exec looks for a pattern and will find all of the options, but how does the third line then determine which one to show?

 

I'll happily post a follow up video crediting you and singing your praises @Airweb_AE , but I'd like to understand it myself.

Legend
November 11, 2024

The regex is used to count the number of characters before the selected word (based on wordStart value), which gives us the start of the character range (firstCharIndex).