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

Now in Beta: Per-character Text and Paragraph Styling in Expressions

Adobe Employee ,
May 17, 2024 May 17, 2024

Copy link to clipboard

Copied

Hi everyone! 

 

We're excited to announce that starting in version 24.5.0x41 of After Effects Beta introduces support for per-character control of text and paragraph styling in Expressions. 

 

This long-requested addition to Expressions builds on recent per-character scripting API updates to unlock powerful text styling capabilities that are able to respond to changes in text content and can be saved and shared as presets. These new options can also streamline template design by making it possible to configure alignment and paragraph styling in a single layer rather than turning on and off multiple synced copies of a layer. 

 

A benefit of per-character control is automatic reflowing of text such as when scaling letters, using superscript, and using a different font, just as you would expect from using substring styling from the Character panel. 

 

Stretchy Text1.gif

Getting Started 

 

Make sure you have your expression engine set to Javascript. 

 

The Expression reference flyout menu provides an overview of available methods in the updated Text > Styling submenu; see the attached document for the full API. 

 

Text_Styles_Menu.gif

Sample Expressions 

 

Change the font for certain words 

Change_fonts.png

 

Using the string: “Change the fonts of some words” apply the following to the Source Text

 

 

text.sourceText.style
.setFont("Montserrat-Light") 
.setFont("Gigantic", 0, 6).setFont("Gigantic", 10, 6).setFont("Gigantic", 20) 

 

 

To customize this for yourself, change the font from the Text Expression flyout menu, and target the character index and amount of characters to make a different font. 

 

Set the first line of a text layer to bold and make it larger 

change_to_bold.png


Using the string: “Change the first line of text to bold and make it larger”
 apply the following to the Source Text

 

 text.sourceText.style.setFontSize(100, 0, 30).setFauxBold(true, 0, 30) 

 

 

 Set superscript for characters 

set_superscript.png

 

Using the string: “1st and 2nd Place”  apply the following to the Source Text

 

 

text.sourceText.style.setBaselineOption("superscript",1,2).setBaselineOption("superscript", 9, 2) 

 

 

Try passing character index values and character amounts to expression sliders and using keyframes to create animation! 

 

Known Issues 
 

  1. There is a difference in behavior when using .setJustification between Left to Right text and Right to Left text. To justify text to the left when using RTL, use .setJustification("alignRight"), and to justify to the right, use .setJustification("alignLeft"). 
  2. When exporting a mogrt, using .setFontSize() and enabling Font Size adjustment in Font Properties causes unexpected behavior in Premiere Pro. It’s recommended to use one or the other, but not both together. 

  

Limitations  

The style object always returns the first character's style information, not the characters' individual substyles. Therefore, when reading the style of a Text layer containing multiple styles, you must use getStyleAt() with a character index to specify which character's style you need. 

 

We've built an example AEP with the above expressions and few extras to get you started. Please give all of these new expressions a try and let us know how they’re working for you!

TOPICS
Feature request , Performance

Views

4.8K

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 17, 2024 May 17, 2024

Copy link to clipboard

Copied

Excellent work on the API PDF. 

I'm trying to think how the Range Definition can be made dynamic, to cater to dynamic Text Inputs? 

I was hoping Text/Font Styling would go into the Text Animator Section where it's more feasible to code for such cases plus more users are familiar with Text Animators than Expressions. Is this still feasible; something for the near future?

 Great to finally have Paragraph Justification and it will work well in text.sourceText. Thank You!  🙂

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 ,
May 17, 2024 May 17, 2024

Copy link to clipboard

Copied

I think there's a typo here - 

Using the string: “Change the fonts of some words” apply the following to the Source Text

 

 

text.sourceText.style
.setFont("Montserrat-Light") 
.setFont("Gigantic", 0, 6).setFont("Gigantic", 10, 6).setFont("Gigantic", 20) 


------------------------ 

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
Participant ,
May 22, 2024 May 22, 2024

Copy link to clipboard

Copied

Ah Fantastic. Looking forward to having a play.

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 ,
May 26, 2024 May 26, 2024

Copy link to clipboard

Copied

In playing around with this wonderful new capability, it seems like there should be an easy way to copy another layer's text and all of its per-character styling, but it's not jumping out at me how you would do that. Am I missing something, and if so, can you provide an example?

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
Participant ,
May 26, 2024 May 26, 2024

Copy link to clipboard

Copied

Yes I was hoping this code would just duplicate the text layer and all its per character styling then turn off any fills and just do stroke the text as I hya number of templates that are setup to work that way with the old methods.

 

const otherLayer = layer("text");
const strokeWPercent = 3; //stroke is percentage of fontsize so that stroke scales with fontsize
const sourceTxt = otherLayer.text.sourceText.value;

const { fillColor, fontSize } = otherLayer.text.sourceText.style
const strokeW = (strokeWPercent/100)*fontSize
const origLayerStyle = otherLayer.text.sourceText.style; 
origLayerStyle.setApplyFill(false).setApplyStroke(true).setStrokeColor(fillColor).setStrokeWidth(strokeW).setText(sourceTxt);

 

This for me would be the ideal solution as it means I don't need to change up my methods too much but others with better expression skills might see a problem with this implementation.

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 28, 2024 May 28, 2024

Copy link to clipboard

Copied

Hi @Dan Ebberts,

 

Unfortunately, this is the limitation.

 

Currently, style pulls the information at the 0 index, while getStyleAt can get whatever index you ask for (and sliders can be useful for this when going between multiple layers), but trying to get all of the substring ends up with a lot of expressions work on the other text layers. And trying to make that dynamic can be a chore.

 

Do you have ideas of how you'd like to see substring copying to work? Would love some thoughts to bring back to the team!

 

Theresa

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 ,
May 28, 2024 May 28, 2024

Copy link to clipboard

Copied

Hmmm... I know this isn't quite right, but it seems like something like this would give you a way to at least copy another layer's styling, character by character:

txt = thisComp.layer("other layer").text.sourceText;
s = style;
for (i = 0; i < txt.length; i++){
  sTemp = txt.getStyleAt(i);
  s.setStyleAt(i,sTemp);
}
s.setText(txt);

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
Participant ,
May 28, 2024 May 28, 2024

Copy link to clipboard

Copied

Could you possibly add a text animator for font. I know text animators interpolate between values but you could hardcode a font so below 0.5 it's the original font and values above 0.5 it's the text animators font values. Keep the expression API and add the text animators. I think that will please a lot of people as they understand text animators easier than coding expressions. I'd also add a text animator for fill equals yes or no and a text trim paths. With all those you have a ton of possibilities 

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
Participant ,
May 30, 2024 May 30, 2024

Copy link to clipboard

Copied

I just wanted to be clear too that i cannot agree more with Dan. We really need a way to refer to another text layer and replicate it through an expression. I've been having a play and think with the ability to set the text and attributes by an index we really need to interrogate the text  attribute style at an index. It's in my mind a given we need this to implemet it properly.

And i agrree with him and see the value in a setTextAt() function would be a fantastic way.  This is a high priority on my wishlist for this api development

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 ,
May 27, 2024 May 27, 2024

Copy link to clipboard

Copied

Having a lot of fun playing with this so far - I also somewhat second that these would be really effective if they could be treated as text animators are - primarily because "word" index is much easier to use than "character" index for many uses. If you're trying to do things more dynamically. Having to parse and split and such to determine a words start/end point within a character index is somewhat laborious (in my particular implementations)


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
Participant ,
May 28, 2024 May 28, 2024

Copy link to clipboard

Copied

Some expressions that could help with laborious long expressions. Now you just need to fill in laborious Arrays!
3 expressions for those to play with. Note You may not have the same fonts installed as me. SO adjust your font arrays as neccesary. AE uses the Postript Name for Fonts in expressions.
1. Random Font Per Character
2. Set Multi Attributes in an array order split per word/line/delimiter
3. Set Multi Attributes in Radnom order split per line/word/delimiter

Numbers 2 and 3 should help you out @Jesse27755342iou7 

// code for AE Beta 24.5 Per character styling
// https://be.net/volition - 2024
// Random Fonts per Character
//
// BEWARE as this is a very slow expression due to the nature of it.
// Could be made slightly more optimal by looking for whitespaces and character returns and grouping them within the iteration, even then i'm not confident in that. 

// posterizeTime(0); // uncomment line and changeRate to 0 if you don't want the font changing over time - it should help with processing optimisation

var changeRate = 50; // change every x frames (I recomend adding )
var frequency = changeRate*thisComp.frameDuration;
var timeIndex = changeRate ? Math.floor(time/frequency) : 0;

var regularFontArray = ["KaushanScript-Regular", "Lato-Regular", "VT323-Regular", "GreatVibes-Regular", "FiraMono-Regular", "Exo2-Regular", "Raleway-Regular", "OpenSans-Regular", "Ubuntu-Regular", "Muli-Regular", "PlayfairDisplay-Regular", "Heebo-Regular", "CutiveMono-Regular", "BarlowCondensed-Regular", "ROGFontsv1.6-Regular", "NotoSansJP-Regular", "ArchivoNarrow-Regular", "PTMono-Regular", "FjallaOne-Regular", "JuliusSansOne-Regular", "Satisfy-Regular", "RobotoMono-Regular", "SourceSansPro-Regular", "Domine-Regular"];

var sourceText = text.sourceText.value; // Get the text value as a string

var startIndex = 0;
var expression = "text.sourceText.style"; // Initialize the expression
for (var i = 0; i < sourceText.length; i++) {
    var charLength = 1;
	seedRandom(index+i+timeIndex*sourceText.length,true);
	var randomFont = regularFontArray[Math.floor(Math.random() * regularFontArray.length)];
	expression += `.setFont("${randomFont}", ${startIndex}, ${charLength})`;
    startIndex += 1;
}
expression += ";"

// Output the final expression
eval(expression)

 

Ok Now for Number 2 

// code for AE Beta 24.5 Per character styling
// https://be.net/volition - 2024
// CHANGES TEXT ATTRIBUTES EVERY WORD/LINE/ OTHER DEPENDING ON DELIMITER ACCORDING TO THE ARRAY ORDERS
// quick guide for those not as familiar with expressions
// choose your delimiter variable [" "] will change per word ["\n","\r"] will change per line you can also use any other delimiters you want
// textProperties & textPropertyValues you can set how ever many or few text attributes and the trange of values it that attribute will cycle through.
// If you don't want the array to cycle through over the animation. you can remove the 3 lines from changeRate on and remove ",index+timeIndex" from output

// WARNING these expressions can slow your system way down if elaborate and lots of text

// posterizeTime(0); // use if not wanting ongoing change of attributes over time also uncomment this line
function getIndicesOf(text, chars) {
    var indices = [];
    for (var i = 0; i < text.length; i++) {
        if (chars.indexOf(text[i]) !== -1) {
            indices.push(i);
        }
    }
    return indices;
}

function setTextPerPropsDelimiterArrayOrder(sourceText, delimiter, textProperties, textPropertyValues, indexOffset) {
    var delimitIndices = getIndicesOf(sourceText, delimiter);
    delimitIndices.push(sourceText.length);

    var expression = "text.sourceText.style"; // Initialize the expression  
    var startIndex = 0;

    for (var i = 0; i < textProperties.length; i++) { // step through the attributes
        startIndex = 0;
        for (var j = 0; j < delimitIndices.length; j++) { // step through the elements for each attribute
            var endIndex = delimitIndices[j];
            var wordLength = endIndex - startIndex;
            if (wordLength > 0) {
                var setAttribute = textProperties[i];
                var setAttributeValue = textPropertyValues[i][(j+indexOffset)%textPropertyValues[i].length]; // cycle back
				if (Array.isArray(setAttributeValue)) { // check if element has more then 1 value it needs to be applied as an array with square brackets
					expression += `.${setAttribute}([${setAttributeValue}], ${startIndex}, ${wordLength})`;
				} else {
					expression += `.${setAttribute}("${setAttributeValue}", ${startIndex}, ${wordLength})`;
				}
            }
            startIndex = endIndex + 1; // Move to next word
        }
    }
    return expression += ";"
}

var sourceText = text.sourceText.value;
var delimiter = [" "];
var textProperties = ["setApplyStroke","setStrokeColor","setStrokeWidth","setFont"];
var textPropertyValues =   [[1,1,0,1,1,0],
                        [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0],[1.0, 1.0, 0.0],[1.0, 0.0, 1.0],[0.0, 1.0, 1.0]],
                        [1,1.5,2,3,0.5,1,],
						["Lato-Regular", "VT323-Regular", "GreatVibes-Regular", "FiraMono-Regular", "Exo2-Regular", "Raleway-Regular", "OpenSans-Regular", "Ubuntu-Regular", "Muli-Regular", "PlayfairDisplay-Regular", "Heebo-Regular", "CutiveMono-Regular", "BarlowCondensed-Regular", "ROGFontsv1.6-Regular", "NotoSansJP-Regular", "ArchivoNarrow-Regular", "PTMono-Regular", "FjallaOne-Regular", "JuliusSansOne-Regular", "Satisfy-Regular", "RobotoMono-Regular", "SourceSansPro-Regular", "Domine-Regular"]
                        ]

var changeRate = 50; // change every x frames (I recomend adding )
var frequency = changeRate*thisComp.frameDuration;
var timeIndex = changeRate ? Math.floor(time/frequency) : 0;

output = setTextPerPropsDelimiterArrayOrder(sourceText, delimiter,textProperties,textPropertyValues,index+timeIndex);

// evaluate the expression string
eval(output)

 

Last one  Hope they help someone

// code for AE Beta 24.5 Per character styling
// https://be.net/volition - 2024
// CHANGES TEXT ATTRIBUTES EVERY WORD/LINE/ OTHER DEPENDING ON DELIMITER DOES SO RANDOMNLY
// quick guide for those not as familiar with expressions
// choose your delimiter variable [" "] will change per word ["\n","\r"] will change per line you can also use any other delimiters you want
// textProperties & textPropertyValues you can set how ever many or few text attributes and the trange of values it that attribute will cycle through.
// If you don't want the array to cycle through over the animation. you can remove the 3 lines from changeRate on and remove ",index+timeIndex" from output

// WARNING these expressions can slow your system way down if elaborate and lots of text

// posterizeTime(0); // use if not wanting ongoing change of attributes over time also uncomment this line

function getIndicesOf(text, chars) {
    var indices = [];
    for (var i = 0; i < text.length; i++) {
        if (chars.indexOf(text[i]) !== -1) {
            indices.push(i);
        }
    }
    return indices;
}

function setTextPerPropsDelimiterRandomOrder(sourceText, delimiter, textProperties, textPropertyValues, textSeed = 0) {
    var delimitIndices = getIndicesOf(sourceText, delimiter);
    delimitIndices.push(sourceText.length);

    var expression = "text.sourceText.style"; // Initialize the expression  
    var startIndex = 0;

    for (var i = 0; i < textProperties.length; i++) { // step through the attributes
        startIndex = 0;
        for (var j = 0; j < delimitIndices.length; j++) { // step through the elements for each attribute
            var endIndex = delimitIndices[j];
            var wordLength = endIndex - startIndex;
            if (wordLength > 0) {
                var setAttribute = textProperties[i];
				seedRandom(index+i+j+textSeed*sourceText.length,true);
                var setAttributeValue = textPropertyValues[i][Math.floor(Math.random() * textPropertyValues[i].length)]; // cycle back
				if (Array.isArray(setAttributeValue)) { // check if element has more then 1 value it needs to be applied as an array with square brackets
					expression += `.${setAttribute}([${setAttributeValue}], ${startIndex}, ${wordLength})`;
				} else {
					expression += `.${setAttribute}("${setAttributeValue}", ${startIndex}, ${wordLength})`;
				}
            }
            startIndex = endIndex + 1; // Move to next word
        }
    }
    return expression += ";"
}

var sourceText = text.sourceText.value;
var delimiter = [" "];
var textProperties = ["setApplyStroke","setStrokeColor","setStrokeWidth","setFont","setApplyFill"];
var textPropertyValues =   [[1,0],
						[[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.5, 1.0],[1.0, 1.0, 0.0],[1.0, 0.0, 1.0],[0.0, 1.0, 1.0],[0.7, 0.5, 1.0],[0.8, 0.5, 0.6]],
                        [1,1.5,2,3,0.5,1,6],
						["Lato-Regular", "VT323-Regular", "GreatVibes-Regular", "FiraMono-Regular", "Exo2-Regular", "Raleway-Regular", "OpenSans-Regular", "Ubuntu-Regular", "Muli-Regular", "PlayfairDisplay-Regular", "Heebo-Regular", "CutiveMono-Regular", "BarlowCondensed-Regular", "ROGFontsv1.6-Regular", "NotoSansJP-Regular", "ArchivoNarrow-Regular", "PTMono-Regular", "FjallaOne-Regular", "JuliusSansOne-Regular", "Satisfy-Regular", "RobotoMono-Regular", "SourceSansPro-Regular", "Domine-Regular"],
						[1,1,1,1,1,1,1,1,1,0],
						[[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.5, 1.0],[1.0, 1.0, 0.0],[1.0, 0.0, 1.0],[0.0, 1.0, 1.0],[0.7, 0.5, 1.0],[0.8, 0.5, 0.6]]
                        ]

var changeRate = 50; // change every x frames (I recomend adding )
var frequency = changeRate*thisComp.frameDuration;
var timeIndex = changeRate ? Math.floor(time/frequency) : 0;

output = setTextPerPropsDelimiterRandomOrder(sourceText, delimiter,textProperties,textPropertyValues,index+timeIndex);

// evaluate the expression string
eval(output)

 

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 ,
Jun 03, 2024 Jun 03, 2024

Copy link to clipboard

Copied

 @Volition74au  Thanks for sharing these. Do these delimiters in your code work with multi-lined texts including Point Text and Paragraph Text layers? 

One thing I've struggled with is to get delimiters to work on multi-lined text and I was thinking perhaps the AE Team could provide an Expression function to handle this.

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
Participant ,
Jun 04, 2024 Jun 04, 2024

Copy link to clipboard

Copied

The expressions only work where there are delimiters so with a paragraph text opposed to point text there is no delimiter that is in the string to indicate a new line. So no it won't work unless you actually hit a line return in the string. SO yes we would need a alternative object in the api that you could use rather then the chracter index we could use line indexes perhaps. e.g. setFont(character, "Cool Font"0,6).setFont(character, "Cool Font"6,10) for character indexing and setFont(line, "Cool Font"0,2) .setFont(line, "Cool Font"0,2) 

or  text .sourceStyleCharacter vs text .sourceStyleLine as ways it could be implemented.

Altough i think this expression api is great  however, a "font" text animator in the same vain as  say a character offset would be a great solution i'd love to see too.

Adobe have not released new animation funtionality for a long time in AFter effects like a new animator. Both that and a text trim paths text animator would make my year.

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 28, 2024 May 28, 2024

Copy link to clipboard

Copied

Thanks for your input @Jesse27755342iou7, glad you're having fun playing with the expressions.

 

We've talked about word and line ranges, but we needed to start somewhere with this large addition to expressions. I'll keep advocating for this addition since I know it would be extremely useful.

 

Thanks,

Theresa

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 29, 2024 May 29, 2024

Copy link to clipboard

Copied

AE's competitors are doing a good job with their Text Tools. 

While wishing for more features, I am also wishfully hopeful for a much, much quicker AE Text Tool. I think it will be a good idea if AE's Text Tool Engine can be speed-improved by 3-5x - even a 6-month long project to make this happen will be worth the while.  🙂

The Paragraph Alignment is a great help in helping us be both more efficient in our workflow as well as develop more performant solutions. I'd also like to see Expressions link to the Based On property. This is another area that requires multiple set ups in order to provide user-expected features. 

On the new Text Expressions, Word, Line and even Paragraph & ALL Ranges will be great and I am actually assuming these are in the works. 
 

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 ,
Jun 06, 2024 Jun 06, 2024

Copy link to clipboard

Copied

Thanks Theresa, per word changes would be extremely useful when making MOGRTs.

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 ,
Jun 04, 2024 Jun 04, 2024

Copy link to clipboard

Copied

I finally got the chance to play a bit more with this and I have to say... I love it !

BUT, as I am trying to update my MoglyphFX tool to support these upcoming features, I notice that I can't use the newly added method for Paragraphs with the "setText()" function, which is a big limitation for me since I want to generate text procedurally AND to be able to force it to remain paragraph centered...

 

So if you try add the following expression to a centered or left aligned text:

 

s = text.sourceText ;
newStyle = style.setFontSize(200).setFillColor([1,0,1,1]).setJustification('alignRight');
newStyle.setText(s)

 

You'll see that the text is indeed managing to colorize all the text in pInk and to make its Font Size to 200 px, but that it fails to align the text on the right as requested.

If this is a bug, could we have it fixed soon please ?

If it wasn't well... please considere this as a feature request 🙂

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 ,
Jun 04, 2024 Jun 04, 2024

Copy link to clipboard

Copied

(in case you wonder why I just don't use the "sourceText.style.setXXX" method you all use here, this is because I will create dynamic strings for the "s" variable, so it won't remain the initial sourceText value anymore ; it was a placeholder in order to demonstrate my problem)

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 ,
Jun 27, 2024 Jun 27, 2024

Copy link to clipboard

Copied

LATEST

I ran into similar limitations with my project as well, +1!

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 ,
Jun 13, 2024 Jun 13, 2024

Copy link to clipboard

Copied

On Number of Lines for Paragraph Text, I've always wondered why internally this number is available via the Range Selector when you switch Units from Percentage @ 100% to Character Index but it's been like locked away from Expressions. 

It'll be great if this (numberOfLines thingy) is accessible via a function/method and directly used within the Start/End Range Selectors in a straightforward manner.   

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
Resources