Activity › Forums › Adobe After Effects Expressions › Record the Time Value of Keyframes?
-
Record the Time Value of Keyframes?
Posted by Dane Cannon on August 17, 2012 at 5:06 pmI asked this in the below “typewriter with cursor” thread along with some other questions, but thought it might get a quicker response on its own thread. Is there any way to record the time value of a keyframe (let’s say the checking of a checkbox)? I’d like to use that to offset an expression that runs based on time, thereby effectively pausing the expression.
Dan Ebbertsreplied 13 years, 8 months ago 2 Members · 12 Replies
-
12 Replies
-
Dane Cannon
August 18, 2012 at 8:47 pmWell, how about assigning the time value of a keyframe to a variable? That way I could move a keyframe and it would update an expression? That might be a little more complex than it needs though… What I’m really trying to do is have a variable that continually returns the time value when a checkbox is checked but returns zero when the checkbox isn’t checked. That will allow to pause a time-based expression and then start it again.
-
Dan Ebberts
August 18, 2012 at 8:58 pmYou can get the time of a particular keyframe like this (this example gives you the time of the last keyframe):
cb = thisComp.layer("Layer 1").effect("Checkbox Control")("Checkbox");
if (cb.numKeys > 0)
t = cb.key(cb.numKeys).time
else
t = 0;
You can get the value at that keyframe by using .value instead of .time
Dan
-
Dane Cannon
August 18, 2012 at 9:30 pmPerfect. Thanks Dan! Also, thanks for answering my question on the % in expressions! And for your expressions site!
-
Dane Cannon
August 22, 2012 at 1:35 amHere’s the problem I’m running into now… I can pause the expression, but when I unpause the expression, it goes immediately to where it would’ve been (it runs on time) as opposed to starting back at the place where I paused it. Is there a way to reference the last keyframe without knowing its key(index)? numKeys will get me the total number of keyframes, but I can’t figure out how to specify for which keyframe I’d like the time value returned (I’m trying to get this so I can save it as an animation preset, so hopefully it’d work with any number of keyframes… or none). nearestKey seems to jump forward in time as well unfortunately.
-
Dane Cannon
August 22, 2012 at 1:41 amWould it be possible to have hold keyframes put onto the time remap property whenever there was an on off keyframe from a checkbox? Hmmm… but then of course, the problem would be that the cursor as well would be paused, when it should still be blinking… This is way more trouble than it’s worth, I’m just having a hard time letting go of it… 🙂
-
Dan Ebberts
August 22, 2012 at 2:05 amVariable n should give you the index of the most-recent, previous keyframe (it will be zero if the CTI hasn’t reached a keyframe yet).
cb = thisComp.layer("Layer 1").effect("Checkbox Control")("Checkbox");
n = 0;
if (cb.numKeys > 0){
n = cb.nearestKey(time).index;
if (cb.key(n).time > time) n--;
}
Dan
-
Dane Cannon
August 26, 2012 at 8:19 amHey Dan,
Thanks again. This works like an absolute charm. I’m only now realizing (after fruitless hours) that this was probably the wrong question to be asking in the first place. I think it’d be easier if I explained what I was trying to do. Let’s say that it’s a clock that counts up (shows time) unless a checkbox is checked. Whenever it’s checked, the clock stops and stays at the number, but when the checkbox is unchecked, it continues to run, starting at the value that it’s already displaying. I thought I might be able to do it by establishing the delay using “else if” statements for the first couple of keyframes, and then using a slider in a null control layer to act as kind of a placeholder (so I could refer back to it’s value at a certain time and calculate its current value from that). It always seems to screw up around the 3rd or 4th keyframe though… Feel free to not read this code at all and just answer the question. I figured I’d include just in case I was on the right track but did something wrong.//this is pasted into the "Placeholder" expression slider on the control null
cb=thisComp.layer("Text/Cursor Controller").effect("Pause if Checked")("Checkbox");
p=effect("Placeholder")("Slider");n=0;
if (cb.numKeys>0){
n=cb.nearestKey(time).index;
if (cb.key(n).time>time)n--;
};if((
n==1)|(n==0)|(cb.numKeys==0))
{m=0};
else
{m=cb.key(n-1).time};//hard part here
if(
(cb==0)&
(cb.numKeys==0)
)
{z=time};else if(
(cb==1)&
(cb.numKeys==0)
)
{z=0};else if(
(cb==0)&
(n==0)
)
{z=time};else if(
(cb==1)&
(n==0)
)
{z=0};else if(
(cb==0)&
(n==1)
)
{z=time};else if(
(cb==1)&
(n==1)
)
{z=0};else if(
(cb==0)&
(n==2)
)
{z=time-m};else if(
(cb==1)&
(n==2)
)
{z=cb.key(n).time};else if(
(cb==0)&
(n>2)
)
{z=p.valueAtTime(m)+(time-cb.key(n).time)};else if(
(cb==1)&
(n>2)
)
{z=(cb.key(n).time-m)+p.valueAtTime(m)};//end hard part
z
-
Dane Cannon
August 26, 2012 at 8:36 amWhat’s especially frustrating is that I have that expression plugged in in 2 places — one on a text layer under the source text, and the other on the null controller slider as detailed above. At the third keyframe, they return different results… yet are the same expression! Can an expression not reference it’s own value at a given time in the past?
-
Dan Ebberts
August 26, 2012 at 5:39 pm>Can an expression not reference it’s own value at a given time in the past?
That is correct (expressions have no way to access their own previous calculations), which is what makes this stuff so tricky.
Your expression, at every frame, has to go back and figure out how long the checkbox has been on in the past. Here’s an example from an article I’m working on:
p = effect("Checkbox Control")("Checkbox");
t = 0;
if (p.numKeys > 1){
n = p.nearestKey(time).index;
if (p.key(n).time > time) n--;
if (n > 0){
for (i = 1; i <= n; i++){
if (p.key(i).value){
if (i < n){
t += p.key(i+1).time - p.key(i).time;
}else{
t += time - p.key(i).time;
}
}
}
}
}
t
Dan
Reply to this Discussion! Login or Sign Up