Skip to main content
Monki Bidniz
Participant
December 31, 2022
Answered

Is it possible to trigger a countdown/animation when an If statement is met?

  • December 31, 2022
  • 2 replies
  • 624 views

I've been trying to find a way to do this all day! If it was possible to run an if function once it would be a lot easier. Like if it was possible to have:
if (a == 50) {
b = time
}
Where b would stay the same, storing the time that the if statement was met. Then I could subtract b from time and be set!

Any help is greatly appreciated.

This topic has been closed for replies.
Correct answer Dan Ebberts

The solution for a value-based trigger usually has to be tailored to your specific situation, but here are a couple of generic solutions that assume "a" is a slider control on a layer name "Control". The first version is for the situation where you only want the animation to trigger the first time the threshold is crossed. Both examples assume that the animated property being driven is time remapping, but if it's a different property (like scale, rotation, etc.) you would just wrap the final line inside valueAtTime()--like:  valueAtTime(Math.max(time - t,0))

a = thisComp.layer("Controls").effect("Slider Control")("Slider");
threshold = 50;
t = inPoint;
while (t <= time){
  if (a.valueAtTime(t) >= threshold) break;
  t += thisComp.frameDuration;
}
Math.max(time - t,0)

This (more complex) version is for when you want the animation to trigger every time the value crosses the threshold:

a = thisComp.layer("Controls").effect("Slider Control")("Slider");
threshold = 50;
triggered = a >= threshold;
t = time - thisComp.frameDuration;
if (! triggered){
  while (t >= inPoint){
    if (a.valueAtTime(t) >= threshold){
      triggered = true;
      break;
    }
    t -= thisComp.frameDuration;
  }
}
if (triggered){
  while (t >= inPoint){
    if (a.valueAtTime(t) < threshold){
      triggered = true;
      break;
    }
    t -= thisComp.frameDuration;
  }
}
triggered ? Math.max(time - t,0) : 0;

Note that this type of brute-force solution requires more an more processing for each frame, so if your comp is long, things can grind to a halt.

 

 

2 replies

Mylenium
Legend
December 31, 2022

You need to explain what exactly you want to do. As Dan already stated, there is no way to do this with a simple function and aside from the while() loop I have a hunch you're also looking for some sort of collision detection, which may further complicate matters.

 

Mylenium 

Dan Ebberts
Community Expert
Community Expert
December 31, 2022

No, expressions have no memory, so your expression would probably have to loop back in time, frame-by-frame, using valueAtTime() to find the frame when a equaled 50. The specifics (and the difficulty) depend on exactly what it is that needs to trigger the animation.

Dan Ebberts
Community Expert
Dan EbbertsCommunity ExpertCorrect answer
Community Expert
December 31, 2022

The solution for a value-based trigger usually has to be tailored to your specific situation, but here are a couple of generic solutions that assume "a" is a slider control on a layer name "Control". The first version is for the situation where you only want the animation to trigger the first time the threshold is crossed. Both examples assume that the animated property being driven is time remapping, but if it's a different property (like scale, rotation, etc.) you would just wrap the final line inside valueAtTime()--like:  valueAtTime(Math.max(time - t,0))

a = thisComp.layer("Controls").effect("Slider Control")("Slider");
threshold = 50;
t = inPoint;
while (t <= time){
  if (a.valueAtTime(t) >= threshold) break;
  t += thisComp.frameDuration;
}
Math.max(time - t,0)

This (more complex) version is for when you want the animation to trigger every time the value crosses the threshold:

a = thisComp.layer("Controls").effect("Slider Control")("Slider");
threshold = 50;
triggered = a >= threshold;
t = time - thisComp.frameDuration;
if (! triggered){
  while (t >= inPoint){
    if (a.valueAtTime(t) >= threshold){
      triggered = true;
      break;
    }
    t -= thisComp.frameDuration;
  }
}
if (triggered){
  while (t >= inPoint){
    if (a.valueAtTime(t) < threshold){
      triggered = true;
      break;
    }
    t -= thisComp.frameDuration;
  }
}
triggered ? Math.max(time - t,0) : 0;

Note that this type of brute-force solution requires more an more processing for each frame, so if your comp is long, things can grind to a halt.

 

 

Monki Bidniz
Participant
January 10, 2023

Very informative explanation, Dan! Thank you.