Scripted After Effects animations

4 years ago | #Motion #Snippet

By adding a scripted bounce or overshoot to a keyframe animation you can easily add a tad of fun and liveliness. Below are a few scripts that come in handy from time to time, and which allow for easy customisation through variables.

Edited on 2nd October 2014, adding more scripts

Bounce

e = .7;
g = 5000;
nMax = 9;
n = 0;

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

if (n > 0) {
    t = time - key(n).time;
    v = -velocityAtTime(key(n).time - .001)*e;
    vl = length(v);

    if (value instanceof Array) {
        vu = (vl > 0) ? normalize(v) : [0,0,0];
    } else {
        vu = (v < 0) ? -1 : 1;
    }

    tCur = 0;
    segDur = 2*vl/g;
    tNext = segDur;
    nb = 1; // number of bounces

    while (tNext < t && nb <= nMax) {
        vl *= e;
        segDur *= e;
        tCur = tNext;
        tNext += segDur;
        nb++
    }

    if (nb <= nMax) {
        delta = t - tCur;
        value + vu*delta*(vl - g*delta/2);
    } else {
        value
    }
} else
    value

Be sure to return an Array of two values if you are dealing with something like position for example.

Overshoot

freq = 3;
decay = 5;
n = 0;

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

if (n > 0) {
    t = time - key(n).time;
    amp = velocityAtTime(key(n).time - .001);
    w = freq<em>Math.PI</em>2;
    value + amp<em>(Math.sin(t</em>w)/Math.exp(decay*t)/w);
} else
    value

Here again, make sure to return an Array if the property requires two values.

Looping

First, trim your layer to where the last keyframe is. Then right click on it, select Time > Enable Time Remapping (or ctrl/cmd+alt/option+t). Finally, alt/option-click the clock icon to open up an expression field, and add:

loop_out("cycle",0)

Random time-based values

Let’s say you want to make an eye blink at random intervals, but don’t want to or can’t make an extra graphic for this. With the following snippet, you can scale the open eye graphic down to a stripe to make it look like a blink.

minSeg = 2.0; // min wait
maxSeg = 5.0; // max wait
blinkDur = .1; // duration of the blink
blinkScale = 20; // yScale

seedRandom(index,true)
segStartTime = -random(minSeg,maxSeg);
segEndTime = segStartTime;
i = 1;

while (time >= segEndTime) {
    i += 1;
    seedRandom(i,true);
    segStartTime = segEndTime;
    segEndTime = segEndTime + random(minSeg,maxSeg);
}

if (time > segStartTime + blinkDur) [100, 100] else [100, blinkScale]

Random time-based trigger with damping

The same can be done, but this time with easing. This is great for animating for example bar graphs, or have flies shoot around the screen.

segMin = .3; // min duration
segMax = .7; // max duration
minVal = 218; // min value
maxVal = 234; // max value
start = 0;
end = 0;
j = 0;

while (time >= end) {
    j += 1;
    seedRandom(j,true);
    start = end;
    end += random(segMin,segMax);
}

endVal = random(minVal,maxVal);
seedRandom(j-1,true);
dummy=random(); //this is a throw-away value
startVal = random(minVal,maxVal);
ease(time,start,end,startVal,endVal)

Source: http://www.motionscript.com/articles/bounce-and-overshoot.html