Skip to main content
Participant
November 20, 2023
Question

Expression to change single property value over several frames once a condition is met.

  • November 20, 2023
  • 2 replies
  • 569 views

I have 30 layers. I have a random number generator (1-30) on a Null Slider Control. I have a preset expression applied to the 30 layers that on each frame compares the random number from the Null to the index of the layers, if the condition is met (random# = index) the opacity toggles from 0 to 100.  Changes the opacity back to 0 when the condition is no longer met. Works great. No markers, no keyframes.

 

What I'd love to add is a gradual fade from 100 back to 0.

 

AE doesn't support events, so when the match is made on frame X, there's no trigger to start the fade over several frames. AE reruns the expression on every frame and (I think) it has no method for storing variables that can exist from one frame to the next, so I can't store the time when the match is made to then use as the starting frame for a loop to control the fade.

 

Is there any way to add a change in value for the opacity (or really any property) over several frames once the expression hits the necessary condition?

This topic has been closed for replies.

2 replies

Dan Ebberts
Community Expert
Community Expert
November 20, 2023

Assuming that the layers with the opacity expression are layers 1-30, it will probably look something like this:

s = thisComp.layer("Control").effect("Slider Control")("Slider");
fadeFrames = 5;
t = time;
triggered = false;
for (i = 0; i < fadeFrames; i++){
  if (t < 0) break;
  if (s.valueAtTime(t) == index){
    triggered = true;
    break;
  }
  t -= thisComp.frameDuration;
}
triggered ? linear(i,0,fadeFrames,100,0) : 0
Participant
November 20, 2023

Thanks Dan, this worked great. I'm going through the code adding comments so I can record my understanding of each line. Would you say the following is accurate?

t -= thisComp.frameDuration;   // Subtract from the evaluated time the amount of                 time that equals one frame. 

You snuck in that ternary operator in the last line. I haven't used my javascript knowledge for many years and had to look that one up.

Dan Ebberts
Community Expert
Community Expert
November 20, 2023

That seems accurate. You're just subtracting one frame's worth for the next time you use valueAtTime().

 

I started using the ternary operator a lot more (as a time saver) when the JavaScript engine came out and single-line if/else no longer worked without extra brackets or lines. It's just more compact and tidy anyway.

Mylenium
Legend
November 20, 2023

https://www.motionscript.com/design-guide/audio-trigger.html

 

Same principle. Good luck with the ensuing mess.

 

Mylenium