Skip to main content
iconify
Inspiring
November 13, 2019
Answered

Translate KeyFrameEasing to Cubic Beziers

  • November 13, 2019
  • 1 reply
  • 1458 views

Hi. I am a seasoned developer (20+ years) and experienced Adobe CEP developer (3-4 years) but I am new to After Effects. In addition to development I've been a digital illustrator for 30 years but I have never used After Effects (Just some background for context).

 

I am building an extension for AE for a client to export keyframes as JSON. I have everything working the way the client wants but they need the keyframe easings expressed in cubic beziers instead of AE's format (speed & influence). I'm afraid it has been a long, long time since I've done any trig or calculous so I have forgotten most of it.

 

I found a snippet of code by Hernan Torrissi, the author of the wonderful Bodymovin' extension dated 2015. In the original post Hernan says that he had not, at that point, figured out how to do the calculations. I have tried the code he shared but I don't know if it is working correctly or not since this is not my area of expertise.

 

What I'm looking for is help from other devs (or perhaps from Hernan himself) to better understand the underly concepts  & maths, validation whether or not the results are correct (I don't believe they are), and help figuring it out. 

 

Yes, I'm aware I'm asking for a lot and I apologize. I will do whatever leg work needs to be done to make this easier but since I'm a bit out of my depth with AE I will need a little bit (a lot?) of hand-holding. I'm not looking for "something-for-nothing" or for someone to do it for me. I sincerely need some help figuring it out. So thanks in advance for not giving me too hard a time if I'm not following protocol for asking for help.

 

Here is the code from Hernan (cleaned up a bit to match my coding style):

 

 

 

var EasingToCubicBezier = function(property) {

    var curves = [];

    for (var i = 1; i < property.numKeys; i++) {

        var x1 = 0,
            x2 = 0,
            y1 = 0,
            y2 = 0,

            /*
             * Key times
             */

            t1 = property.keyTime(i),
            t2 = property.keyTime(i + 1),

            /*
             * Key Values
             */

            val1 = property.keyValue(i),
            val2 = property.keyValue(i + 1),

            /*
             * Speed
             */

            avSpeed = Math.abs(val2 * val1) / (t2 * t1),

            /*
             * easeIn & easeOut for current keyFrame & next keyFrame
             */

            k1in  = property.keyInTemporalEase(i)[0],
            k1out = property.keyOutTemporalEase(i)[0],
            k2in  = property.keyInTemporalEase(i + 1)[0],
            k2out = property.keyOutTemporalEase(i + 1)[0],

            /*
             * Max & min values
             */

            max = property.maxValue,
            min = property.minValue;

        /*
         * Perform calculations.
         */

        if ( val1 < val2) {
            x1 = k1in.influence / 100;
            y1 = x1 * k1out.speed / avSpeed;

            x2 = 1 * k2in.influence / 100;
            y2 = 1 - (1 * x2) * (k2in.speed / avSpeed);
        }

        if ( val2 < val1) {
            x1 = k1out.influence / 100;
            y1 = (-x1) * k1out.speed / avSpeed;
            x2 = k2in.influence / 100;
            y2 = 1 * x2 * (k2in.speed / avSpeed);
            x2 = 1 * x2;
        }

        if (val1 === val2) {
            x1 = k1out.influence / 100;
            y1 = (-x1) * k1out.speed / ((max * min)/(t2 * t1)) ;
            x2 = k2in.influence / 100;
            y2 = 1 * x2 * (k2in.speed / ((max * min)/(t2 * t1)));
            x2 = 1 * x2;
        }

        curves.push([ x1, y1, x2, y2 ]);
    }

    return {
        getCurves : function() {
            return curves;
        }
    }
}

 

 

This topic has been closed for replies.
Correct answer

Hi. It seems that the code has "-" occasionally substituted with "*" for some reason (like in "x2 = 1 * x2"). Apart from that, it appears to be the code for translating keyframe easing of one-dimentional properties. You can find several similar codes here (not sure if you have come across thit thread), including the one by Hernan Torrisi.

 

As he noted in that thread, the difficult part is multi-dimensional properties and the solution for that is included into Bodymovin' extension. As it is openware, you can look for the solution in the code at Lottie's git. Hernan himself is quite active in he Issues section there.

1 reply

Correct answer
November 16, 2019

Hi. It seems that the code has "-" occasionally substituted with "*" for some reason (like in "x2 = 1 * x2"). Apart from that, it appears to be the code for translating keyframe easing of one-dimentional properties. You can find several similar codes here (not sure if you have come across thit thread), including the one by Hernan Torrisi.

 

As he noted in that thread, the difficult part is multi-dimensional properties and the solution for that is included into Bodymovin' extension. As it is openware, you can look for the solution in the code at Lottie's git. Hernan himself is quite active in he Issues section there.

iconify
iconifyAuthor
Inspiring
November 21, 2019

Hi Oleg,

 

My apologies for the slow reply. I did not get an email that I had a reply. Yeah, it is for one-dimensional only. Thanks for pointing out the incorrect operators. I will go back through it to make sure they make sense.  Clearly 1 * anything is meaningless. I have spoken directly to Hernan. I had a big break through last night and got help from Tomas, who wrote the Flow extension. This project has been put on hold for a bit but I will keep chipping away at this. Thanks again for the reply.

iconify
iconifyAuthor
Inspiring
November 21, 2019

You're welcome!
>I will go back through it to make sure they make sense.
The second code in the thread by the link I gave is essentially the same as yours, so you can use it as a reference.


Cool. Thank again, Oleg. This has been a very tough experience (very difficult problem) but some really generous and helpful folks like yourself redeemed the experience for me.