The Expressions Thread

MartinLemaire said
felt_tips said
MartinLemaire said

Hey, it’s me again :smiley:
i’m still stuck, how can i parent only the vertical size of a layer to the vertical size of another layer ?
Thanks a lot for your help guys

On Scale:

L = thisComp.layer("whatever");
[value[0], L.transform.scale[1]];

It doesn’t work for me.


As you can see, i’m trying to parent the horizontal size (not the vertical) of the layer called “Background” to the horizontal size of the “Rectangle 1” contained in the layer called “Frame”, the rectangle is parented to a slider so the client can easily slide the horizontal scale.
Thanks again for your help

That’s because you’re not using the Scale of the Frame layer, you’re altering the Size of the vector. Use the same principle as outlined above, but pick-whip the X component of the Size instead. Be aware though that Size is a pixel size and Scale is a percentage, so you will have to divide the pick-whipped value by the pixel width of the layer with the expression on and then multiply by 100 to get the percentage that you need to scale. To get the width of the layer with the expression on use thisLayer.source.width.

Unfortunately I have 2 weeks of very intensive work as of today, so I most likely won’t be able to go into greater depth until after that.

After reading 20 times your answer, i still don’t understand what you mean, does anyone else could help me ? Thanks

MartinLemaire said

After reading 20 times your answer, i still don’t understand what you mean, does anyone else could help me ? Thanks

Since you’re using the Size property of the vector rectangle to adjust the size of the layer “Frame” and not its Transform → Scale property, you need to link the Scale of the layer “Background” to this Size property, not the Scale property.

Because the Size property is in pixels and the Scale property that you want to link to it is a percentage, you need to work out what Scale you will need to make the layer “Background” have the same pixel width as the layer “Frame”. To do this, you divide the target width in pixels by the width of the layer “Background”'s source and multiply by 100. The code is below. Take some time if you can to study and understand it.

L = thisComp.layer("Frame");
currentWidth = thisLayer.source.width;
targetWidth = thisComp.layer("Frame").content("Rectangle Path 1").size[0];
tWidth = 100*targetWidth/currentWidth;
[tWidth, value[1]];

Note: this code will only work if the Scale of the layer “Frame” is 100%. Otherwise, the code needs to be somewhat more complex. Also, if you scale the layer “Frame” by making it the child of another layer and then scaling that, this code will fall down (in that case it would need to get quite a lot more complex still).

Hello everyone,

I have an issue with markers and keyframes, to be more precise with connecting keyframes with markers. So, I have a time remapping on my composition, and its ok when it’s 2 keyframes, but when i want to add more, for example to reverse animation, I get stuck.
i have tried to add more, but it doesn’t work. Hope you guys have a solution.


soundeleon said

Hello everyone,

I have an issue with markers and keyframes, to be more precise with connecting keyframes with markers. So, I have a time remapping on my composition, and its ok when it’s 2 keyframes, but when i want to add more, for example to reverse animation, I get stuck.
i have tried to add more, but it doesn’t work. Hope you guys have a solution.


The problem is that you’re specifically referring to the keyframe number 2, but you’re only checking that there is one or more keyframes.

What you actually need to do is check the previous and the next keyframe. Sounds like a similar job to what I posted for Amberija a couple of days ago.

But until you give me a better description of what it is you’re trying to achieve, I can’t help much further.

It does strike me as though you’re trying to use markers as pseudo-keyframes though. I really wouldn’t bother with this. If you get into this way of working (presumably to make life ‘easier’ for template customers), what you’re actually doing is making a lot of extra coding work for yourself, and a lot of overheads for After Effects to (unnecessarily) calculate on every frame. You need to check a lot of things - are there the same number of keyframes as markers? Are you before the first marker or after the last marker? What happens if the user starts deleting markers or keyframes?

The much better solution is to direct the user how to move the positions of the keyframes. Creating an ease, cubic or exponential curves between linear keyframes is still a bit of work, but you can cut out the whole error checking side of things.

I was actually trying to make a pseudo keyframes, to “replace” 4 keyframes on time remapping, just to make it easier for customers to change the speed and time of animation. I thought it would be a cleaner look. So far in my files I have instructed the users to move the keyframes, and you are right, that is probably a better idea. But I would really wanna know, it’s killing me :smiley:
Thank you so much for your advice felt tips. :slight_smile:

Hey all. I just can’t find answer it or i just missed it, but my question is…
Is there a way to change source text color, font and size but to affect my “parent” text?
Thank’s

3eka said

Hey all. I just can’t find answer it or i just missed it, but my question is…
Is there a way to change source text color, font and size but to affect my “parent” text?
Thank’s

You can cheat source text color and size, but you still can’t change a font using expressions as far as I’m aware.

You can cheat source text color and size, but you still can't change a font using expressions as far as I'm aware.
Yeah, figured that out. Font can be just hard scaled and colors can be filled, while font type is still...Anyway thank you, i did it hard way, pre-compose, pre-compose...endlessly :)

Hi there,

is there some way to automatically precompose all the layers with track matte layer on, into the new compositions? So, if I have 200 layers, 100 layers are main layers and 100 layers are hidden track matte layers for each layer, and I need to precompose all the layers separately to have only 100 layers, and not 200.

Or, if this is not possible… if I select all the main 100 layers can I also add to this selection it’s track matte layers. So, what I need is to add to my current selection all the layers above each selected layer.

Maybe it sounds confusing, but I have 5000 layers and I need to isolate some of them, but I really don’t want to do it manually :slight_smile:

Thanks for any ideas…

It’s SOLVED with a script…

Thanks again!

3Dspace said

It’s SOLVED with a script…

Thanks again!

Yep… definitely a scripting thing. Expressions are for creating dynamic relationships within an existing structure. If you want to change the structure, you need scripting (which you can think of as a kind of macro for user input).

soundeleon said

Hello everyone,

I have an issue with markers and keyframes, to be more precise with connecting keyframes with markers. So, I have a time remapping on my composition, and its ok when it’s 2 keyframes, but when i want to add more, for example to reverse animation, I get stuck.
i have tried to add more, but it doesn’t work. Hope you guys have a solution.

Maybe something like that?

t1 = L.marker.key(1).time;
t2 = L.marker.key(2).time;
t3 = L.marker.key(3).time;
t4 = L.marker.key(4).time;
v1 = valueAtTime(key(1).time);
v2 = valueAtTime(key(2).time);
v3 = valueAtTime(key(3).time);
v4 = valueAtTime(key(4).time);
if (time < t2) {
\tlinear(time,t1,t2,v1,v2);
} else if (time <t3) {
\tlinear(time,t2,t3,v2,v3);
} else {
\tlinear(time,t3,t4,v3,v4);
}

I’m doing something similar, but with a general control to change the duration of the animations (logo in, logo middle static, and logo out).

fps = 1 / thisComp.frameDuration;

//load slider values
lid=comp("controls").layer("controls").effect("logo-in-duration")(1)*fps;
lmd=comp("controls").layer("controls").effect("logo-middle-duration")(1)*fps;
lod=comp("controls").layer("controls").effect("logo-out-duration")(1)*fps;

//calculate markers
m1 = 0;
m2 = framesToTime(lid);
m3 = framesToTime(lid+lmd);
m4 = framesToTime(lid+lmd+lod);

//in, middle and out points at the original animation, in seconds
k1 = 0;
k2 = 3;
k3 = 5;

//my formulas for time remap
if(time<m2){
\tlinear(time, m1, m2, k1, k2);
} else if (time<m3){
\tlinear(time, m2, m3, k2, k2);
} else {
\tlinear(time, m3, m4, k2, k3);
}

I’m not sure if it’s the best way, but it works for me :slight_smile:

Sorry for my English!

felt_tips said
3Dspace said

It’s SOLVED with a script…

Thanks again!

Yep… definitely a scripting thing. Expressions are for creating dynamic relationships within an existing structure. If you want to change the structure, you need scripting (which you can think of as a kind of macro for user input).

Thank you felt_tips!

Sometimes we spend hours trying to find some workarounds, and yet scripts are so powerful and can solve our problem in just a few lines.

||+1194484|ilovemedia-es said-||
soundeleon said

Hello everyone,

I have an issue with markers and keyframes, to be more precise with connecting keyframes with markers. So, I have a time remapping on my composition, and its ok when it’s 2 keyframes, but when i want to add more, for example to reverse animation, I get stuck.
i have tried to add more, but it doesn’t work. Hope you guys have a solution.

Maybe something like that?

t1 = L.marker.key(1).time;
t2 = L.marker.key(2).time;
t3 = L.marker.key(3).time;
t4 = L.marker.key(4).time;
v1 = valueAtTime(key(1).time);
v2 = valueAtTime(key(2).time);
v3 = valueAtTime(key(3).time);
v4 = valueAtTime(key(4).time);
if (time < t2) {
\tlinear(time,t1,t2,v1,v2);
} else if (time <t3) {
\tlinear(time,t2,t3,v2,v3);
} else {
\tlinear(time,t3,t4,v3,v4);
}

I’m doing something similar, but with a general control to change the duration of the animations (logo in, logo middle static, and logo out).

fps = 1 / thisComp.frameDuration;

//load slider values
lid=comp("controls").layer("controls").effect("logo-in-duration")(1)*fps;
lmd=comp("controls").layer("controls").effect("logo-middle-duration")(1)*fps;
lod=comp("controls").layer("controls").effect("logo-out-duration")(1)*fps;

//calculate markers
m1 = 0;
m2 = framesToTime(lid);
m3 = framesToTime(lid+lmd);
m4 = framesToTime(lid+lmd+lod);

//in, middle and out points at the original animation, in seconds
k1 = 0;
k2 = 3;
k3 = 5;

//my formulas for time remap
if(time<m2){
\tlinear(time, m1, m2, k1, k2);
} else if (time<m3){
\tlinear(time, m2, m3, k2, k2);
} else {
\tlinear(time, m3, m4, k2, k3);
}

I’m not sure if it’s the best way, but it works for me :slight_smile:

Sorry for my English!

Perfect! Thank you so much!
I have tried something similar but it did’t work.
This is exactly what I was trying to achieve.
Thanks again. :slight_smile:

soundeleon said

Perfect! Thank you so much!
I have tried something similar but it did’t work.
This is exactly what I was trying to achieve.
Thanks again. :slight_smile:

Glad to have helped :slight_smile:

I was reading the felt_tips reply, and I think if you use my method (with slider controls), it is unlikely that an error occurs, because you don’t need markers, and the keyframes are irrelevant. And customers do not even need to get into that comp to modify the duration.

Another advantage is that customers can modify the length of several comps from a single control. This is useful if you want to change in the same way different animations (in my case, social logos)

||+1194484|ilovemedia-es said-||
fps = 1 / thisComp.frameDuration;

//load slider values
lid=comp("controls").layer("controls").effect("logo-in-duration")(1)*fps;
lmd=comp("controls").layer("controls").effect("logo-middle-duration")(1)*fps;
lod=comp("controls").layer("controls").effect("logo-out-duration")(1)*fps;

//calculate markers
m1 = 0;
m2 = framesToTime(lid);
m3 = framesToTime(lid+lmd);
m4 = framesToTime(lid+lmd+lod);

//in, middle and out points at the original animation, in seconds
k1 = 0;
k2 = 3;
k3 = 5;

//my formulas for time remap
if(time<m2){
\tlinear(time, m1, m2, k1, k2);
} else if (time<m3){
\tlinear(time, m2, m3, k2, k2);
} else {
\tlinear(time, m3, m4, k2, k3);
}

Is there any way to create or move a marker dynamically or to change the outPoint? I’m doing a time remap and I would like the customer had any visual information about where the animation ends. Thanks!

felt_tips said
MartinLemaire said

After reading 20 times your answer, i still don’t understand what you mean, does anyone else could help me ? Thanks

Since you’re using the Size property of the vector rectangle to adjust the size of the layer “Frame” and not its Transform → Scale property, you need to link the Scale of the layer “Background” to this Size property, not the Scale property.

Because the Size property is in pixels and the Scale property that you want to link to it is a percentage, you need to work out what Scale you will need to make the layer “Background” have the same pixel width as the layer “Frame”. To do this, you divide the target width in pixels by the width of the layer “Background”'s source and multiply by 100. The code is below. Take some time if you can to study and understand it.

L = thisComp.layer("Frame");
currentWidth = thisLayer.source.width;
targetWidth = thisComp.layer("Frame").content("Rectangle Path 1").size[0];
tWidth = 100*targetWidth/currentWidth;
[tWidth, value[1]];

Note: this code will only work if the Scale of the layer “Frame” is 100%. Otherwise, the code needs to be somewhat more complex. Also, if you scale the layer “Frame” by making it the child of another layer and then scaling that, this code will fall down (in that case it would need to get quite a lot more complex still).

Thanks again for your answer, unfortunatly, i’m scaling the ‘‘frame’’ layer trought a slider located on itself, as you said, if it is too tricky and too time consuming for you to write it, i’ll understand, don’t worry.

MartinLemaire said
felt_tips said
MartinLemaire said

After reading 20 times your answer, i still don’t understand what you mean, does anyone else could help me ? Thanks

Since you’re using the Size property of the vector rectangle to adjust the size of the layer “Frame” and not its Transform → Scale property, you need to link the Scale of the layer “Background” to this Size property, not the Scale property.

Because the Size property is in pixels and the Scale property that you want to link to it is a percentage, you need to work out what Scale you will need to make the layer “Background” have the same pixel width as the layer “Frame”. To do this, you divide the target width in pixels by the width of the layer “Background”'s source and multiply by 100. The code is below. Take some time if you can to study and understand it.

L = thisComp.layer("Frame");
currentWidth = thisLayer.source.width;
targetWidth = thisComp.layer("Frame").content("Rectangle Path 1").size[0];
tWidth = 100*targetWidth/currentWidth;
[tWidth, value[1]];

Note: this code will only work if the Scale of the layer “Frame” is 100%. Otherwise, the code needs to be somewhat more complex. Also, if you scale the layer “Frame” by making it the child of another layer and then scaling that, this code will fall down (in that case it would need to get quite a lot more complex still).

Thanks again for your answer, unfortunatly, i’m scaling the ‘‘frame’’ layer trought a slider located on itself, as you said, if it is too tricky and too time consuming for you to write it, i’ll understand, don’t worry.

Without seeing the exact set-up of your project, Martin, I’m really only guessing about what you’re trying to do. If you’re finding it hard to write the code, imagine what it’s like without the project in front of you. If you want to send me your project (minus all assets) I can take a look, but it might not be for a week or so. I’m inundated with work at the moment.

Hello guys, is it possible to set a specific time to start at a layer marker ?

For example:

time flows normally :
1s,2s,3s,4s,5s…

Then, when the time indicator reachs the marker it jumps to 30s and flows from that point:
30s,31s,32s,33s…

Is it possible ?