Skip to main content
ShiveringCactus
Community Expert
Community Expert
September 12, 2026
Answered

Bake in Text Styling expression

  • September 12, 2026
  • 3 replies
  • 41 views

I’ve an interesting issue.  I have spent a bit of time recreating the look of AE’s expression editor as a Per Character styling expression.  It’s not complete yet, but serves my purposes… but the per-frame render time add 5s each frame.  And rendering out a 90 second sequence took 90 minutes.

 

I’m wondering if there’s a way to bake the expression styling once done.

 

Here’s the code if anyone wants to experiment:

///// HEX COLOR CONFIGURATION //////
var hexBase = "#D4D4D4"; // Off-white
var hexBlue = "#3E8FE1"; // Blue (Keywords)
var hexLtBlue = "#48D9FD"; // Light Blue (Numbers)
var hexPink = "#F67476"; // Pink (Strings)
var hexYellow = "#9D9039"; // Yellow (Brackets)
var hexLightYellow = "#DCBE84"; // Yellow (reserved terms)
var hexGreen = "#6A9955"; // Green (Comments)
var hexCursor = "#FFFFFF"; // White (Cursor)

///// Convert Hex to AE-friendly RGB [0,1]
function hexToRgb(hex) {
var r = parseInt(hex.slice(1, 3), 16) / 255;
var g = parseInt(hex.slice(3, 5), 16) / 255;
var b = parseInt(hex.slice(5, 7), 16) / 255;
return [r, g, b, 1];
}

//// TYPEWRITER & CURSOR LOGIC
var fullText = value;
var typeProgress = effect("Typewriter")("Slider");
var charCount = Math.floor(typeProgress);
var currentText = fullText.substring(0, charCount);

var cursorChar = "|";
const blinkSpeed = 2.5;
const isVisible = Math.floor(time * blinkSpeed) % 2 === 0;
if (effect("Show Cursor")("Checkbox") == 0) {
cursorChar = "";
}

//// Add cursor to the currently typed text
var finalDisplay = isVisible ? currentText + cursorChar : currentText + " ";

//// the Style object
var outText = createStyle().setText(finalDisplay).setFillColor(hexToRgb(hexBase));

//// Colour logic

// Blue Keywords
["var", "let", "const", "if", "Math", "continue", "push", "min", "sqrt", "else", "return", "function", "true", "false", "continue", "return", "length", "sin", "cos", "tan"].forEach(word => {
const regex = new RegExp(`\\b${word}\\b`, "g");
let m;
while ((m = regex.exec(currentText)) !== null) {
outText = outText.setFillColor(hexToRgb(hexBlue), m.index, word.length);
}
});



/// Yellow Brackets/Punctuation
const punctRegex = /[\[\]\{\}\(\)\=\<\>\\.\;]/g;
let p;
while ((p = punctRegex.exec(currentText)) !== null) {
outText = outText.setFillColor(hexToRgb(hexYellow), p.index, 1);
}
// Yellow Brackets/Punctuation
["thisComp", "layer", "isClosed", "inTangents", "createPath", "value", "outTangents", "frameDuration", "time", "effect", "thisProperty", "length", "linear","degreesToRadians"].forEach(word => {
const ReservedRegex = new RegExp(`\\b${word}\\b`, "g");
let r;
while ((r = ReservedRegex.exec(currentText)) !== null) {
outText = outText.setFillColor(hexToRgb(hexLightYellow), r.index, word.length);
}
});

/////// Pink Strings
const stringRegex = /"(.*?)"|'(.*?)'/g;
let s;
while ((s = stringRegex.exec(currentText)) !== null) {
outText = outText.setFillColor(hexToRgb(hexPink), s.index, s[0].length);
}

// Green Comments
const commentRegex = /\/\/.*/g;
let c;
while ((c = commentRegex.exec(currentText)) !== null) {
outText = outText.setFillColor(hexToRgb(hexGreen), c.index, c[0].length);
}

// Light Blue Numbers
const numRegex = /\d+/g;
let n;
while ((n = numRegex.exec(currentText)) !== null) {
outText = outText.setFillColor(hexToRgb(hexLtBlue), n.index, n[0].length);
}

////// style for cursor
if (isVisible) {
outText.setFillColor(hexToRgb(hexCursor), currentText.length, 1);
}

outText

 

​@Nishu Kushwaha - what’s the code style I should choose to make the forum code look like AE?  EDIT: Oh, it updates on saving.

    Correct answer David.Arbor

    Yup, this is definitely going to get slow because you’re constantly evaluating the text block as it reveals each new character. 

    If you want to bake the styling first, I would suggest splitting this on two layers and adding `posterizeTime(0);` to the first line, so the styling expression evaluates only one time (scrub the CTI before and after doing this and you’ll see a huge perf improvement.

    AE also ships with a preset called Blinking Cursor Typewriter Console which is almost perfect for what you need. By default, the preset works on a single text layer, and the way it reveals text won’t copy the styling, even if you reference an already styled text layer.

    However, I’ve attached a .aep where I modified the setup a bit.

    1. On the Blinking Cursor layer, I modified the expression to reference the SourceText layer.
    2. On the SourceText layer (the stylized one), I added an Opacity animator and linked its Offset parameter to the Blinking Cursor’s animation. This lets the stylized text reveal at the same rate you set for the preset.
    3. I added another Opacity animator to the Blinking Cursor layer and set it to 0%. This hides the plain text.

    So you’re left with two linked layers where one styles the text and the other animates the cursor. 

    Does this work for you?

     

    -David, After Effects Engineering Team 

    3 replies

    David.Arbor
    Community Manager
    David.ArborCommunity ManagerCorrect answer
    Community Manager
    September 30, 2026

    Yup, this is definitely going to get slow because you’re constantly evaluating the text block as it reveals each new character. 

    If you want to bake the styling first, I would suggest splitting this on two layers and adding `posterizeTime(0);` to the first line, so the styling expression evaluates only one time (scrub the CTI before and after doing this and you’ll see a huge perf improvement.

    AE also ships with a preset called Blinking Cursor Typewriter Console which is almost perfect for what you need. By default, the preset works on a single text layer, and the way it reveals text won’t copy the styling, even if you reference an already styled text layer.

    However, I’ve attached a .aep where I modified the setup a bit.

    1. On the Blinking Cursor layer, I modified the expression to reference the SourceText layer.
    2. On the SourceText layer (the stylized one), I added an Opacity animator and linked its Offset parameter to the Blinking Cursor’s animation. This lets the stylized text reveal at the same rate you set for the preset.
    3. I added another Opacity animator to the Blinking Cursor layer and set it to 0%. This hides the plain text.

    So you’re left with two linked layers where one styles the text and the other animates the cursor. 

    Does this work for you?

     

    -David, After Effects Engineering Team 

    ShiveringCactus
    Community Expert
    Community Expert
    October 1, 2026

    Oh that’s such an elegant solution ( posterizeTime(0); )

    I’m using v26 right now and the project you shared is v27, so I haven’t been able to try out the cursor blinking.  But I was able to use the opacity animator to achieve the same result.

    25 years+ (of using AE) and still learning.   Thank you.

     

     

    David.Arbor
    Community Manager
    Community Manager
    October 1, 2026

    Oops, sorry about that! I work in the beta all day long. For good measure, I’m uploading a 26.x version. But glad I was able to help!

    -David, After Effects Engineering Team