ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

Value in relation to keyframes

COW Forums : Adobe After Effects Expressions

<< PREVIOUS   •   FAQ   •   VIEW ALL   •   PRINT   •   NEXT >>
Aaron Pozzer
Value in relation to keyframes
on Sep 3, 2011 at 3:15:43 am

so im not sure how to describe what i want to be able to do here, but ill take a shot.

i have a particle system being controlled by 2 nulls. 1 null is parented to another object, gets path info etc, and it gives the particle system the xy position. then i parented a seperate null to the 1st, just do deal with z position. so the emitter gets its z position from that 2nd null.

this is more an issue of me being lazy i guess, but isnt that what expressions are for? if i make time adjustments to the keys that control the xy position, if i dont make sure i also adjust the keys on the z position null, the motion of the path gets messed up. im wondering if there is an expression that will say something like...

'if you are at a keyframe, be 0, if you are not, be 100 (or whatever value), and anywhere in between a key be at the correct percentage of 100 corresponding to how far between keys you are'.

does that make sense? so if i have a key at frame 1, and a key at frame 10, and i set the CTI to frame 5, the z would calculate a value of 50 because its in the middle. if i set the CTI to frame 3 or 7 it would be 30%, etc... the xy values dont matter, just where their keyframes are.

basically im trying to make a line that hops around a map, representing a flight, hence why i need z now, as the travelling line is no longer constrained to just driving around ON the map. so this would make the line automatically arc into the air between keys, as the keys usualy mark destinations where the path turns.

my problem with this is telling it how to figure out where a keyframe is and where it is in relation to other keys. im sure its probably pretty easy.

looking forward to more expression magic! thanks!


Return to posts index

Dan Ebberts
Re: Value in relation to keyframes
on Sep 3, 2011 at 4:25:31 am

I have no idea if this is what you're looking for, but this expression will generate values between 0 and 100 as the time moves between keyframes of another property (position in this example). Before the first keyframe and after the last keyframe it just sets the result to value.


p = transform.position; // property you want to monitor
v = value;
if (p.numKeys > 0){
n = p.nearestKey(time).index;
if (p.key(n).time > time) n--;
if (n > 0 && n < p.numKeys)
v = linear(time,p.key(n).time,p.key(n+1).time,0,100);
}
v



Dan



Return to posts index

Aaron Pozzer
Re: Value in relation to keyframes
on Sep 3, 2011 at 12:55:13 pm

hey Dan. thanks for the response. so this KINDA works, but not quite.

i have my null object. lets say it has 4 position keys to its animation, and it just outlines a simple path. lets say the 1st key of this animation is on frame 10.

when i start at frame 0, the expression calculates the value i entered: -50 (i want the line to come closer to the camera, hence the negative value). as i scrub forward towards frame 10 (the first key), nothing happens. when i hit frame 10 the value is set to 0. as i keep scrubbing towards the next keyframe the value climbs all the way up to -50 and when it hits the next key it resets back down to 0. over and over for as many keys as there are in the animation.

so, this isnt the desired effect. this creates steps kinda, with the -50 z value always being right before the next key is reached. what i was after was that -50z was always in the middle of any 2 keys. so when its ON a key, its 0, and when its between any 2 keys its trying to get to -50 (or whatever value). the goal is to create arcs with the highest point of the arc being between any 2 keys.

i suppose using linear would give a series of pyramids/steps rather than arcs. perhaps ease is better suited for this expression?

anyway, does that make more sense? is it possible?


Return to posts index


Dan Ebberts
Re: Value in relation to keyframes
on Sep 3, 2011 at 3:37:41 pm

Something more like this then, probably:


p = transform.position;
offset = 0;
if (p.numKeys > 0){
n = p.nearestKey(time).index;
if (p.key(n).time > time) n--;
if (n > 0 && n < p.numKeys){
t0 = p.key(n).time;
t1 = p.key(n+1).time;
d = t1 - t0;
t = Math.abs(time - (t0+t1)/2)
offset = ease(t,0,d/2,-50,0);
}
}
value + offset


Dan



Return to posts index

Aaron Pozzer
Re: Value in relation to keyframes
on Sep 4, 2011 at 2:53:08 pm

thats the ticket! worked great. if i wanted to be SUPER picky id ask if there was a way to increase the offset for the further away keys are. like if keys are more than 10 frames apart offset by ____, if more than 20 frames apart offset by _____... or some automatic scaling factor that would just do it automatically.

but ya, its fine now as it stands unless you wanna try and solve that one too.

thanks dan!


Return to posts index

Dan Ebberts
Re: Value in relation to keyframes
on Sep 4, 2011 at 4:30:55 pm

This should do it. Adjust variables nom and peak to get the relationship you want.


p = transform.position;
offset = 0;
if (p.numKeys > 0){
peak = -50;
nom = 10; // frames
n = p.nearestKey(time).index;
if (p.key(n).time > time) n--;
if (n > 0 && n < p.numKeys){
t0 = p.key(n).time;
t1 = p.key(n+1).time;
d = t1 - t0;
t = Math.abs(time - (t0+t1)/2)
offset = ease(t,0,d/2,peak*d/timeToFrames(nom),0);
}
}
value + offset


Dan



Return to posts index


Aaron Pozzer
Re: Value in relation to keyframes
on Sep 5, 2011 at 2:09:01 pm

awesome dan!

a question about ease. my ideal curve for the line all this stuff is controlling would be this sort of shape...

http://www.unifycommunity.com/wiki/images/e/e8/Mathfx-Bounce.png

...where the in and out points are hard, and the arc in the middle is smooth. is there a command like ease that will give this shape instead of the smooth shape of ease?


Return to posts index

Dan Ebberts
Re: Value in relation to keyframes
on Sep 5, 2011 at 11:38:36 pm

Maybe you just need to use easeOut() and easeIn() instead of ease(), like this:


p = transform.position;
offset = 0;
if (p.numKeys > 0){
peak = -50;
nom = 10; // frames
n = p.nearestKey(time).index;
if (p.key(n).time > time) n--;
if (n > 0 && n < p.numKeys){
t0 = p.key(n).time;
t1 = p.key(n+1).time;
d = t1 - t0;
t = (t0+t1)/2;
if (time <= t)
offset = easeOut(time,t0,t,0,peak*d/framesToTime(nom))
else
offset = easeIn(time,t,t1,peak*d/framesToTime(nom),0);
}
}
value + offset


I also corrected an error in the previous version where I was using timeToFrames() instead of framesToTime().

If this doesn't give you what you want, you may need to implement your own quadratic or cubic easing function.

Dan



Return to posts index

Aaron Pozzer
Re: Value in relation to keyframes
on Sep 7, 2011 at 12:55:54 pm

hey Dan. thanks for making the above adjustment. i didnt even notice till just now when i came here to ask another follow up question. so, im trying to be proactive and figure stuff out for myself, but not having much luck.

im trying to modify the 1st expression you posted (since its the simplest) to serve as a general purpose monitor for the same property im trying to watch and drive the Z position of that null.

i want it to be able to drive things like opacity, birth rate, etc, on any property i want, so things will all turn on/off in relation to those keys, and i only have to animate one channel basically.

but!... the modification i was trying to make would seem to only require the time of the 1st and last keys. if i wanted to fade something in at the 1st key, and then fade it out at the last, any keys in between wouldnt matter.

i had a look at the options available. im not sure key(index) would work, cause the # of keys might change... so only the 1st key would be the same. nearestkey would use them all i think, so thats no good, and key(markerName)... well im not sure on this one. i dont know how to set a marker name for a key, unless it means just a regular marker with you set with the * key?

then i guess the other problem would be, once it hits the 1st key and the opacity is triggered to raise from 0 to 100, does that happen instantly? i guess so, unless you tell it otherwise... so i wouldnt know how to build in a frame buffer as it were, so it comes on over 5 or 10 frames.

so if you were to modify the above, im not sure if needs all the fancy easing and such. these just need to turn stuff on.

thanks again Dan!


Return to posts index


Dan Ebberts
Re: Value in relation to keyframes
on Sep 7, 2011 at 3:18:45 pm

This should fade from 0 to 100 at the first position keyframe and 100 to 0 coming into the last keyframe. It won't do anything unless there are at least two keyframes:


p = transform.position;
fadeFrames = 10;

if (p.numKeys > 1){
t0 = p.key(1).time;
t1 = p.key(p.numKeys).time;
t = framesToTime(fadeFrames);
if (time < (t0+t1)/2){
ease(time,t0,t0+t,0,100)
}else{
ease(time,t1-t,t1,100,0)
}
}else{
value
}



Dan



Return to posts index

Aaron Pozzer
Re: Value in relation to keyframes
on Sep 7, 2011 at 4:06:55 pm

great Dan! perfect as always. much appreciated.


Return to posts index

Aaron Pozzer
Re: Value in relation to keyframes
on Sep 8, 2011 at 12:25:18 pm

hey Dan. just wondering if its possible to add a time offset in there? as it stands now, the fades in/out start/end at the keyframes, and thats exactly correct, but not what i was expecting for some reason. its fine how it is... i just added extra frames at the head and tail of the animation to get the layers faded in when i wanted them, in relation to the animation. for some reason i thought the fade in/out would start before the 1st key and be 100% by the time it hit that 1st key, and then start fading out on the last key and be 0% however many frames after the last key.

again, its fine this way, as i can tweak it with additional keys, but right now the only thing i can change is how fast the fade in happens. it would be great if i could offset the effect by some frames so that each layer/property using the script doesnt start/end at the same time.

thanks!


Return to posts index


Dan Ebberts
Re: Value in relation to keyframes
on Sep 8, 2011 at 1:15:14 pm

Try changing the in and out eases line this:

ease(time,t0-t,t0,0,100)

ease(time,t1,t1+t,100,0)


Dan



Return to posts index

Aaron Pozzer
Re: Value in relation to keyframes
on Sep 8, 2011 at 3:42:44 pm

that did it! good stuff. i tried to add in an offset function as follows...

p = property;
fadeFrames = 10;
<b><i>offset = .1;</i></b>

if (p.numKeys > 1){
t0 = p.key(1).time;
t1 = p.key(p.numKeys).time;
t = framesToTime(fadeFrames);
if (time < (t0+t1)/2){
ease(time,t0-t<b><i>+offset</i></b>,t0,0,100)
}else{
ease(time,t1<b><i>+offset</i></b>,t1+t,100,0)
}
}else{
value
}


this works, but it seems what it does is offset the value changes start, but not its finish. so the fade still happens in 10 frames, it just waits to start the fade, and then the fade has to be accomplished in fewer frames. also, i think cause of your framesToTime i had to put the offset as .1, because i think its in time, not frames.


Return to posts index

Zoltán Riskó
Re: Value in relation to keyframes
on Mar 20, 2018 at 11:29:36 pm

Hey Dan, very very old thread but thanks for it!
The first expression works for me like a charm but when I reach the last keyframe it's set to default. If I duplicate the last keyframe I can avoid it but it would be more elegant when I reach the last keyframe and I leave it in the timeline the value is still the last keyframe's value. Could you help how can I achieve this? Thanks!

p = transform.position; // property you want to monitor
v = value;
if (p.numKeys > 0){
n = p.nearestKey(time).index;
if (p.key(n).time > time) n--;
if (n > 0 && n &lt; p.numKeys)
v = linear(time,p.key(n).time,p.key(n+1).time,0,100);
}
v


Return to posts index


Dan Ebberts
Re: Value in relation to keyframes
on Mar 21, 2018 at 12:06:15 am

Like this maybe:


p = transform.position; // property you want to monitor
v = value;
if (p.numKeys > 0){
n = p.nearestKey(time).index;
if (p.key(n).time > time) n--;
if (n > 0 && n < p.numKeys)
v = linear(time,p.key(n).time,p.key(n+1).time,0,100)
else if (n == p.numKeys)
v = 100;
}
v



Dan



Return to posts index

Zoltán Riskó
Re: Value in relation to keyframes
on Mar 21, 2018 at 6:37:17 am

Oh yes that's it! Thank you very much! You are awesome! :)


Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2018 CreativeCOW.net All Rights Reserved
[TOP]