Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Editing graph when an ‘ease’ expression is used

  • Editing graph when an ‘ease’ expression is used

    Posted by Nikolay Arkhipov on December 13, 2019 at 3:53 pm

    Hi Everyone! I suddenly found out that it’s impossible to edit graph when I use ‘ease’ expression… (or, am I doing smth wrong)?
    For example, I make keyframes for position and type:

    x1 = thisComp.layer(“TEXT”).sourceRectAtTime().height +2;
    x2 = ease(time, key(1).time, key(2).time, x1, value[0]) + ease(time, key(3).time, key(4).time, 0, x1);
    [value[0], x2]

    But since then I can’t edit the graph, and the default ‘easing’ is not enough for me… I understand that the ‘linear’ doesn’t give a chance to edit a graph, but what’s wrong with the ‘ease’ expression? Can I somehow make the ‘ease’ expression more controlable?

    Thanks.

    Alex Printz replied 6 years, 4 months ago 4 Members · 7 Replies
  • 7 Replies
  • Andrei Popa

    December 13, 2019 at 6:22 pm

    You can’t edit the ease function. It uses the default easing graph(the 0 speed, 33% influence)

    Andrei
    My Envato portfolio.

  • Nikolay Arkhipov

    December 13, 2019 at 8:27 pm

    That’s sad…
    But is there any alternative? The main idea is just to get movement between these 4 keyframes, when the initial position of the moving object can vary.

  • Christian Geijer

    December 16, 2019 at 8:37 am

    Hey, I’m not sure if this is what you want, but I’ve put together a script to be able to do an in animation from value1 to value2, hold value2 and then do an out animation from value2 to value3 with custom easing curves and timings.

    To set it up, create a null and name it “Control”. Create two sliders, one named “Anim in” and one named “Anim out”. Add keyframes to “Anim in” that goes from 0 to 100. Add keyframes to “Anim out” that goes from 100 to 0. Apply the animation curves that you want the animations to have.

    In the script, change the timing values under // TIMINGS and change the actual values that you want to animate from and to under // VALUES.

    It’s not perfect and there’s probably loads of better ways to do it, but it has worked for me.

    // KEYS
    iAnimInKeys = thisComp.layer("Control").effect("Anim in")("Slider");
    iAnimOutKeys = thisComp.layer("Control").effect("Anim out")("Slider");

    // SLIDERS MIN/MAX
    n = iAnimInKeys.numKeys;
    inMinVal = Infinity;
    inMaxVal = -Infinity;

    for (var i = 1; i <= n; i++) {
    if(iAnimInKeys.key(i).value < inMinVal) {
    inMinVal = iAnimInKeys.key(i)
    }
    if(iAnimInKeys.key(i).value > inMaxVal) {
    inMaxVal = iAnimInKeys.key(i)
    }
    }

    n = iAnimOutKeys.numKeys;
    outMinVal = Infinity;
    outMaxVal = -Infinity;

    for (var i = 1; i <= n; i++) {
    if(iAnimOutKeys.key(i).value < outMinVal) {
    outMinVal = iAnimOutKeys.key(i)
    }
    if(iAnimOutKeys.key(i).value > outMaxVal) {
    outMaxVal = iAnimOutKeys.key(i)
    }
    }
    iAnimInMin = inMinVal;
    iAnimInMax = inMaxVal;

    iAnimOutMax = outMaxVal;
    iAnimOutMin = outMinVal;

    // TIMINGS
    tAnimInStart = 0;
    tAnimInDuration = 0.5;

    tAnimOutDuration = 0.5;
    tAnimOutStart = 3;

    // VALUES
    inVal = 0;
    holdVal = 100;
    outVal = 0;

    // ANIM VALUES CALC
    iAnimInVal1 = inVal - ((holdVal - inVal) * (iAnimInMin/-100));
    iAnimInVal2 = inVal + ((holdVal - inVal) * (iAnimInMax/100));

    iAnimOutVal1 = outVal - ((holdVal - outVal) * (iAnimOutMin/-100));
    iAnimOutVal2 = outVal + ((holdVal - outVal) * (iAnimOutMax/100));

    // ANIMATION
    if (time < tAnimInStart){
    animVal = inVal

    } else if (time >= tAnimInStart && time < (tAnimInStart + tAnimInDuration)) {
    t = time - tAnimInStart;
    d = iAnimInKeys.key(iAnimInKeys.numKeys).time - iAnimInKeys.key(1).time;
    animVal = linear(iAnimInKeys.valueAtTime(iAnimInKeys.key(1).time + d*t/tAnimInDuration), iAnimInMin, iAnimInMax, iAnimInVal1, iAnimInVal2)

    } else if(time >= (tAnimInStart + tAnimInDuration) && time < tAnimOutStart) {
    animVal = holdVal

    } else if (time >= tAnimOutStart && time < (tAnimOutStart + tAnimOutDuration)) {
    t = time - tAnimOutStart;
    d = iAnimOutKeys.key(iAnimOutKeys.numKeys).time - iAnimOutKeys.key(1).time;
    animVal = linear(iAnimOutKeys.valueAtTime(iAnimOutKeys.key(1).time + d*t/tAnimOutDuration), iAnimOutMin, iAnimOutMax, iAnimOutVal1, iAnimOutVal2);

    } else {
    animVal = outVal

    }

    animVal

  • Nikolay Arkhipov

    December 16, 2019 at 10:46 am

    Thanks for your participation, but I’m not sure this is what I need… I can’t find where to put the position values that I have to animate. The very problem is that these values are not numbers. I need to animate the text, that starts moving from its left side and goes to the right on a distance of its length. So, the text size is not constant, that’s why I use sourceRectAtTime expression to define the starting and ending points. And the problem is that I can’t figure out (or simply don’t know) how to animate these points not using “ease” or “linear” expression.

    Example of starting and ending points (Text anchor point is in the center):
    InStart = thisLayer.sourceRectAtTime().left – thisLayer.sourceRectAtTime().width / 2;
    InEnd = thisLayer.sourceRectAtTime().left + thisLayer.sourceRectAtTime().width / 2;

    I was trying to use text animators, and I suppose it was a very good idea, because I could define the position and animate the Start that is in %. BUT the text starts acting very strange when I type an expression for its position… I’ve even posted another post concerning this problem yesterday.

  • Nikolay Arkhipov

    December 17, 2019 at 9:14 am

    Thanks for everybody for taking part. I’ve finally found a solution.

    If it is interesting for somebody:

    I created a Null object and put a slider on it. Then I just created keyframes for this slider – 0 and 100. These particular keyframes are the future animation between the 1st and the 2nd position that I needed.
    So, finally I just turned the position numeric values into % using a formula and made them dependent on this slider.

    In this way one can animate the position of an object, using not numbers, but its realtime height or width.

    P.S. In script below the anchor point of the layer is in the center, so as the anchor point of the Null.

    x1 = thisComp.layer("Null").transform.position.value[0] - thisLayer.sourceRectAtTime().width;
    x2 = thisComp.layer("Null").transform.position.value[0];
    s = thisComp.layer("Null").effect("Animation")("Slider");
    x = x2 - (100 - s) * (x2 - x1) / 100;
    y = thisComp.layer("Null").transform.position.value[1];
    [x, y]

  • Nikolay Arkhipov

    December 17, 2019 at 10:06 am

    And the most important thing is that this method makes possible editing graph.

  • Alex Printz

    December 17, 2019 at 3:49 pm

    You could always do something like the code below for quick and dirty force-easing between all of your keys. Just set the keys to ‘continuous bezier’ and then edit the linearity to adjust the easing output post-expression.

    Just make sure you turn on the expression view in the graph editor to see what is actually happening.

    In the past I’ve also built custom Penner easing expressions and built a cubic Bezier easing expression, but neither of those are quick and easy to implement, but allow totally-customizable easing expressions quickly and easily once you have the expressions built.

    note: plugins “ease and wizz” is Penner functions, and “Flow” is cubic beziers, if you don’t want to write your own.

    if(thisProperty.velocity == 0) value; else{
    n=thisProperty.nearestKey(time).index;
    if(key(n).time>time)n--;
    valueAtTime(ease(time,key(n).time, key(n+1).time, key(n).time, key(n+1).time))
    };

    Alex Printz
    Mograph Designer

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