Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Use Keyframe as trigger

  • Use Keyframe as trigger

    Posted by Lisa Schmölzer on May 2, 2012 at 2:50 pm

    Hi,

    Does anybody know whether there is anyway to use a keyframe as a trigger for an animation in an expression?

    What I’m talking about is, that you have a layer that’s supposed to be doing a small repeating animation (i.e. pulsating / increasing and decreasing it’s size) from time to time. The starting points of this animation are supposed to be triggered manually and than stop until the next trigger comes.

    I was thinking about keyframing the animation once inside the object and then use a slider object that would be increased in value, every time I need the animation. The difficult thing is to link the two, because first of all the animation will have to start as soon as the value of the slider object increases and than stop until the value rises again.

    I know that I could just copy and paste the keyframes but there has to be some way to solve this with an expression.
    Does anybody have an idea how? Or do I need scripting to solve this problem (I do have some feeling for expressions but I have to admit that I’m quite a noob when it comes to scripting).

    Thanks a lot in advanced,

    Lisa

    Brie Clayton
    replied 2 years ago
    6 Members · 12 Replies
  • 12 Replies
  • Kevin Camp

    May 2, 2012 at 5:31 pm

    this may work for you..

    when i’ve needed to ‘recall’ an animation at specific points i’ve used an expression like the one bellow. it looks at layer markers on the layer for timing of the animation for a given property.

    so, say your scale animation is:
    key1: 00:00f — [50,50]
    key2: 00:15f — [100,100]
    key3: 01:00f — [50,50]

    the expression will play that scale animation every time it passes a layer marker on that layer.

    n = 0;
    if (marker.numKeys > 0){
    n = marker.nearestKey(time).index;
    if (marker.key(n).time > time) n--;
    }

    if (n > 0){
    valueAtTime(time-marker.key(n).time);
    }else{
    valueAtTime(0);
    }

    Kevin Camp
    Senior Designer
    KCPQ, KMYQ & KRCW

  • Lisa Schmölzer

    May 4, 2012 at 8:51 am

    Wonderful! This works just perfect! Thank you so much!
    Cheers, Lisa

  • David Cabestany

    April 20, 2016 at 9:56 pm

    Kevin,

    Any idea how to use this expression to trigger the animation every given time (for example once every minute) instead of using keyframes?

    Best,
    D.

  • Dan Ebberts

    April 20, 2016 at 10:38 pm

    Something like this maybe:

    segLength = 60;
    t = (time – inPoint)%segLength;
    valueAtTime(t)

    Dan

  • David Cabestany

    April 20, 2016 at 10:56 pm

    Mr. Dan Ebberts to the rescue as always! Thanks!!!

    Just for my own understanding, would you mind explaining why the modulo operator?
    I understand that segLength is how often I wan my animation to repeat, in this case every 60 seconds. Then t is the comp’s time minus the in point, in this case the start of my comp, so that leaves us with the following:

    at 60 seconds it would be

    t=60-in point (which is 0) = 60

    60/60 = 1, % (the remainder) = 0

    so then

    valueAtTime(t) would be 0, right?

    How does that produce the desired behavior?

    Thanks again!
    D.

  • Dan Ebberts

    April 20, 2016 at 11:19 pm

    Modulo 60 just creates a repeating loop from 0 to 59.99… as the time increases continuously.

    Dan

  • David Cabestany

    April 24, 2016 at 4:30 pm

    I see. Thanks!
    D.

  • Kyle Spangenberger

    April 17, 2024 at 12:20 am

    is there a way to leverage this to pull values from another layer? or from values set in expression controls?

     

    I have a layer where every time I pass a layer marker, I want to do a linear interpolation to fade from one color to another (i.e. marker 1 goes from color 1 to color 2 at a prescribed duration, marker 2 goes from color 2 to color 3 and so on).

     

    I love the implementation from above for oscillating values set by keyframes. I just wish there was an elegant way to change the values reference each time it’s called. Thanks for any help!

  • Dan Ebberts

    April 17, 2024 at 4:25 am

    I’m not sure this is exactly what you’re after, but it should get you close. This defines a bunch of colors in an array (you could get them from color controls instead) and will transition between colors at layer markers:

    //          red       yellow    green      cyan      blue    magenta
    colors = [[1,0,0,1],[1,1,0,1],[0,1,0,1],[0,1,1,1],[0,0,1,1],[1,0,1,1]];
    fadeDur = .5;
    m = marker;
    n = 0;
    if (m.numKeys > 0){
    n = m.nearestKey(time).index;
    if (time < m.key(n).time) n--;
    }
    if (n == 0 || m.numKeys == 1){
    colors[0];
    }else if (n >= colors.length || n >= m.numKeys){
    colors[colors.length-1];
    }else{
    t1 = m.key(n).time;
    t2 = t1 + fadeDur;
    v1 = colors[n-1];
    v2 = colors[n];
    linear(time,t1,t2,v1,v2);
    }
  • Kyle Spangenberger

    April 17, 2024 at 1:29 pm

    and here I was thinking I was an “intermediate” expression user! this works a treat, my greatest gratitude Dan! It’s going to take me a while to parse this, I’m not a programmer so this paradigm isn’t clicking yet with the nested and subsequent ‘if’ uses.

    Do you recommend learning Javascript or just plugging away at expression-specific exercises? (response optional, of course, you’ve certainly helped me plenty already).

    Cheers!

Page 1 of 2

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy