Skip to main content
Participant
January 28, 2023
Answered

How would I create a cascading list that scales dynamically?

  • January 28, 2023
  • 2 replies
  • 628 views

I'm looking to create a repeating list of words, that when animated go from around 40% scale at the top and bottom to 100% scale at the center, also the words should go down in opacity at the extremities.

 

I've set up my composition with the list of words arranged vertically, a null at the center and the following script on each text layer (anchor point on each text layer is set to the middle left)...

For Scale:

distMax = thisComp.layer("Center Null 1").effect("DistanceMax")("Slider");

distMin = thisComp.layer("Center Null 1").effect("DistanceMin")("Slider");

scaleMax = thisComp.layer("Center Null 1").effect("ScaleMax")("Slider");

scaleMin = thisComp.layer("Center Null 1").effect("ScaleMin")("Slider");

pos = length(position, thisComp.layer("Center Null 1").position);

sca = easeOut(pos, distMax, distMin, scaleMax, scaleMin);

[sca, sca]

 

For Opacity:

distMax = thisComp.layer("Center Null 1").effect("DistanceMax")("Slider");

distMin = thisComp.layer("Center Null 1").effect("DistanceMin")("Slider");

opacMax = thisComp.layer("Center Null 1").effect("OpacityMax")("Slider");

opacMin = thisComp.layer("Center Null 1").effect("OpacityMin")("Slider");

pos = length(position, thisComp.layer("Center Null 1").position);

opac = ease(pos, distMax, distMin, opacMax, opacMin);

[opac]

 

I set slider controls on the Center Null so I can control the values of the minimum and maximum scale and opacity, as well as the distance from the Center Null that those min's and max's should apply.

 

So far I've got half what I'm looking for (see below)

However, I'm looking to have the leading (line spacing) scale proportionally with the text scale (see below)

I tried creating a padding script to the position property, but it seems to work correctly when the list is in one position, but bunch up the text when it's in another (script below)...

distMax = thisComp.layer("Center Null 1").effect("DistanceMax")("Slider");

distMin = thisComp.layer("Center Null 1").effect("DistanceMin")("Slider");

padMax = thisComp.layer("Center Null 1").effect("PaddingMax")("Slider");

padMin = thisComp.layer("Center Null 1").effect("PaddingMin")("Slider");

mid = length(position, thisComp.layer("Center Null 1").position);

pos = easeOut(mid, distMax, distMin, padMax, padMin);

pad = thisComp.layer(index-1).transform.yPosition;

[pad-pos]

 

What am I missing, and how could this be achieved?

This topic has been closed for replies.
Correct answer Rick Gerard

Try adding these expressions to a text layer:

// Scale
h = sourceRectAtTime(inPoint).height/2;
c = thisComp.height/2;
p = position[1];
t = Math.abs(c - p);
s = ease(t, h, 150, 100, 50);
[s, s]

//Opacity
h = sourceRectAtTime().height/2;
c = thisComp.height/2;
p = position[1];
t = Math.abs(c - p);
s = ease(t, h, 90, 100, 50);

Now you have a text layer that will scale from 50% to 100% as soon text above it approaches the center of the comp, and the opacity will also change at the same time.

 

Duplicate the text layer and add this expression to the bottom layer's position property:

//Position on layer under main text layer.
ref = thisComp.layer(index - 1);
th = ref.sourceRectAtTime().height;
p = ref.position;//
c = thisComp.height/2;
p2 = position[1];
t = Math.abs(c - p2);
s = ease(t, th, 150, 100, 50);
pad = 1.6; //padding
y = s * pad + p[1];
x = p[0];
[x, y]

You can then animate the position of the top layer, and the layers below will stack up below it and follow the layer as it moves up or down on the screen.

 

Fiddle with the values to get the spacing you want.

 

I used an Angle Angle Control to animate the position of the top layer so that I could just keep rotating the angle, and every layer below would follow. It made it easier to control the movement. Here's the expression for that:

//Position
y = effect("Angle Control")("Angle")/360 * thisComp.height;
[value[0], thisComp.height - y]

I hope this helps. I think it is the easiest way to stack up layers and animate scale and opacity. 

 

2 replies

Community Expert
January 29, 2023

I would use sourceRectAtTime().height to measure the height of each text layer, add some padding, and add in the sRAT().height/2 + SRAT().top multiplied by the ratio of the comp height and position of the layer to automatically set the spacing and adjust the opacity of the layer below and also adjust the scale based on the percentage of the comp height. You would look at the layer above using ref = this.Comp.layer(index -1); to keep the layers separated by a specific padding amount.

 

When you get one layer moving up the screen, automatically adjusting the opacity and scale based on layer position, you would have to duplicate that layer as many times as you like, and they would all follow. 

 

If I geet a little free time this evening, I will work out the expressions and share them.

Rick GerardCommunity ExpertCorrect answer
Community Expert
January 29, 2023

Try adding these expressions to a text layer:

// Scale
h = sourceRectAtTime(inPoint).height/2;
c = thisComp.height/2;
p = position[1];
t = Math.abs(c - p);
s = ease(t, h, 150, 100, 50);
[s, s]

//Opacity
h = sourceRectAtTime().height/2;
c = thisComp.height/2;
p = position[1];
t = Math.abs(c - p);
s = ease(t, h, 90, 100, 50);

Now you have a text layer that will scale from 50% to 100% as soon text above it approaches the center of the comp, and the opacity will also change at the same time.

 

Duplicate the text layer and add this expression to the bottom layer's position property:

//Position on layer under main text layer.
ref = thisComp.layer(index - 1);
th = ref.sourceRectAtTime().height;
p = ref.position;//
c = thisComp.height/2;
p2 = position[1];
t = Math.abs(c - p2);
s = ease(t, th, 150, 100, 50);
pad = 1.6; //padding
y = s * pad + p[1];
x = p[0];
[x, y]

You can then animate the position of the top layer, and the layers below will stack up below it and follow the layer as it moves up or down on the screen.

 

Fiddle with the values to get the spacing you want.

 

I used an Angle Angle Control to animate the position of the top layer so that I could just keep rotating the angle, and every layer below would follow. It made it easier to control the movement. Here's the expression for that:

//Position
y = effect("Angle Control")("Angle")/360 * thisComp.height;
[value[0], thisComp.height - y]

I hope this helps. I think it is the easiest way to stack up layers and animate scale and opacity. 

 

Participant
January 29, 2023

Thanks Rick, worked like a dream!

Mylenium
Legend
January 28, 2023

The padding itself of course also needs to be piped through an ease() or linear() function.

 

Mylenium 

Participant
January 28, 2023

Thanks Mylenium,

 

I might add, I'm a complete newbie with scripting, what I wrote was based on my ancient flash actionscript knowledge (from 2005) and looking at examples online.

 

I added a ease() to the padding and it made it look like this...

I think I'm missing something in my setup of the rig. I think I need to add a variable for 'current position' but I don't even know where to begin with that, being that my padding script lives in the position property.