Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions better than ease ?

  • better than ease ?

    Posted by Adam Greenberg on May 25, 2021 at 5:10 pm

    Hi All. I am making a template where the start of an animation is dependant on the size of the text layer, but the ending position is always fixed. I have managed to do everything correctly with the use of nulls and markers to drive the animation. The problem is the movement is not the same because the original animation was using the ease and wizz. Now that I no longer have keyframes is there a way to simulate this movement which seems to be a much steeper curve than regular ease.

    here is the code on 1 of my null layers, and it is already using ease as you can see. But its not good enough;

    startmarker = thisComp.marker.key(1).time;

    endmarker = thisComp.marker.key(2).time;

    xinposition = thisComp.layer(“IN”).transform.position[0];

    yinposition = thisComp.layer(“IN”).transform.position[1];

    xoutposition = thisComp.layer(“OUT”).transform.position[0];

    youtposition = thisComp.layer(“OUT”).transform.position[1];

    x = ease(time, startmarker, endmarker, xinposition, xoutposition);

    y = ease(time, startmarker, endmarker, yinposition, youtposition);

    [x,y]

    thanks so much

    Adam Greenberg replied 2 years, 6 months ago 3 Members · 9 Replies
  • 9 Replies
  • Dan Ebberts

    May 25, 2021 at 5:25 pm

    You could add your own ease function to the expression, but you’d need to know which of the ease and wizz functions you’re trying to emulate.

  • Adam Greenberg

    May 25, 2021 at 5:43 pm

    yes it seems quite complicated, maybe I can do trial and error, Would you be able to give me an example of what part of the expression I would have to modify ?

  • Dan Ebberts

    May 25, 2021 at 6:03 pm

    I can probably do better than that, but I need to know what kind of ease you want. Do you still have access to the ease and wizz expression? It usually tells you right at the top which of the Penner eases it’s using.

  • Adam Greenberg

    May 25, 2021 at 6:05 pm

    yes, this is the code that was in the project

    // Ease and Wizz 2.0.1 : inOutExpo : All keyframes

    // Ian Haigh (http://ianhaigh.com/easeandwizz/)

    // Last built: 2010-10-09T13:35:40+11:00

    // some defaults

    var p = 0.8; // period for elastic

    var a = 50; // amplitude for elastic

    var s = 1.70158; // overshoot amount for “back”

    function inOutExpo(t, b, c, d, a, p) {

    if (t==0) return b;

    if (t==d) return b+c;

    if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t – 1)) + b;

    return c/2 * (-Math.pow(2, -10 * –t) + 2) + b;

    }

    function easeAndWizz() {

    var n = 0;

    if (numKeys > 0) {

    n = nearestKey(time).index;

    if (key(n).time > time) { n– }

    }

    try {

    var key1 = key(n);

    var key2 = key(n+1);

    } catch(e) {

    return null;

    }

    // determine how many dimensions the keyframes need

    var dim = 1; // It’s gotta have at least ONE dimension

    try {

    key(1)[1];

    dim = 2;

    key(1)[2];

    dim = 3;

    } catch(e) {}

    t = time – key1.time;

    d = key2.time – key1.time;

    sX = key1[0];

    eX = key2[0] – key1[0];

    if (dim >= 2) {

    sY = key1[1];

    eY = key2[1] – key1[1];

    if (dim >= 3) {

    sZ = key1[2];

    eZ = key2[2] – key1[2];

    }

    }

    if ((time < key1.time) || (time > key2.time)) {

    return value;

    } else {

    val1 = inOutExpo(t, sX, eX, d, a, p, s);

    switch (dim) {

    case 1:

    return val1;

    break;

    case 2:

    val2 = inOutExpo(t, sY, eY, d, a, p, s);

    return [val1, val2];

    break;

    case 3:

    val2 = inOutExpo(t, sY, eY, d, a, p, s);

    val3 = inOutExpo(t, sZ, eZ, d, a, p, s);

    return [val1, val2, val3];

    break;

    default:

    return null;

    }

    }

    }

    (easeAndWizz() || value);

  • Dan Ebberts

    May 25, 2021 at 6:23 pm

    I think InOutExpo would be like this:

    function myEase(curT,t1,t2,val1,val2){

    if(curT <= t1)return val1;

    if(curT >= t2)return val2;

    dtEase = t2 - t1;

    dvEase = val2 - val1;

    tEase = (curT-t1)/dtEase;

    if(tEase < .5) return val1 + (dvEase/2)*Math.exp(10*(2*tEase-1));

    return val1 + dvEase*(1-Math.exp(10*(1-2*tEase))/2);

    }

    startmarker = thisComp.marker.key(1).time;

    endmarker = thisComp.marker.key(2).time;

    xinposition = thisComp.layer("IN").transform.position[0];

    yinposition = thisComp.layer("IN").transform.position[1];

    xoutposition = thisComp.layer("OUT").transform.position[0];

    youtposition = thisComp.layer("OUT").transform.position[1];

    x = myEase(time, startmarker, endmarker, xinposition, xoutposition);

    y = myEase(time, startmarker, endmarker, yinposition, youtposition);

    [x,y]

  • Kevin Camp

    May 25, 2021 at 7:09 pm

    Another approach (I use this a lot when I manually adjust velocity curves) is to apply the velocity changes to a slider value to use for timing, then interpolate those values for the result.

    You can apply the slider anywhere, but I often create a null, name it Control and add it there. Keyframe the slider to go from 0 – 1 at the time that you need, then you could adapt your expression like this:

    d = thisComp.layer("Control").effect("Slider Control")("Slider") ;
    xinposition = thisComp.layer("IN").transform.position[0];
    yinposition = thisComp.layer('IN').transform.position[1];
    xoutposition = thisComp.layer('OUT').transform.position[0];
    youtposition = thisComp.layer('OUT').transform.position[1];
    x = linear(d, xinposition, xoutposition);
    y = linear(d, yinposition, youtposition);
    [x,y]

    If you apply your ease and wizz to the slider, or make any other adjustments to the key frame velocities, the layer with the expression should follow the timing of the slider’s velocity.

  • Adam Greenberg

    May 25, 2021 at 10:49 pm

    Wow. seemless. Works perfectly. I need to study this more in depth to better understand what s going on.

    And Kevin. I will need to try yours as well because I think I know a project we have somewhere that needs somethnig like this.


    Thanks to both of you. Much appreciated.


    Adam

  • Dan Ebberts

    May 25, 2021 at 11:41 pm

    It occurred to me that you can simplify this somewhat just by eliminating all the separate x and y stuff, like this:

    function myEase(curT,t1,t2,val1,val2){

    if(curT <= t1)return val1;

    if(curT >= t2)return val2;

    dtEase = t2 - t1;

    dvEase = val2 - val1;

    tEase = (curT-t1)/dtEase;

    if(tEase < .5) return val1 + (dvEase/2)*Math.exp(10*(2*tEase-1));

    return val1 + dvEase*(1-Math.exp(10*(1-2*tEase))/2);

    }

    startmarker = thisComp.marker.key(1).time;

    endmarker = thisComp.marker.key(2).time;

    inposition = thisComp.layer("IN").transform.position;

    outposition = thisComp.layer("OUT").transform.position;

    myEase(time, startmarker, endmarker, inposition, outposition);

  • Adam Greenberg

    May 26, 2021 at 6:19 pm

    Oh that`’s really interesting, I would never think that would work. I guess one would keep the old way if you were to attribute different functions for the x then the y

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