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

sourceRectAtTime().height not updating when layer scale is adjusted

Community Beginner ,
Aug 18, 2020 Aug 18, 2020

Hello,

This topic has been confusing me so much over the past few days... Essentially, I'm trying to make a graphic where I have one text box on top and one separate text box below. I would like the bottom text to stay aligned to the bottom of the top text (using sourceRectAtTime and height).

 

The issue: When I scale the top text box, the .sourceRectAtTime().height property does not adjust hence eliminating the bottom text from making proper position updates. For example, in the photo below, when I scale the red null that the text is attached to which increases the text box height, the pink null below does not recognize that scale and does not move.

 

Example of my issue... red arrow indicates when I scale this, the cyan null does not update.Example of my issue... red arrow indicates when I scale this, the cyan null does not update.

 

 

 

 

 

 

 

 

 

 

 

 

 

I've tried numerous solutions and have dug through all sorts of community forms to no avail. Any help would be wonderful.

 

Thanks,

Kyle

TOPICS
Expressions , How to , Scripting
4.4K
Translate
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 ,
Aug 18, 2020 Aug 18, 2020

The cropped screenshot is completely useless for troubleshooting your problem. We need to see the layers that are giving you problems with their modified properties revealed. Do that by selecting both the text layer use as the source for sourceRectAtTime() and the layer that it is supposed to be controlling, press the "u" key twice to reveal everything that is modified, and also copy and paste any expressions you use or at least expose them so we can see what is going on.

 

My first guess is that you are just poking around in the UI or following a tutorial posted by an enthusiast that isn't explaining things well.

 

If you want to use an expression to scale a shape layer used as a background for the text and you want to be able to position the text anywhere you have to compensate for scale and position. Here's a screenshot showing how I do it:

Screenshot_2020-08-18 14.01.44_AOxT7f.png

The first slider controls the padding around the rectangle, the second is used to correct for baseline shift when your text has descenders or is on multiple lines.

 

The first expression calculates the size of the rectangle by looking at the size of the layer that is one layer above the text layer. This eliminates the need to rename layers. The height and width of the layer above have the padding from the slider added to both dimensions, then the result is multiplied by the scale of the layer above. It's all pretty simple. This example only works with text that has the paragraph set to Centered. 

 

The second expression fixes position errors for the Text Box rectangle. The other expressions are pretty simple. They just lock the position and anchor point of the shape layer to the text layer so things line up automatically.

 

I have animation presets for left, and right-justified text.  Here are the expressions used in these presets. They were thrown together a long time ago and could be improved. The only thing that could not be automated 100% is the correction for the size of the descenders like y and j in a line of text. That's what the slider is for. Multi-line text is also a little wonky. I should probably fix that sometime soon.

// Rectangle size
txt = thisComp.layer(index - 1);
s = txt.sourceRectAtTime();
pad = effect("Padding")("Slider");
txtScale = txt.scale * .01;
txtBox = [s.width, s.height] + [pad, pad];
[txtBox[0] * txtScale[0], txtBox[1] * txtScale[1]]

// Text Box>Rectangle Path 1>Position Correction
txt = thisComp.layer(index - 1);
s = txt.sourceRectAtTime();
pad = effect("Padding")("Slider");
txtScale = txt.scale * .01;
descFix = effect("Baseline Correction")("Slider");
txtBox = [s.width, s.height] + [pad, pad];
correction = content("Text Box").content("Rectangle Path 1").size;
[txtBox[0] * txtScale[0], (txtBox[1] + (s.top/2) + descFix)  * txtScale[1]] - correction

As long as the text layer is above the shape layer, these expressions will only work on a shape layer.

Translate
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 ,
Aug 18, 2020 Aug 18, 2020

Hi Rick,

Thank you for your reply... let me gather some more details for you when troubleshooting. I apologize that I didn't get enough background information to make the troubleshooting process easier. To give you a little background on me, I work in After Effects for my job every day and am familiar with expressions. I just can't wrap my head around this issue when it comes to .sourceRectAtTime().height and the scale of other layers when affecting another layer position.

 

Photo 1: In this example, I have two textboxes (the one on top, the one below). Essentially, I want the 2nd line text box to always be attached to the '1 - Bottom Corner' null which is attached to the bottom left of the first text box. I have achieved this using this script on '1 - Bottom Corner.'

 

'1 - Bottom Corner' position expression script:

targetLayer = thisComp.layer("1. Using Scenario Based Configurations ");
pos = targetLayer.transform.position;

rect = targetLayer.sourceRectAtTime();
height = rect.height;

[pos[0], pos[1] + height/2]

 

normal.png

 

Photo 2: When adjusting the font size, this interferes with the spacing and doesn't properly align with the '1 - Bottom Corner' null...

fontSize.png

 

Photo 3: When adjusting the scale of the first text box, this does not affect the spacing at all.

layerScale.png

 

The script that I have written for the second text line is:

x = thisComp.layer("1 - Bottom Corner");
pos = x.transform.position;

rect = thisComp.layer("1. Using Scenario Based Configurations ").sourceRectAtTime();

[pos[0], pos[1] + rect.height/2]

 

Let me know how else I can clarify! I feel like this should be easy in premise but it's not cooperating.

 

Thanks,

Kyle   

Translate
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 ,
Aug 18, 2020 Aug 18, 2020

I edited my post before I saw your reply.

 

Your workflow is awfully wonky. If you just want to attach the bottom text layer to the top text layer simply make the top text layer the parent of the bottom one. Scale and position will all stay relative.

 

If you want the size of the bottom text layer to stay the same you can't use a null parented to the text layer. You'll need the top of the bottom text layer + a pad value to put a little space between the top and bottom text layers, and an adjustment of the top value + padding for the bottom layer to offset the position of the bottom layer in Y while tying it to the top layer's position. 

 

Here's the expression:

src=thisLayer;
lyrSize = src.sourceRectAtTime();
txtTop = lyrSize.top;
refLayer = thisComp.layer(index - 1);
srcScale = refLayer.scale[1] * .01;
space = 30 * srcScale; // 30 is the pad value - link it to a slider
pad = txtTop - space;
pos = [refLayer.position[0], refLayer.position[1] - pad]

If you were going to use this for a bunch of text layers I would ass a slider to the expression and multiply the slider value by the srcScale.

 

It's really common to way over think expressions. 

 

If you must have some nulls in your comp to tie the layers together then you will need some toComp or toWorld language added to the mix so that the layers would maintain their relative position. You could also throw in calculations for the bottom text layer scale to modify the Top value. One more thing, the baseline for both layers should be set to zero for this to work properly. 

 

This is what the comp looks like:

Screenshot_2020-08-18 15.54.32_F4xyDk.png

Translate
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 ,
Aug 18, 2020 Aug 18, 2020

Thank you for this, Rick! I'll have to look at these expressions some more to dig through them and how they'd fit with my specific project. You gave me a lot to think about, which I truly appreciate!

 

I appreciate the suggestions and I'll reply here if I make any discoveries using your code and some more trial and error.

 

Thanks,

Kyle

Translate
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 ,
Aug 18, 2020 Aug 18, 2020

Natively, sourceRectAtTime() does not compute Layer>Transform>Scale for the layer it is referencing. It does however auto respond to resizing the Font which is accessible in the Essential Graphics Panel's, for the Source Text property when you enable Edit Properties and choose to add Enable Font Size Adjustment.

 

An alternative is to add the necessary math to the sourceRectAtTime() code that you use.

Very Advanced After Effects Training | Adaptive & Responsive Toolkits | Intelligent Design Assets (IDAs) | MoGraph Design System DEV
Translate
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 ,
Aug 18, 2020 Aug 18, 2020

Hi Roland,

Thank you for your input! The reason why I can't just use the font size adjustment is that I want to keyframe the size of the text. According to my research, the font size can only be keyframed with the scale property. I've tried countless ways to do the math with expressions but can never seem to get it to work properly.

 

I just need a way to calculate the text box height after I scale the layer which seems so difficult, at least from what I've been trying and researching.

 

To see some more specific details, check my recent post in this thread for some more detailed screengrabs, suggested by Rick.

 

Thanks,

Kyle

 

 

Translate
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 ,
Oct 26, 2020 Oct 26, 2020

Hi!

I had the same issue.

The main problem with calculating the placement is the text layer doesn't have a centered anchorpoint.

BUT you can set the font size thru expressions now and just link it to a slider then keyframe that.

style.setText(value).setFontSize(effect("size")("Slider"));

 Hope that's helpful. 🙂

Steve

Translate
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 ,
Oct 26, 2020 Oct 26, 2020

sorry, I should have said that expression goes on the SourceText property. I got too excited that I could help haha!

 

Translate
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 20, 2021 Feb 20, 2021
LATEST

I should also add that I had to switch from Legacy JavaScript to the non-legacy option in order for the "style" option to work without an error.

Translate
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 20, 2021 Feb 20, 2021

Hey Steve,

This totally worked and I think it would even solve my original question posted a few months ago. When pinning nulls to text layers to impact other layers, animating text size works whereas scale may need some custom code like Rick's answer above. This answer solves my main issues and I'm excited to try it out on the original project file and see if it'll work! You made animating font size via keyframes and/or expressions easy and I appreciate it!

 

Thanks so much,

Kyle

Translate
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