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

Change X position with condition

New Here ,
Dec 04, 2022 Dec 04, 2022

I wrote a simple script, but it doesn't work. In the composition there is one circle with a position of 0, 0. I expect the circle to go down 10 pixels and then change the X position to a random one and go down 10 pixels again. But the condition of the IF loop does not work. The circle just keeps going down and doesn't change position. What did I do wrong?

 

if(position[1]<=-10){ [position[0],position[1]+Math.round(time)] } else { [random(width),-10] }

TOPICS
Expressions
987
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 ,
Dec 04, 2022 Dec 04, 2022

Your expression says if the Y position is less than or equal to minus ten keep the X position the same and add  one to the current Y position every second but if the Y position is greater than minus 10 make the X position random and keep the Y position at minus 10. 

 

A position of 0, 0 would put the circle in the top left corner of a composition unless the circle is the child of. another layer. 

 

A random value for x is going to change every frame. If the layer is anywhere above minus ten, it will move down one frame every second, but the else condition will never cause random movement in x because it is looking at the Y position before the expression moves it down. If the original position for Y is -10 or more, then the layer will never move down, it will just randomly move in X every frame. 

 

I'm not sure what you want to happen. If you want the layer to jump down 10 pixels every second then you simply add 10 to the Y value every second. 

y = value[1] + 10 * Math.round(time);
[value[0], y]

If you want to also have a random X position every second, then you need to set the random seed to change every second and then establish a random number range based around the comp center.

y = value[1] + 10 * Math.round(time);
seedRandom(Math.round(time), true);
x = thisComp.width/2 + random(200);
	
[x, y]

 There is no if condition required. You could modify the expression so that you could place the layer anywhere you want to start and it would move down 10 frames every second and have a new random x position plus or minus 200 pixels from the original position by using this expression:

y = value[1] + 10 * Math.round(time);
seedRandom(Math.round(time), true);
x = value[0] + random(200);
	
[x, y]

That is how I usually write expressions that automatically move layers. Using the value of the property in an expression even allows you to animate the movement of the layer and throw in the random movement. 

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
New Here ,
Dec 04, 2022 Dec 04, 2022

Rick, thanks for the tips, they helped a lot. But I need to use the IF statement, because I want to start the animation again from above (Y = 0) after let's say Y becomes 200

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 ,
Dec 04, 2022 Dec 04, 2022

The code is never going to do anything. Aside from the random stuff not making sense, there's the simple matter of your coordinates being upside down. And in expansion to Rick's explanations you probably don't even need any expressions. this could be thrown together by parenting the Circle to a Null and animating the positions with a bunch of keyframes - Y on the Null, the rest on the circle itself.

 

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
New Here ,
Dec 04, 2022 Dec 04, 2022

Hi, Mylenium. I need to write code that will animate circle movement from top to bottom and start again when the circle leaves the Comp visible window. The fact is that in this code, the IF condition simply does not work. Why I can't understand.

if(position[1]<=height) {

[position[0],position[1]+Math.round(time)]

}
else {

[random(width),-10]

}

 

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 ,
Dec 04, 2022 Dec 04, 2022

I apologize if I'm misreading the situation, but it seems that maybe you're not aware of one of the key limitations of expressions, which is an expression has no memory and thus no access to anything it has calculated at previous frames. So when you use position[1], you will always get the pre-expression value, not the value that your expression calculated on the previous frame. To get around this limitation, you generally need to make your expression a function of time, as in Rick's examples.

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 ,
Dec 05, 2022 Dec 05, 2022
LATEST

Your expression says that if the X position is less than or equal to the layer's height, add 1 to the Y value.  It also says if the X position is greater than the height of the layer to make the X position a random value between zero and the layer width. 

 

The problem is if you start out with the layer lower than the layer height, you get the second half of the expression working. The layer will have a random X position but the Y position will not change. 

 

If you start out with the layer with a Y position value equal to or less than the layer height, the expression will add 1 to the original layer's Y position for every second the comp runs. If the comp runs 10 seconds long, the layer will move down in Y 10 pixels. The "else" part of the statement is never activated because you use the original Y position instead of the value at time for Y generated by the expression. 

 

Start with Y less than the layer height, and the layer will move down one pixel per second. Start with the Y value greater than the height of the layer, and the X value will be a random number between zero and the layer width and the Y value will never change. 

 

If you want an expression to move a layer down until it reaches the bottom of the frame, then pop it up to the top and start down again, you have to set up the Y part of your expression so that it starts animating the layer's position at the layer in-point by moving the layer above the top of the composition, then move the layer down until it leaves the bottom of the comp panel. To simplify things, the Anchor Point must be in the middle of the layer. You need to calculate half the layer height and subtract that from Zero (top Y) for the first frame, then move down a specific number of frames per second until the position equals the Composition Height + half the Layer height. Then you have to use a calculation of how long that move will take instead of the Y position to make the loop start over again. There would be no if/else statement in an expression that looped a move from the top to the bottom of the frame.

 

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