Skip to main content
filmsproket
Known Participant
October 4, 2023
Question

Position Expression for Start and End Position of Animated Shape Layer

  • October 4, 2023
  • 1 reply
  • 2306 views

The box shape in my lower third animation adjusts it's width based on the length of text through soureRectAtTime anchor point expression. Then the box is parented to a Null object to animate it and the text on and off screen.

I've attached "SSF_L3rd_AGENT.mp4" which shows the animation working.

 

It works great, but when my text gets longer the animation of that box and text doesn't start fully off screen.  Is there a position expression I can apply to the Null layer that will take into account the width of the box and start and end it off screen?

I've attached "SSF_L3rd_AGENT_tooLong.mp4" which shows the animation when the text gets longer and the box doesn't start off screen.

 

 

This topic has been closed for replies.

1 reply

Community Expert
October 4, 2023

You have not told us how you set the starting position of the shape/text layer combination. 

 

An efficient way to do this is to use sourceRecAtTime() to find the length of the shape layer, multiply those values by the scale of the layer, and then subtract that distance from zero. If you use the Left value and the width, you should be able to line things up properly. Positioning the text layer over the shape layer with expressions is also the way to go. In the animation presets that I have designed, I also use the layer's in and out points to create the move using one of the ease linear interpolation methods. 

 

If the text layer is already tied to the shape layer background, then this expression should move the shape layer from the left edge of the comp and stop the movement when the left edge of the shape layer reaches the left edge of the comp. The expression assumes that all of the internal transform properties for the shape layer are at their default values.

 

s = scale[0] / 100;
box = sourceRectAtTime();
boxW = box.width/2;
t = time;
mov = 20 * thisComp.frameDuration; // 20 frame move
x = easeOut(t, inPoint, inPoint+ mov, - boxW, boxW);

[x * s, value[1]]

If that does not help solve your problem, please drag a screenshot that shows the modified properties of the shape layer and the text layer to the reply field on the forum so we don't have to download it to see it.  

 

 

filmsproket
Known Participant
October 4, 2023

AMAZING!  This totally works and I'm so grateful.  This is my first multi-expression comp, so I'm stretching.  I would love to be able to make the easeOut more dramatic.  Is there a way to put that in the expression, where the ease is fast in the beginning and then sloooooows to a stop?

 

Also, I need my text to follow a few frames behind the box.  I wanted to use a transform.xPosition.valueAtTime expression to accomplish this, but it errors.  Plus, the text layer needs to adjust to the edge at the beginning the same as the box.  I tried to parent the text to the box, then I tried to quickwhip the position, and then I just tried to use your scripting on the text layer, but it causes the position to pop around.  Maybe there is an easy expression that I'm missing.

 

 

 

 

 

 

 

 

filmsproket
Known Participant
October 4, 2023

I probably would have done something like this to adjust the timing of the text layer. I like working in frames instead of time.

 

d = 10 * thisComp.frameDuration;
m = thisComp.layer(index+1).transform.position;
m.valueAtTime(time - d)

 

The expression will work as long as the text layer is above the background shape layer. For this kind of thing, I always use layer index instead of layer name so the expressions will always work without throwing an error.

 

You could also change the expression slightly using a value + argument so you can fine-tune the final position of the text layer by simply dragging it around after the move completes.

 

v = [thisComp.width/2, thisComp.height/2] - value;
d = 10 * thisComp.frameDuration;
m = thisComp.layer(index+1).transform.position;
v + m.valueAtTime(time - d);

 

You can also use sourceRectAtTime() for the text layer, add padding, and offset so that the text is always the same distance from the top and right edge of the background layer. We're starting to get into some pretty heady stuff that I will cover in the tutorials. 

 

Here is the basic idea:

// set variablesw
d = 10 * thisComp.frameDuration; // 10 frame delay
topPad = 30; // top padding in pixels
leftPad = 60; // left padding in pixrels
// get bg layer size and find the middle
bg = thisComp.layer(index + 1);
bgScale = bg.scale/100;
bgDim = bg.sourceRectAtTime();
bgCntr = [bgDim.width * bgScale[0], bgDim.height * bgScale[1]]/2;
// use this layer size to set top left corner
lSize = sourceRectAtTime();
lFix = [lSize.width + lSize.left, lSize.top + bgDim.height*bgScale[1]];
// set timing and text layer position
p = bg.position.valueAtTime(time-d);
p + bgCntr - lFix - [leftPad, - topPad]

I just knocked that out. The comments should help you follow the logic. 


Thanks so much for your time!  I can't seem to get any of those to work, but I'm sure it's just because I don't know what I'm doing.  I'll try to work with these in future spare time to figure out what they can do.  Thank you, Thank you!