Skip to main content
Participant
August 15, 2022
Answered

Get the Time at a specific Value

  • August 15, 2022
  • 1 reply
  • 921 views

Hello!
I've been wracking my brain trying to find a solution to this problem I'm having.
I have an animation where a null follows a path and "picks up" objects along the path. I want to be able to keyfram the null animation along the path at specific points, but still have the objects get picked up at the right time along the path and ease between the 2 positions.

 

I've done it somewhat by using the progress value then adding on a delay to that value, but the problem I'm running into is that if I put a keyframe into the progress slider while the transition between the positions is happening, the animation of the "pick up" stops. I'd like the "collecting" animation to continue regardless if the progress slider stops.

Here's what I have so far:
a = transform.position;
b = thisComp.layer("Trace Shape Layer 1: Path 1 [1.1]").transform.position;//null position
s = effect("Start Point")("Slider");//start point where null passes shape
progress = thisComp.layer("Trace Shape Layer 1: Path 1 [1.1]").effect("Trace Path")("Progress"); //progress of null along path
c = ease(progress, s, s+20, a, b);

 

I want to know if there's a way to get the time at a specific value of the slider, i.e. "when the progress slider = 10 give me the static value at that time" then use that time to trigger the animation. Something like:

a = transform.position;
b = thisComp.layer("Trace Shape Layer 1: Path 1 [1.1]").transform.position;//null position
s = effect("Start Point")("Slider");//start point where null passes shape
progress = thisComp.layer("Trace Shape Layer 1: Path 1 [1.1]").effect("Trace Path")("Progress"); //progress of null along path

begin = *time at the value of slider s*;

delay = 3;

c = ease(time, begin, begin +delay, a, b);

 

 

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

Unfortunately, that's the toughest kind of expression event triggering, where you don't have a corresponding object with an accessible time (like a keyframe or marker). You have use a brute force, frame-by-frame approach to find the frame where the value crosses the target value. It helps, if you can make some assumptions. For example, if the value never decreases, you can search backwards from the current frame until you find the most recent trigger, like this:

targetVal = 50;
pct = thisComp.layer("Shape Layer 1")("Contents")("Trim Paths 1")("End");
dur = 0;
f = timeToFrames(time);
while (f >= 0){
  if (pct.valueAtTime(framesToTime(f)) <= targetVal){
    dur = time - framesToTime(f);
    break;
  }
  f--;
}
dur // amount of time since the trigger

In other situations, you might have to start at the first frame and search forward to find the first trigger.

1 reply

Dan Ebberts
Community Expert
Dan EbbertsCommunity ExpertCorrect answer
Community Expert
August 15, 2022

Unfortunately, that's the toughest kind of expression event triggering, where you don't have a corresponding object with an accessible time (like a keyframe or marker). You have use a brute force, frame-by-frame approach to find the frame where the value crosses the target value. It helps, if you can make some assumptions. For example, if the value never decreases, you can search backwards from the current frame until you find the most recent trigger, like this:

targetVal = 50;
pct = thisComp.layer("Shape Layer 1")("Contents")("Trim Paths 1")("End");
dur = 0;
f = timeToFrames(time);
while (f >= 0){
  if (pct.valueAtTime(framesToTime(f)) <= targetVal){
    dur = time - framesToTime(f);
    break;
  }
  f--;
}
dur // amount of time since the trigger

In other situations, you might have to start at the first frame and search forward to find the first trigger.

Participant
August 15, 2022

Thank you so much for your help! This was exaclty what I needed! This is the expression that I'm using now.

a = transform.position;
b = thisComp.layer("Path Control").transform.position;
swap = effect("animstart")("Slider");
progress = thisComp.layer("Path Control").effect("Trace Path")("Progress");
dur = 0;
f = timeToFrames(time);
while (f >= 0){
	if(progress.valueAtTime(framesToTime(f)) <= swap){
		dur = time - framesToTime(f);
		break;
	}
f--;
}
c = ease(dur,a,b);
c