Copy link to clipboard
Copied
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);
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.la
...
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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