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

How do text layer expression selectors operate on character value?

Enthusiast ,
Apr 16, 2009 Apr 16, 2009

Copy link to clipboard

Copied

I'm banging my head against my desk here.  Every other attribute I try to animate using expressions selectors works by multiplying the value returned by the selector by the value of the property in question.  But I can't make heads or tails of what an expression selector does to either Character Value or Character Offset properties.

Has anyone had any luck with these?

I'm just trying to transcribe the characters from one text layer into another using the expression:

MT = thisComp.layer("Master Text").text.sourceText;

if(textIndex < MT.length) MT.charCodeAt(textIndex) else 32

I set my character value to 1, and left the Amount property set to [100,100,100] thinking the value coming out of my expression would be multiplied by 1.  Instead, the results I get are nonsensical.  Is there something obvious that I'm missing?

TOPICS
Expressions

Views

12.6K

Translate

Translate

Report

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 , Apr 17, 2009 Apr 17, 2009

It is hard to wrap your head around. Try this. create a text layer containing the string "246".

Add an animator for Character Value and set the Character Value property to 56 (decimal ASCII for "8"). All the digits should change to 8.

Add an expression selector and delete the range selector.

Delete (or comment out) the defalut expression in the Amount parameter and replace it with this:

0

You should be back to the original string because the expression is telling AE to go 0% of the way from each exis

...

Votes

Translate

Translate
Community Expert ,
Apr 17, 2009 Apr 17, 2009

Copy link to clipboard

Copied

It is hard to wrap your head around. Try this. create a text layer containing the string "246".

Add an animator for Character Value and set the Character Value property to 56 (decimal ASCII for "8"). All the digits should change to 8.

Add an expression selector and delete the range selector.

Delete (or comment out) the defalut expression in the Amount parameter and replace it with this:

0

You should be back to the original string because the expression is telling AE to go 0% of the way from each existing character ("2","4",and "6") to the target character ("8").

Change the expression from 0 to 50. Now each character should be halfway from the original to "8", resulting in the string "567".

Change the expression to 100, and as you would expect, each character is transformed 100% of the way to the target character, resulting in "888".

I hope that helps.

Dan

Votes

Translate

Translate

Report

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
Enthusiast ,
Apr 17, 2009 Apr 17, 2009

Copy link to clipboard

Copied

Rock on, Dan!

That's exactly the explanation I needed.  How on earth did you figure that out?

Anyway, thanks to you I managed to get exactly what I want using the following method:

I have two text layers, Master Text Layer and Slave Text Layer.  The master will determine what characters are ultimately displayed in the slave layer.  In the slave layer I place enough null characters (character code 0) to equal or exceed the length any text that might be put in the master layer.

To the slave text layer I apply a text animator named "Transcription" which contains the Character Value property and an Expression Selector.  I set the Character Value to 65535 (the maximum possible value), set the Character Alignment to "Adjust Kerning", and in the Amount expression I use the following code:

MT = thisComp.layer("Master Text Layer").text.sourceText;

ST = text.sourceText;

if(textIndex < ST.length) STCode = ST.charCodeAt(textIndex) else STCode = 0;

if(textIndex <= MT.length) MTCode = MT.charCodeAt(textIndex-1) else MTCode = 0;

linear(MTCode, STCode, text.animator("Transcription").property.characterValue, 0, 100)

And it works!

What this allows me to do is to drive the text of the slave layer with the text of the master layer but to maintain the formatting properties of the slave layer.  This is impossible to do with simple sourceText expressions, since the expression-modified text would simply adopt the character attributes of the first character.

Obviously this should only be used on short bits of text, since the expression is evaluated once per character, but that suits my purposes just fine.

You're a lifesaver, Dan.

Votes

Translate

Translate

Report

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 ,
Apr 17, 2009 Apr 17, 2009

Copy link to clipboard

Copied

That's very clever. I think I learned as much as you did. Thanks!

Dan

Votes

Translate

Translate

Report

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
Enthusiast ,
Apr 17, 2009 Apr 17, 2009

Copy link to clipboard

Copied

You know, I think what really tripped me up about the expression selector is that although the expression modifies the Amount property, the interface doesn't acknowledge this as it would with other properties.  I can understand why the Adobe team chose to do it this way – they didn't want to give the impression that the expression applied on a per-frame basis when it actually applies on a per-character basis – but without that feedback it didn't really click that what I was dealing with was a 0-100 range of outputs.

Edit:  It occurs to me that it's actually a -100 to 100 range, not 0 to 100.

Votes

Translate

Translate

Report

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
Apr 17, 2009 Apr 17, 2009

Copy link to clipboard

Copied

That's a terrific hack, Aaron.

Wanna add a comment to the "Text selectors" section of After Effects Help so others who are reading the documentation can benefit from this?

Votes

Translate

Translate

Report

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
Enthusiast ,
Apr 17, 2009 Apr 17, 2009

Copy link to clipboard

Copied

I was just thinking about doing that.  It's late right now, but I'll try to find a few minutes this weekend to add a comment there.

Votes

Translate

Translate

Report

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
Enthusiast ,
Apr 18, 2009 Apr 18, 2009

Copy link to clipboard

Copied

Okay, done.  I hope the explanation is at least marginally coherent.

Votes

Translate

Translate

Report

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
Advisor ,
Apr 20, 2009 Apr 20, 2009

Copy link to clipboard

Copied

WIld. Positively wild.

*head explodes*

Votes

Translate

Translate

Report

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
Enthusiast ,
Apr 20, 2009 Apr 20, 2009

Copy link to clipboard

Copied

I've refined the code for the expression a bit:

MT = thisComp.layer("Master Text Layer").text.sourceText;

ST = text.sourceText;

if(textIndex < ST.length) STCode = ST.charCodeAt(textIndex) else STCode = 0;

if(textIndex <= MT.length) MTCode = MT.charCodeAt(textIndex-1) else MTCode = 0;

CV = text.animator("Transcription").property.characterValue;

linear(MTCode, STCode*2-CV, CV, -100, 100)

This allows you to use pretty much any character that can be typed in the original text of the slave layer, rather than having to use characters with very low character codes.

Votes

Translate

Translate

Report

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 ,
Apr 25, 2009 Apr 25, 2009

Copy link to clipboard

Copied

I've been playing around with this and it's really quite powerful. I've had a number of jobs where this would have solved a major problem. You can set up a template text layer with different formatting for different fields. You use special characters to denote the different fields and include enough of them to accomodate the longest entry you might have. For example, for a name and phone number, the template might look like this:

$$$$$$$$$$$$$$$$$$$$ ##############

Where "$" represents a name character and "#" represents a phone number character. Then, using this technique, you just replace the appropriate characters. For any template characters left over, you replace them with the Unicode Zero Width Space character (8203). Then you just need to add Tracking to the Animator and set the Character Alignment parameter to Adjust Kerning to remove the space of the unused characters. The result ends up looking like this:

Joe Smith 123.456.7890

One other note - here's the name-independent way to pick up the value from the Character Value property:

charVal = propertyGroup(3).property.characterValue;

Dan

Votes

Translate

Translate

Report

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
Enthusiast ,
Apr 25, 2009 Apr 25, 2009

Copy link to clipboard

Copied

This is essentially what I'm doing to automate some network promo keys that involve times in which the minutes and seconds are different fonts, and in which the eastern and central times are different point sizes and colors.  It's pretty easy for times, since they can't be more than four digits, but my hat's off to you for trying this with something like names.

And thanks a million for letting me know about the Zero Width Unicode character.  I had just played around with using some of the non-printing characters, which worked okay but occasionally gave unexpected result.  I didn't know about #8203.

While you are playing around with this method, maybe you could help me figure out what is going on with my expression.  I find that it works great for everything but the last character, which will end up being incorrect.  I know it has something to do with the way I'm mapping the original text to the textIndex values, but I can't figure out where the problem is.  These expression selectors are really tough to debug, since I can't transplant the code into a text layer to get a readout of this or that value.

Votes

Translate

Translate

Report

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 ,
Apr 25, 2009 Apr 25, 2009

Copy link to clipboard

Copied

I did the mapping  a different way, like this:

charVal = propertyGroup(3).property.characterValue;

((newChar - oldChar)/(charVal - oldChar))*100

It may give the same result as your linear() call, but I'm not sure.

Dan

Votes

Translate

Translate

Report

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
Enthusiast ,
Apr 26, 2009 Apr 26, 2009

Copy link to clipboard

Copied

Dan Ebberts wrote:

charVal = propertyGroup(3).property.characterValue;


This line works in CS3, but in CS4 it gives the error:

After Effects warning: Bad method arguments:

Layer Level property groups don't have enclosing groups

Expression disabled

I'm not yet sure why this would have changed.

Votes

Translate

Translate

Report

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
Enthusiast ,
Apr 26, 2009 Apr 26, 2009

Copy link to clipboard

Copied

Okay, I've figured out the problem.  I was indexing the layer's sourceText incorrectly.  New code below (and I've incorporated your interpolation code, which is a bit more elegant than mine):

MT = thisComp.layer("Master Text Layer").text.sourceText;

ST = text.sourceText;

if(textIndex <= ST.length) STCode = ST.charCodeAt(textIndex-1) else STCode = 32;

if(textIndex <= MT.length) MTCode = MT.charCodeAt(textIndex-1) else MTCode = 32;

CV = text.animator("Transcription").property.characterValue;

((MTCode - STCode)/(CV - STCode))*100

If I can just get the propertyGroup() vs. CS4 problem resolved I think this will be pretty much finished.

Votes

Translate

Translate

Report

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 ,
Apr 26, 2009 Apr 26, 2009

Copy link to clipboard

Copied

I keep forgetting about that change. It should be like this:

charVal = thisProperty.propertyGroup(3).property.characterValue;

Dan

Votes

Translate

Translate

Report

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
Enthusiast ,
Apr 26, 2009 Apr 26, 2009

Copy link to clipboard

Copied

LATEST

Great!  That works just fine.

Votes

Translate

Translate

Report

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