Copy link to clipboard
Copied
I have a layer moving along the X-axis. I have a shape layer with a simple stroke and trim paths that has the starting point of the stroke on the same X-axis. When the moving layer (m) reaches the same X value, I want the stroke to move up. This simple expression pops the line up to 100%
m = thisComp.layer("Mover").position;
r = position;
if (m[0] < r[0] || m[0] > r[0] + 60)
y = 0;
else
y = 100;
There are no keyframes at the time of the collision, so using time in an ease method is not working for me.
Is there some way to come up with an interpolation method that says
when m = r increase the value of y so that when m = r + 30, y == 100;
then as m moves from r+30 to r + 60, y changes from 100 to 0
If I had a keyframe where the collision occurs, it would be easy to use valueAtTime for the keyframe to create the growing and falling stroke. I can't figure out how to make it happen without a keyframe.
Any suggestions would be appreciated.
This could also be helpful in animating a countdown so as the numbers go from 10 to zero a line would grow and shrink instead of just blinking when each number is reached.
Maybe something like this:
m = thisComp.layer("Mover").transform.position[0];
r = position[0];
m < r + 30 ? ease(m,r,r+30,0,100) : ease(m,r+30,r+60,100,0)
This is one idea. It assumes your value for Points only jumps in whole number increments. The expression checks to see when it last changed and when it next changes and uses the time in between those changes to animate from 0 to 100. I have no idea if that's what you're looking for, but it might give you some ideas:
n = content("Polystar 1").content("Polystar Path 1").points;
tMin = null;
tMax = null;
t = time - thisComp.frameDuration;
while(t >= inPoint){
if (n.valueAtTime(t) != n){
tMi...
Copy link to clipboard
Copied
Why not simply measure the distance from the stroke to the box with length()? Fed into a linear() expression that could give you the driver/ driven relation you seem to be after. Real collision detection would be way too complicated, though Dan would probably have some code handy that uses temporal integration and then makes the whole thing respond.
Mylenium
Copy link to clipboard
Copied
Maybe something like this:
m = thisComp.layer("Mover").transform.position[0];
r = position[0];
m < r + 30 ? ease(m,r,r+30,0,100) : ease(m,r+30,r+60,100,0)
Copy link to clipboard
Copied
Thanks, Dan. Perfect for my application.
Copy link to clipboard
Copied
How about a situation where you are only working with whole numbers? Something like this:
n = content("Polystar 1").content("Polystar Path 1").points;
t = time?;
tMin = ???;
tMax = ???;
if (n == 3)
ease(t, tMin, tMax, 0, 100)
else
0
With no keyframes and no values to look for that gradually change over time how would you ease between values?
Copy link to clipboard
Copied
I'm having trouble picturing what you're trying to do and how it's affected by the number of points in the star. I think a more detailed description would help.
Copy link to clipboard
Copied
This is one idea. It assumes your value for Points only jumps in whole number increments. The expression checks to see when it last changed and when it next changes and uses the time in between those changes to animate from 0 to 100. I have no idea if that's what you're looking for, but it might give you some ideas:
n = content("Polystar 1").content("Polystar Path 1").points;
tMin = null;
tMax = null;
t = time - thisComp.frameDuration;
while(t >= inPoint){
if (n.valueAtTime(t) != n){
tMin = t+thisComp.frameDuration;
break;
}
t -= thisComp.frameDuration;
}
t = time + thisComp.frameDuration;
while(t <= outPoint){
if (n.valueAtTime(t) != n){
tMax = t-thisComp.frameDuration;
break;
}
t += thisComp.frameDuration;
}
if (tMin != null && tMax != null){
ease(time,tMin,tMax,0,100);
}else{
0;
}
Copy link to clipboard
Copied
Thanks, Dan. I need this because I have data-driven animations that don't use any keyframes, and a lot of them jump between whole numbers. Some of the animated maps and charts I'm working on have about 200 shapes that need to react to changing digits and moving layers. Your solutions will save me many hours of trying to keyframe all those layers. I just threw in a thisProperty. propertyGroup(3) to create a c variable and added && n == c to the last if statement for Trim Paths on an ellipse named 1, moved the duplicates (all 12 of them) to the proper positions, and I now have an ellipse that draws around a text layer that is moving along a path and is driven by a JSON file that lights up 12 different numbers. You have saved me hours.
Copy link to clipboard
Copied
Now I'm curious. Could the expession have referenced the JSON file itself? That would probably be more efficient than the frame-by-frame sniffing I put in there.
Copy link to clipboard
Copied
That's a very interesting idea.
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more