ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

Trigger Pre-Comped Animation through Condition

COW Forums : Adobe After Effects Expressions

<< PREVIOUS   •   FAQ   •   VIEW ALL   •   PRINT   •   NEXT >>
Michael Müller
Trigger Pre-Comped Animation through Condition
on Jan 8, 2019 at 5:13:15 pm
Last Edited By Michael Müller on Jan 8, 2019 at 5:14:42 pm

I certainly think it's possible but just can't wrap my head around it.

I'm trying to tweak dan's famous "triggering animation with markers" expression on a time remap, so that a pre-comped animation, which has a named marker before it, gets triggered. Just not by a marker. I want it to be triggered, whenever a certain condition in the main comp is true.

The condition is simply:
if (a>b) {c} else d
I want to trigger the animation whenever d is true and have nothing happening whenever c is true.

My comp so far is very dynamic and I want to be flexible with tweaking currently set values, that's why I want to set up the expression.

here is the original code, in case you are unfamiliar with it: http://motionscript.com/design-guide/marker-sync.html

Thanks,

Michael


Return to posts index

Dan Ebberts
Re: Trigger Pre-Comped Animation through Condition
on Jan 8, 2019 at 5:41:58 pm

>I want to trigger the animation whenever d is true

I suspect that what you really want is:

to trigger the animation whenever d becomes true

The trick is to figure out the most recent time when d became true, subtract that from the current time, and the result is how far into the animation you should be. The best way to do that depends on the nature of the calculation...


Dan



Return to posts index

Michael Müller
Re: Trigger Pre-Comped Animation through Condition
on Jan 8, 2019 at 6:47:37 pm

I see what you are saying, Indeed I only want to trigger it when d becomes true, once for every time.
How do I return the most recent time when d becomes true? I could only figure out how to return the time-value constantly until d is not true anymore but I guess that doesn't help me much.

Thanks,

Michael


Return to posts index


Dan Ebberts
Re: Trigger Pre-Comped Animation through Condition
on Jan 8, 2019 at 7:01:15 pm

It depends on what the condition is. Sometimes it's possible to calculate how long ago the condition went try. But if not, you may have to backtrack, frame-by-frame until you find the most recent frame where the condition went from false to true (or you get to frame 0).

Dan



Return to posts index

Michael Müller
Re: Trigger Pre-Comped Animation through Condition
on Jan 8, 2019 at 7:18:45 pm

I have two layers, AA and BB, randomly swinging from left to right. I am comparing the positions of both and d to become true when the x value of BB is lower than the x value of AA.

I am not very familiar with try and catch, but I assume you would have to have a condition that doesn't change it's value while it's true for the first method you mentioned, am I right?
I think I would have to set up some kind of loop, which goes through every frame until it finds one that is different.
I am aware that I would need
frame = Math.round(time/thisComp.frameDuration);
and some if statement with frame-- as the else
but I am not very sure. This seems way more complicated than I thought.

Maybe you can give me another hint, there is something I am missing here.

Thanks,

Michael


Return to posts index

Dan Ebberts
Re: Trigger Pre-Comped Animation through Condition
on Jan 8, 2019 at 7:36:44 pm

This is an example. Apply it to a slider in your comp a look at it in the graph editor and watch how it relates to the x positon of BB compared to AA. You would use variable t to drive your animation.


a = thisComp.layer("AA").transform.position;
b = thisComp.layer("BB").transform.position;
if (b[0] < a[0]){
t0 = time - thisComp.frameDuration;
while (t0 >= 0){
if (b.valueAtTime(t0)[0] >= a.valueAtTime(t0)[0]){
break;
}
t0 -= thisComp.frameDuration;
}
t0 += thisComp.frameDuration;
t = time - t0;
}else{
t = 0;
}



Dan



Return to posts index


Michael Müller
Re: Trigger Pre-Comped Animation through Condition
on Jan 8, 2019 at 8:54:31 pm

First of all: thank you very much. I think I understand whats happening. In my Intention to truly learn from you, I have a few questions. I'll try to recap what I do understand as well. Correct me if I am wrong.

t0 = time - thisComp.frameDuration; // you're setting t0 equal to one frame?

why is the "t0" in a.valueAtTime(t0). I never really understood this fully. I understand that if you have property.valueAtTime(time-1) you delay it by 1 second, and I do understand that in this line:

if (b.valueAtTime(t0)[0] >= a.valueAtTime(t0)[0]){

you are comparing two frames by their value in time but I never knew exactly what it means to have something stand in parenthese after a command like this. It seems obvious but I can't grasp what it means in general. (I'd google it but I don't know the name of what I'm looking for)

break interrupts the time loop. I get that. To my eye it looks like thats already it but its obviously not and what is following I just cannot grasp:

t0 -= thisComp.frameDuration; // doesn't thisComp.frameDuration equal one frame? Wouldnt that mean that you're setting one frame equal to.. uhm.. one frame-one frame? It's obviously not a number but what is it then?
}
t0 += thisComp.frameDuration; // 1 = 1+1 ??
t = time - t0; // what is t0 equal in the end? I've never seen a nested condition like this

I see it's necessary for completing the code but I just cannot understand what it means.


Return to posts index

Dan Ebberts
Re: Trigger Pre-Comped Animation through Condition
on Jan 8, 2019 at 9:35:00 pm

>you're setting t0 equal to one frame?

No, I'm initializing t0 to the current time minus one frame.

>why is the "t0" in a.valueAtTime(t0)

Because I need the value a's position at time t0.

>t0 -= thisComp.frameDuration; // doesn't thisComp.frameDuration equal one frame?

No, this decrements t0 by the duration of one frame. The result is that each time through the loop, t0 gets a frame closer to 0.

>t0 += thisComp.frameDuration; // 1 = 1+1 ??

We're looking for the frame where the condition went from false to true. When the loops ends, t0 will be set to one frame prior to that, so we need to increment it by one frame.

>t = time - t0; // what is t0 equal in the end?

The time when the condition went from false to true. The whole point of the loop. ☺

Dan



Return to posts index

Michael Müller
Re: Trigger Pre-Comped Animation through Condition
on Jan 9, 2019 at 12:05:47 pm

After a few hours of taking this code apart and trying to understand it, I think I an idea of what's going on. Definitely at least learned few things.

Now there is still one problem, which is what you talked about earlier. The Animation gets triggered when the condition is true, not when it becomes true, which is to say that once the condition becomes true, the time value of the animation is stuck on 0 until the condition is no longer true again.

what am I missing?

Thanks,

Michael


Return to posts index


Dan Ebberts
Re: Trigger Pre-Comped Animation through Condition
on Jan 9, 2019 at 1:03:56 pm

Did you look at the result of the expression in the Graph Editor? Whenever BB moves to the left of AA, you get a ramp up from zero, which should drive your animation.

Dan



Return to posts index

Michael Müller
Re: Trigger Pre-Comped Animation through Condition
on Jan 9, 2019 at 1:55:33 pm
Last Edited By Michael Müller on Jan 9, 2019 at 6:37:44 pm

Yes, I looked at it and it clearly shows what is happening. I now understand how the loop is driving the animation. Now it almost works. Unfortunately, the loop stops as soon as the condition is false again ant the time value drops to zero before the animation is finished.

I thought it would help me to count the number of Iterations of the loop while the condition is true. I thought I could somehow force the loop to continue until a certain number of Iterations is reached. Here is what I got:

curFrame = 0;
frameCount = 0;

while (curFrame <= timeToFrames(time)){
if (b.valueAtTime(framesToTime(curFrame))[0] <= a.valueAtTime(framesToTime(curFrame))[0]){
frameCount++;
}
curFrame++;
}

Returning frameCount shows the number of Iterations, the number of completed frame-steps before the animation stops
I don't know how to force the loop to continue. I thought I could reset the number by adding a limit and then limiting the number of Iterations the loop can have to not make it crash. Does that make sense?

Thanks,

Michael


Return to posts index

Dan Ebberts
Re: Trigger Pre-Comped Animation through Condition
on Jan 9, 2019 at 8:26:03 pm

That changes things quite a bit, but it brings up a couple of questions: What happens when it gets to the end of the animation? What happens if the animation gets re-triggered (b becomes less than a again) while the animation is running?


Dan



Return to posts index


Michael Müller
Re: Trigger Pre-Comped Animation through Condition
on Jan 9, 2019 at 8:47:44 pm

End of the animation > I thought that maybe you could reset the time value to zero again, once 20 Iterations of the loop (and 20 frames of the animation) passed.

Re-triggered while the animation is running > in this case, I'm pretty sure that situation will never occur. If it would be just one extra line of code, I'd prefer to not interrupt any current animation. But as I said, it's probably not necessary.

Is it really complicated? This starts to begin looking like a contract. You have a tip jar, do you?

Thanks,

Michael


Return to posts index

Dan Ebberts
Re: Trigger Pre-Comped Animation through Condition
on Jan 9, 2019 at 11:07:23 pm

>Is it really complicated?

Well, it changes the algorithm completely. Probably something more like this (it may not be exactly right, but it should be close):


a = thisComp.layer("AA").transform.position;
b = thisComp.layer("BB").transform.position;
d = 20; // duration of animation in frames
t = framesToTime(d);
lookingForOn = b.valueAtTime(time-t)[0] >= a.valueAtTime(time-t)[0];
if (lookingForOn){
while (d > 0){
d--;
t = framesToTime(d);
if (b.valueAtTime(time-t)[0] < a.valueAtTime(time-t)[0]){
break;
}
}
}else{
while (d > 0){
d--;
t = framesToTime(d);
if (b.valueAtTime(time-t)[0] >= a.valueAtTime(time-t)[0]){
break;
}
}
while (d > 0){
d--;
t = framesToTime(d);
if (b.valueAtTime(time-t)[0] < a.valueAtTime(time-t)[0]){
break;
}
}
}
t


Dan



Return to posts index

Michael Müller
Re: Trigger Pre-Comped Animation through Condition
on Jan 10, 2019 at 5:21:51 pm

I'm glad it works now. In my attempt of understanding it, I was able to shorten it quite a bit, while maintaining functionality. This leads me to a question:

I was able to completely get rid of the if statement. All I was left with, was the while statement that was included in both the "then" and the "else" of this if-statement. Did you include it to have the case of re-triggering covered? I couldn't really wrap my head around it.

The code now looks like this:


a = thisComp.layer("Bubble L").transform.position;
b = thisComp.layer("Trace").transform.position;
d = 20; // duration of animation in frames
t = framesToTime(d);
while (d > 0){
d--;
t = framesToTime(d);
if (b.valueAtTime(time-t)[0] < a.valueAtTime(time-t)[0]){
break;
}
}
t


Thanks,

Michael


Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2019 CreativeCOW.net All Rights Reserved
[TOP]