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:
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.
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.
Douglas, John and Sebastien
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
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?
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
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
Copy link to clipboard
Copied
Thanks for the reply, Seb & Douglas - much appreciated.
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!
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.
Copy link to clipboard
Copied
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
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.
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.
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.
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.
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.
Copy link to clipboard
Copied
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
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
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!
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!
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.
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.
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?
Copy link to clipboard
Copied
What about this guys?
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
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?
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.
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
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 🙂