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

Per-Character Scripting Public Beta Announcement

Adobe Employee ,
Nov 20, 2023 Nov 20, 2023

Copy link to clipboard

Copied

Hi everyone, 

With After Effects (Beta) 24.2.0 build 17, we have added some very significant and long-awaited additions to the TextDocument DOM:

  • The properties of individual characters can now be changed independently of the others with the new CharacterRange and ParagraphRange objects. 
  • New paragraphCount attribute will return the number of paragraphs in the TextDocument. 
  • New paragraphCharacterIndexesAt method will return the paragraph bounds from a character index—useful if you have a character index and wonder what the character index bounds of the paragraph it is part of. 
  • It is now possible to faithfully round trip a mixed-property Text Layer via the TextDocument without losing individual properties. 
  • boxTextPos will now accept negative values (this was a long-standing bug.) 

You can read the updated docs here: https://ae-scripting.docsforadobe.dev/introduction/changelog.html. 

 

The CharacterRange and ParagraphRange will benefit from a short explanation. 

The former is returned by the characterRange() function where the parameters are character indexes, and the latter by the paragraphRange() function where the parameters are paragraph indexes. With them, you have all the same familiar character and paragraph properties that are available on the TextDocument, but now they apply to the effective character index range which was used to construct the specific range object. 

For example: 

 

 

var td = ....layer(1).property(“Source Text”).value; 
td.text; => “Hello, World!” 
var cr = td.characterRange(0,5); 
cr.text; => “Hello” 
cr.text = “After Effects”; // replace “Hello” with “After Effects” 
cr.text; => “After” 
td.text; => “After Effects, World!” 

 

 

 

Though these new objects share the same character and paragraph property definitions, there are still a few differences of note. 

  • A TextDocument character attribute on read returns the attribute's value for the first character in the Text layer, but on write applies it to the whole Text layer. Because of this, a TextDocument character property is never mixed. 
  • A TextDocument paragraph attribute on read and write is for all the characters in the Text layer. Because of this, a TextDocument paragraph property can be mixed. 
  • A CharacterRange and ParagraphRange object can return mixed if the range exceeds one character or paragraph, mixed is always indicated by returning undefined (except for .justification). 
  • The TextDocument fillColor and strokeColor will throw an exception on read if the corresponding applyFill and applyStroke properties are not set - the CharacterRange and ParagraphRange objects will not. 

 

PerCharacter_StyleEdit_ScriptUISample.png


We have built a demo script exercising the new CharacterRange and ParagraphRange hooks to get you started. You can get it from our Github repository: https://github.com/AdobeDocs/after-effects/blob/main/samples/PerCharacter_StyleEdit_ScriptUISample.j...

 
Remember, these scripting hooks are currently in Beta and are subject to change. 
 
We can't wait to see what you'll be building with these new hooks. 

 
PerCharacterScripting.png

 Douglas, John and Sebastien 

TOPICS
Feature request , Performance

Views

10.0K

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

Adobe Employee , May 14, 2024 May 14, 2024

Hi all,

Thank you so much for your feedback on these new per-character scripting APIs. We are happy to announce that these are available for use in the release version of After Effects 24.3. The documentation on https://ae-scripting.docsforadobe.dev/ has also been updated to reflect the wider release of the APIs.

 

Thanks again,

- Douglas, John,and Sebastien

Votes

Translate

Translate
Valorous Hero ,
Nov 21, 2023 Nov 21, 2023

Copy link to clipboard

Copied

And these work with both Point and Paragraph Text Layers?

And is it safe to expect WordRange and LineRange in the near future?


Motion Graphics Brand Guidelines & Motion Graphics Responsive Design Toolkits

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
Adobe Employee ,
Nov 21, 2023 Nov 21, 2023

Copy link to clipboard

Copied

Hi Roland,

yes it works with both Point and Box Text Layers. As for Word and Line ranges, I'll add your voice to the feature request 😉

Cheers,
Seb

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
Adobe Employee ,
Nov 21, 2023 Nov 21, 2023

Copy link to clipboard

Copied

Hi Roland:

 

Many things we could do, not equally as important, or equally as cheap.

 

LineRange though is an interesting one - at the moment the TextDocument instance that the Character/Paragraph is modifying is not actually composed until it is saved back to a Layer. So we would need to start composing it, which I have not done yet - though if we did we could start returning glyph location information as well...which would be nice for some.

 

baselineLocs is NOT updated while changes are made to the TextDocument instance - it is a copy from where the TextDocument as retrieved from.

 

Play with what we have given you for a bit and let us know about things you cannot work around.

 

Douglas Waterfall

After Effects Engineering

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
Valorous Hero ,
Nov 21, 2023 Nov 21, 2023

Copy link to clipboard

Copied

Thanks for the reply, Seb & Douglas - much appreciated. 

Motion Graphics Brand Guidelines & Motion Graphics Responsive Design Toolkits

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
Explorer ,
Nov 26, 2023 Nov 26, 2023

Copy link to clipboard

Copied

Thanks a lot guys for these!, I've been playing with them a little bit already, looking very promising!

It will definitely remove plenty of hacks and speed up things a lot!

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
New Here ,
Nov 27, 2023 Nov 27, 2023

Copy link to clipboard

Copied

Will this be avalaible for expressions too or just for scripting?

Having it in expressions would make my life so much easier to create and update some templates I use almost everyday.

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
Adobe Employee ,
Nov 27, 2023 Nov 27, 2023

Copy link to clipboard

Copied

Hi @Thomas Ladorian

 

This update is only "just" for scripting.

 

I have some questions I would like to ask you about your Expressions workflow, if you can spare the time - send me a letter via forum mail.

 

Douglas Waterfall

After Effects Engineering

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 ,
Nov 28, 2023 Nov 28, 2023

Copy link to clipboard

Copied

Expressions access to these features would be a pretty big deal for me as well. I'm frequently have to find workarounds to accommodate designs with mixed typefaces, and I hate having to impose limitations on the designers who create these looks or on the editors who will have to navigate complicated controls and weird constraints when using the templates I build.

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
Valorous Hero ,
Dec 05, 2023 Dec 05, 2023

Copy link to clipboard

Copied

@douglas, I have something that's Expression Driven that might be useful to look at in terms of workflow as well as UI. Let me know if you'd like to take a look.

 

Motion Graphics Brand Guidelines & Motion Graphics Responsive Design Toolkits

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
Valorous Hero ,
Dec 05, 2023 Dec 05, 2023

Copy link to clipboard

Copied

After a little more thinking, I think my ideas/thoughts are too entrnched in my own workflow which I doubt will do well for the majority of users AND I'm assured and better rested seeing what you guys come up with. 

Motion Graphics Brand Guidelines & Motion Graphics Responsive Design Toolkits

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 ,
Dec 05, 2023 Dec 05, 2023

Copy link to clipboard

Copied

This is a wonderful development for scripting, but per-character formatting for expressions would be huge. There are work-arounds, but they are cumbersome and time-consuming.

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
Valorous Hero ,
May 04, 2024 May 04, 2024

Copy link to clipboard

Copied

IMO, an elegant and functional way for multifont use is to add a Font Text Animator Property. We can then use Range/Expression/Wiggly selectors to apply multiple fonts. IOW, please don't make it a text.sourceText thingy.



Also, Expressionable Paragraph Alignement will be take off a huge burden off performance issues. It's a PITA and a performance hit each time.  


Motion Graphics Brand Guidelines & Motion Graphics Responsive Design Toolkits

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
Adobe Employee ,
May 05, 2024 May 05, 2024

Copy link to clipboard

Copied

@Roland Kahlenberg 

 

I would like to learn more about how you might like this to work - propose an API/UI to help me understand what you trying to accomplish. Is there an existing pattern it should follow?

 

Thanks

Douglas Waterfall

After Effects Engineering

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
Valorous Hero ,
May 05, 2024 May 05, 2024

Copy link to clipboard

Copied

@Douglas_Waterfall 

For adding a Typeface and its Related Fonts, I was thinking of combining the existing Font UI which is invoked within text.sourceText with the Add Text Animator Flyout Menu. 

So, the Text Animator Flyout Menu will include a separate section (for non-3D layers, we currently have 6 sections), for a 7th section. This new item in the Flyout Menu will be identical to the existing Font Menu we now use in text.sourceText.

On its use, if there is no Font Animator application via a Text Animator, then all text characters default to chosen values via the Character Panel. 

When a Font Animator Property is applied to a Text Animator Group, the user selects one font for one or more Selectors. User then uses at least one Selector to apply this Font Animator Property onto. Expected behavior will be for Selected Objects to be displayed as per the Font Animator Property and Unselected Objects to display as per Character Panel options.

My thoughts are such a workflow will be easier for users to implement since the process of adding Text Animator Groups and Properties are common knowledge/practice. I'd also not want to have lots of additional code to use in text.sourceText which for me is already 'crowded' in lots of use-cases and which I assume to be an alternative to the aformentioned Text Animator Property option.

For Paragraph Alignment, text.sourceText will be a good spot; assuming it'll only require 1 or 2 lines of code at most and I assume most users will have no issues using such code there. 

Hope this helps. 

Bestest
- RolandK
  

Motion Graphics Brand Guidelines & Motion Graphics Responsive Design Toolkits

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 Beginner ,
Jan 17, 2024 Jan 17, 2024

Copy link to clipboard

Copied

First off - thank you @Douglas_Waterfall  for taking the time to support the community. It is extremely valuable. 

Per-Character expression would be beneficial in my workflow: I have a signle text box that contains a mix of [NotoSans](Chinese) and [Regular Sans] (English).

 

Right now,  I have to adjust the chinese font to a lower size, and then decrease the baseline of the english font so that everything looks symetrical and lined up. Otherwise the english font will look a little too small and raised up from the baseline compared to the chinese lettering. 

The baseline and text size variables are usually about -12% size and -1 baseline. But if the entire text is smaller, then the baseline and text variables change. 

Using the script per-character feature, it helps, but this adjustment needs to only happen in specfic layers....and dpending on those text box sizes, the baseline can be -3 or -1. This requires scripting specific conditional scenarios to target those layers, and for specific layers use different sizing and baselines.

IF...this was expressiom based, I could just apply the changes to each text box with thier unique per-character (language based) baseline and size adjustment. And then not have to code specific scenarios via scripting. 

Thanks!

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 Beginner ,
Apr 02, 2024 Apr 02, 2024

Copy link to clipboard

Copied

Add yet another request for expression access to these hooks. Personally, I'd rather everything text-related be developed for expressions FIRST and then scripting. I have no idea how I'd use this in scripting yet, but I have been wanting this in expressions FOREVER!

workbench.tv

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 Beginner ,
Mar 27, 2024 Mar 27, 2024

Copy link to clipboard

Copied

I agree with this comment.

I think this might be REALLY close to the update I've been waiting for. I make MoGrt files and I keep getting asked if there's a way for my clients to highlight a chosen portion of their text input with a different font/styling. It would be great if I could link a range selector to a complete style change (font, colour, size etc.).

At the moment I'm stuck using clunky workarounds with multiple text layers that don't always line up.

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
Valorous Hero ,
May 05, 2024 May 05, 2024

Copy link to clipboard

Copied

For different colored text to a range of Text Objects, this should be easy with Text Animators. For italics, the Skew Text Animator does a very good faux italics. For Bold, adding Stroke Width, again, via a Text Animator Property, is a viable option. Scaling up is also viable but Scaling down produces insurmountable kerning issues in my experience.

 

Motion Graphics Brand Guidelines & Motion Graphics Responsive Design Toolkits

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
Engaged ,
Dec 26, 2023 Dec 26, 2023

Copy link to clipboard

Copied

Is there any way to know whether a character is/isn't selected?
If not, can it be added please?

dbDavideBoscolo_0-1703581500950.png

 

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
Engaged ,
Jan 25, 2024 Jan 25, 2024

Copy link to clipboard

Copied

What about this guys? 

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
Adobe Employee ,
Jan 26, 2024 Jan 26, 2024

Copy link to clipboard

Copied

Just a quick update on the status of this, as it has been in Beta for a while and I expect a number of gentle readers are patiently waiting for this to appear in a full release.

 

We have elected to hold this back from the upcoming 24.2 release as we wish to make a substantial change to the API for the ParagraphRange object first.

 

What we are planning to do is remove all the text properties from the ParagraphRange and substitute them for a single API which will return a CharacterRange object which is initialized to the start/end character index values of the ParagraphRange.

var pr = textDocument.paragraphRange(5);
var cr = pr.characterRange(); // note, no parameters
cr.fontSize = 72;
cr.font = "Helvetica";

 

Our motivation for this is performance related - each time any text property of a ParagraphRange instance is accessed the start/end character index has to be computed based on the nTh paragraph reference - for single or small paragraph Text Layers this is not that important, but a Text Layer consisting of a long film credit with each contributor getting their own paragraph...not so good.

 

We will let you know shortly before this change shows up in a Beta release.

 

Douglas Waterfall

After Effects Engineering

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 Beginner ,
Feb 01, 2024 Feb 01, 2024

Copy link to clipboard

Copied

Is it possible for one to stay on a older beta build without updating so we can wait for the next implementation of the character scripting?

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
Adobe Employee ,
Feb 10, 2024 Feb 10, 2024

Copy link to clipboard

Copied

And we are back with a heads up on the API update and more detail.

 

Starting with beta build 24.3.0/25 we have made the following breaking changes.

  • We have removed all the text properties from the ParagraphRange object (ie. font, fontSize, etc).
  • We have added a new function, ParagraphRange.characterRange() which will return a CharacterRange object initialized to the (characterStart, characterEnd) from the ParagraphRange.

 

What this means in effect is that instead of doing this:

 

var td = ...value();
var pr = td.paragraphRange(0);
pr.fontSize = 4;
pr.fillColor = [1,0,0];

 

You should do this:

 

var td = ...value();
var pr = td.paragraphRange(0);
// fastest
var cr = pr.characterRange();
cr.fontSize = 4;
cr.fillColor = [1,0,0];
// slower
pr.characterRange().fontSize = 4;
pr.characterRange().fillColor = [1,0,0];

 

 

Also part of this build will be a new scripting object, ComposedLineRange... but I wll leave you to read the docs for that. 

 

Douglas Waterfall

After Effects Engineering

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 ,
Feb 19, 2024 Feb 19, 2024

Copy link to clipboard

Copied

Wow, ComposedLineRange is amazing!
Should finally give me a reliable way to figure out the lines of a box text 🙂

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects

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
Resources