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

Scroll variable text lenghts

Explorer ,
Jan 16, 2023 Jan 16, 2023

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!

TOPICS
Expressions
955
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

correct answers 1 Correct answer

Explorer , Jan 17, 2023 Jan 17, 2023

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

...
Translate
LEGEND ,
Jan 16, 2023 Jan 16, 2023

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

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
Explorer ,
Jan 16, 2023 Jan 16, 2023

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!

 

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 ,
Jan 16, 2023 Jan 16, 2023

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]

 

 

 

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
Explorer ,
Jan 16, 2023 Jan 16, 2023

@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.

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 ,
Jan 16, 2023 Jan 16, 2023

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.

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
LEGEND ,
Jan 16, 2023 Jan 16, 2023

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

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
Explorer ,
Jan 17, 2023 Jan 17, 2023

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!

 

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
Explorer ,
Jan 17, 2023 Jan 17, 2023
LATEST

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!

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 ,
Jan 16, 2023 Jan 16, 2023

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.

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