Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Forums Adobe After Effects Expressions Follow the leader, with some springy/elastic motion…

  • Follow the leader, with some springy/elastic motion…

  • Joseph Patrick

    May 2, 2007 at 1:43 am

    Hi there. I’m fairly new to expressions, so, apologies in advance for my naivety.

    What I’m trying to do is have five boxes move around the screen. The first (the leader of the pack) will be key framed, then I want the remaining four (the followers) to follow the leader, on a delay. Additionally, as if they’re connected by an invisible rubber band, I’d like the motion of the followers to have some elasticity when the leader starts and stops abruptly.

    I copied the script below from an AE expression template called “follow”, and applied it to the followers’ position. So, now they follow, but do not have the springiness I’m after:

    delay = effect(“Follow”)(“Delay”);
    include = effect(“Follow”)(“Position”);
    basedOnIndex = effect(“Follow”)(“Based On Index”);

    if (include == 1){
    try{
    L = effect(“Follow”)(“Leader”);
    if (basedOnIndex == 1){
    delta = Math.abs(L.index – index)*delay;
    }else{
    delta = delay;
    }
    L.toWorld(L.anchorPoint,time – delta)
    }catch(err){
    value
    }
    }else{
    value
    }

    I’ve poked around both in the AE expression templates, and on motionscript.com a bit, but can’t figure out how to get reactions based on abrupt movements of the leader. Most of the expression I’ve seen for springy/elastic motion seems to be based on Math.sine or some pattern, rather than referencing the motion of another element in the comp.

    Sorry for the long-winded post. Any help is greatly appreciated. Thanks!

  • Dan Ebberts

    May 2, 2007 at 1:44 pm

    Hmmm… I think this could end up being a fairly complicated simulation if you want each layer to be affected by its own momentum and the acceleration of the layers on either side while staying on the path defined by the leader.

    I’m sure there’s a way to do it, but I don’t have a canned solution for you.

    Dan

  • Filip Vandueren

    May 2, 2007 at 2:06 pm

    I think the script is very complicated to begin with, it could be simplified, since all it really does is this:

    L.toWorld(L.anchorPoint,time – delta);

    I’ve developped a script that applies inertia to any function that returns a certain value at a certain time:


    inertia = 0.75;
    stiffness = 0.20;
    // for easier tweaking use a null layer with two sliders:
    // inertia = thisComp.layer("CONTROLLER").effect("inertia")("Slider");
    // stiffness = thisComp.layer("CONTROLLER").effect("Stiffness")("Slider");

    lagValue = calcValue(0);
    f= thisComp.frameDuration;
    will=0;

    for (t=0; t<=time; t+=f) { delta = calcValue(t) - lagValue; will = will * inertia + delta*stiffness ; lagValue +=will } lagValue; function calcValue(t) { // or another expression that factors in time return valueAtTime(t); }

    in the case of a 'follow the leader' you could change that last line to something like this:


    return thisComp.layer(index-1)position.valueAtTime(t-0.1);

    This assumes the 5 followers are directly below the leader, and the offset is .1 seconds. Nothing is parented.

    Experiment with the inertia and stiffness settings, the last follower will effectively appear to be 5 times more elastic than the first.

    Dan, I'm not sure how this code compares to the springy expression on your site, I just discovered it yesterday.
    Knowing you, your code will probably be more optimised 😉
    I developped this one based on a calculating function so that I could have for example a character's ponytail that rotates based on the speed at which she walks, but still have a wavy inertia about it.

  • Dan Ebberts

    May 2, 2007 at 3:40 pm

    Interesting solution, Filip. I like it.

    Because of the nature of these types of simulations, it does grind to a halt pretty quickly, but I don’t think there’s anything that can be done about that.

    I did find a typo in this line:

    return thisComp.layer(index-1)position.valueAtTime(t-0.1);

    (missing period before “position”).

    Good job!

    Dan

  • Joseph Patrick

    May 2, 2007 at 5:04 pm

    That works! Thanks for the help guys. I appreciate it.
    -Joseph

  • Joseph Patrick

    May 2, 2007 at 5:51 pm

    …Given the speed of the leader, these values (for inertia, stiffness and time) are working for me the best… Thanks again!

    inertia = 0.01;
    stiffness = 1.10;

    lagValue = calcValue(0);
    f= thisComp.frameDuration;
    will=0;

    for (t=0; t<=time; t+=f) { delta = calcValue(t) - lagValue; will = will * inertia + delta*stiffness ; lagValue +=will } lagValue; function calcValue(t) { return thisComp.layer(index-1).position.valueAtTime(t-0.02) }

  • Julian Sixx

    May 3, 2007 at 4:27 am

    Hi
    Filip can you give me some explanation on this line of code
    “for (t=0; t<=time; t+=f) {"

    is it a looping structure?What does it do?
    THX

  • Filip Vandueren

    May 3, 2007 at 9:03 am

    As you know, expressions are calculated for every point in time with a ‘clean slate’ ie. no knowledge of what value was calculated the frame before.

    For expressions that need to know what’s being calculated over a period of time, we often resort to this solution:

    start at time=0 and step through every frame untill we’re at the current time.
    For every step: calculate something and -for example- add it to a running total.

    so the basic construction of a for() loop as used in this case is:


    for (t=0; t<=time; t+=f) { // do stuff }

    this literally means:
    start with t=0,
    as long as t is less that or equal to the current time,
    // do stuff
    then add the value of f to t (we defined f as the length of 1 frame)
    is it still less than or equal to the current time ? if not: stop, else
    // do stuff
    then add...
    etc.

  • Julian Sixx

    May 4, 2007 at 4:23 am

    Hi Filip

    thank you

  • Lord Scales

    May 15, 2007 at 8:47 pm

    I looked in Google about “calcValue” but I found nothing intersting about.

    Is “calcValue” an specific function of JavaScript Expressions or you created it in the expression?

    Thanks.

    Lord Scales

Viewing 1 - 10 of 11 posts

Log in to reply.

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