Copy link to clipboard
Copied
Hello. Please, help. I asked GPT about this problem, but it always made mistakes.
My question to GPT:
Help me write an expression for After Effects. There are two layers. The bottom layer is a shape layer. The upper layer is a text layer. First condition: I need the text layer to split into two equal lines if its width is greater than the width of the shape layer below it. After that, and only after the first condition is met, the second condition should come into effect: if the width of the text layer after splitting it into two lines is still wider than the width of the shape layer, then let the text be scaled down until it fits within the width of the shape layer.
GTP answered:
To achieve your goal in After Effects using expressions, you'll need to apply a series of expressions to your text layer. Here's how you can do it:
1. Split Text into Two Lines if Necessary: You'll use an expression on the `Source Text` property of the text layer to split the text into two lines if it's wider than the shape layer.
2. Scale Down Text if Still Too Wide: You'll use an expression on the `Scale` property to scale down the text if, after splitting, it's still too wide.
### Step-by-Step Guide
#### 1. Determine the Widths
First, you need to compare the width of the text layer with the width of the shape layer.
- Shape Layer Width: Directly use the width of the shape layer's bounding box or a specific dimension if it's a simple rectangle.
- Text Layer Width: Use the `sourceRectAtTime()` method to get the text layer's width.
#### 2. Apply Expressions
Here’s how to set up the expressions:
A. Source Text Expression
Go to the text layer, hold `Alt` (or `Option` on Mac), and click the stopwatch next to `Source Text` to add an expression:
var myText = value;
var shapeLayer = thisComp.layer("Shape Layer 1"); // Adjust the name as needed
var textLayer = this;
var textWidth = textLayer.sourceRectAtTime(time, false).width;
var shapeWidth = shapeLayer.sourceRectAtTime(time, false).width;
if (textWidth > shapeWidth) {
// Split text into two lines
var words = myText.split(" ");
var midPoint = Math.ceil(words.length / 2);
var line1 = words.slice(0, midPoint).join(" ");
var line2 = words.slice(midPoint).join(" ");
line1 + "\n" + line2;
} else {
myText;
}
This expression splits the text into two lines if its width exceeds the width of the shape layer.
B. Scale Expression
Now, adjust the scale of the text layer if the text (potentially split into two lines) is still too wide. Hold `Alt` (or `Option` on Mac) and click the stopwatch next to `Scale`:
var shapeLayer = thisComp.layer("Shape Layer 1"); // Adjust the name as needed
var textLayer = this;
var originalScale = transform.scale.value;
// Get current text width after potentially splitting into lines
var textWidth = textLayer.sourceRectAtTime(time, false).width;
var shapeWidth = shapeLayer.sourceRectAtTime(time, false).width;
if (textWidth > shapeWidth) {
var scaleFactor = shapeWidth / textWidth;
[originalScale[0] * scaleFactor, originalScale[1] * scaleFactor];
} else {
originalScale;
}
### Explanation
- Source Text Expression: Checks if the text width is greater than the shape width and splits the text into two lines if true.
- Scale Expression: After the text is potentially modified (split into lines), this checks the width again and scales down the text to fit within the shape layer.
### Notes
- Make sure your text layer’s anchor point and alignment are set appropriately for the scaling and line splitting to appear correctly.
- Update `"Shape Layer 1"` in the expressions to match the exact name of your shape layer.
- This approach assumes the text layer’s `Source Text` is plain text. If you use text formatting (like bold or different sizes), you need to adjust the logic to account for formatting changes.
This should give you a good starting point to tweak further based on your specific needs in After Effects!
* * *
But every time in the discuss there were the same problems:
TypeError: textLayer.sourceRectAtTime is not a function
TypeError: Cannot read properties of undefined (reading 'value')
And so on.
I hope, may be you can help me, people?
Copy link to clipboard
Copied
You cannot self-reference an object with "this". It needs to be thisLayer or whatever is appropriate.
Mylenium
Copy link to clipboard
Copied
Thank you, Mylenium. NOw it works.
Not quite as planned, but overall, almost acceptable. It starts scale text thinking it's written in one line, so it shrinks it too much without aligning both lines to the width of the shape. Oh well, at least that's the way it is.
Copy link to clipboard
Copied
Now I would somehow indicate before scaling that the text is written in two lines instead of one. But here I don't even know how to formulate the task.
Copy link to clipboard
Copied
I changed the row
[originalScale[0] * scaleFactor, originalScale[1] * scaleFactor];
to
[originalScale[0] * scaleFactor * 2, originalScale[1] * scaleFactor * 2];
but now it can be more than 100%. How to limit it with maximum 100%?
Copy link to clipboard
Copied
Everything in AE has a specific evaluation order. If you want to scale based on the wrapped text you may need to apply the scale expression to a duplicate text layer whose source text is linked with a simple pickwhip expression to the text property of another, invisible layer, which has the actual wrapping code.
Mylenium