Copy link to clipboard
Copied
Hey Pros!
I'm searching for an expression that scrolls a text sideways based on its length.
Let's say you have these two texts: «Sample» and «This is a longer sample».
The composition has a defined width that allows the shorter text «Sample» do be displayed in full length but the longer one will be cutted off somewhere in the middle of «…longer…».
My idea is to have the text scroll by from the start to its end, based on the length of the text. So, the beginning of the scentence will be shown and starts scrolling sideways until it reaches its end.
What I found are various ways to do this with a fixed length to scroll (100px to the right, …). But because I need to do this for a lot of texts it would be great to have an expression on the text layer, rewrite the text and render out the new one without manually change the scrolling position each time.
When having a shorter text like «Sample», the text can just stay where it is without moving.
Does someone have an idea how I could get this done?
Thanks in advance!
Ah! Solved!
I changed the minus to a plus here: {X=linear(time,tStart,tEnd,wPos[0],wPos[0]+wDiff)} and added a «-20» here: wDiff=wCom-wTex-20;
That's because not every text gets perfectly aligned to the left side of the comp. I now placed it a little in the comp, so every letter is fully displayed and the comp gets moved a little more (20px) than the comp width.
Here's the final expression:
tStart=0; //start time
tEnd=5; //end time
wPos=thisLayer.transform.position;
wTex=thisLayer.sourceRectAtTime
...Copy link to clipboard
Copied
A simple sourceRectAtTime() and calculating the differences will do.
tStart=0; //start time
tEnd=5; //end time
wPos=thisLayer.transform.position;
wTex=thisLayer.sourceRectAtTime().width;
wCom=thisComp.width;
wDiff=wCom-wTex;
if(wDiff >0)
{X=linear(time,tStart,tEnd,wPos[0],wPos[0]-wDiff}
else
{X=wPos[0]};
Y=wPos[1];
[X,Y]
This is the basic drill. It assumes left-aligned text. You may also need to account for padding and of course will need to tweak the values to your needs.
Mylenium
Copy link to clipboard
Copied
Hi Mylenium!
Thanks for the fast response!
When adding the expression to the position it moves every text thats shorter than the comp width. However, it should move the text if it sticks out of the comp on the right side. Is there a simple fix for that?
Thanks again!
Copy link to clipboard
Copied
If you want the text to scroll off the left side of the screen when the line is longer than the comp width, you'll need to calculate the width of the text layer, set up an if/else statement that gives you two ending values for an easeOut ineterpolation.
Try something like this for center-justified text.
w = sourceRectAtTime().width/2;
cw = thisComp.width;
t = time - inPoint;
tMin = 0;
tMax = w / cw * 5;// sets the speed
value1 = thisComp.width + w;
if (w * 2 < cw){
value2 = w + 100;
}
else{
value2 = cw - w - 100
}
x = easeOut(t, tMin, tMax, value1, value2);
y = value[1];
[x, y]
Copy link to clipboard
Copied
@Rick Gerard Thanks for your help!
I tried to put in this expression on scale that keeps the text in the comp (scaling down text size):
// grab sourceRect based on layer time
R = sourceRectAtTime(sourceTime(time), true);
// find the center, and use sourceRect offsets
x = (R.width/2) + R.left;
y = (R.height/2) + R.top;
[x,y]
But the problem here is as you mentioned: The text is getting smaller. That would be the solution if I wouldn't need to scroll - just scaling and placing the text.
I think the solution @Mylenium suggested sounds right but needs to be tweaked a little so the short texts remain on position while longer texts scroll by.
Copy link to clipboard
Copied
I rethought my answer and gave you a different expression. Instead of scaling, I just let the left edge run off the screen if it was longer than the frame. The speed changes with longer text. I didn't take the time to create a constant speed, but it can probably be done. If I think of a solution I'll let you know.
Copy link to clipboard
Copied
Messed up the math. Here's soemthing that should work
tStart=0; //start time
tEnd=5; //end time
wPos=thisLayer.transform.position;
wTex=thisLayer.sourceRectAtTime().width;
wCom=thisComp.width;
wDiff=wCom-wTex;
if(wDiff < 0)
{X=linear(time,tStart,tEnd,wPos[0],wPos[0]-wDiff}
else
{X=wPos[0]};
Y=wPos[1];
[X,Y]
Mylenium
Copy link to clipboard
Copied
Hi @Mylenium
That one works but it moves the text to the wrong side. (I attached an mp4)
I think the expression is close to final 😉 Thanks again!
Copy link to clipboard
Copied
Ah! Solved!
I changed the minus to a plus here: {X=linear(time,tStart,tEnd,wPos[0],wPos[0]+wDiff)} and added a «-20» here: wDiff=wCom-wTex-20;
That's because not every text gets perfectly aligned to the left side of the comp. I now placed it a little in the comp, so every letter is fully displayed and the comp gets moved a little more (20px) than the comp width.
Here's the final expression:
tStart=0; //start time
tEnd=5; //end time
wPos=thisLayer.transform.position;
wTex=thisLayer.sourceRectAtTime().width;
wCom=thisComp.width;
wDiff=wCom-wTex-20;
if(wDiff < 0)
{X=linear(time,tStart,tEnd,wPos[0],wPos[0]+wDiff)}
else {X=wPos[0]};
Y=wPos[1];
[X,Y]
Thanks guys for your help! I really appretiate it!
Copy link to clipboard
Copied
Here is a simpler expression with a little better speed control.
w = sourceRectAtTime().width/2;
cw = thisComp.width;
t = time - inPoint;
s = 3;//speed multiplier
value1 = thisComp.width + w;
if (w * 2 < cw){
value2 = w + 100;
}
else{
value2 = cw - w - 100
}
x = easeOut(t / s, value1, value2);
y = value[1];
[x, y]
Give that one a try.
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more