javascriptmatheasinglinear-interpolationeasing-functions

is there a programming / math term for what the linear() function does in After Effects?


Adobe After Effects (an animation / compositing app) has a scripting language (Expressions) that's based on JavaScript, and it comes with a bunch of After Effects-specific functions built on top of JS. The function linear() is one of these. It considers the animated change in one object's property (say, the X position of a slider) and links that to another property (say, the rotation of some other object in the scene), so that the first animated property controls / animates the second property.

If that explanation is confusing, see 11:33 in this vid: https://www.youtube.com/watch?v=gK1Ejt7qND0&t=693s

The linear() function call looks like this:

linear(ref, refStart, refEnd, outStart, outEnd);

I don't know what the actual internal arg names are, but this is what they do:

ref == the "controller" property (in my earlier example, the X position of an object). Usually animated, varies over time.

refStart / refEnd == the lower and upper bounds of the ref property

outStart / outEnd == the lower and upper bounds of the destination property (in my earlier example, the rotation of another object)

Is there generic programming term for what this function does? Or a math term? As far as I can tell, it's something involving "interpolation," maybe linear interpolation, but I'm unclear.

Are there general programming / math libraries that include the equivalent of this function? After Effects also has eased versions of linear(), called ease(), easeIn(), and easeOut(). As far as I can tell, those might be called "easing functions" in programming, but not sure.

Bonus: I tried my hand at reverse-engineering AE's linear() from scratch. Pretty barebones and doesn't do any type checking or errors, but otherwise it seems to work identically in my testing in AE:

function fauxLinear( ref, refStart, refEnd, outStart, outEnd ) {
    // constrain refTemp to range of refStart to refEnd
    let refTemp = 0;
    const refMin = Math.min( refStart, refEnd );
    const refMax = Math.max( refStart, refEnd );

    refTemp =   (ref < refMin) ? refMin :
                (ref > refMax) ? refMax : ref;

    // calculate input range and ref proportion
    const refRange = Math.abs( refStart - refEnd ) || .001; // avoid dbz
    const refRangeTarget = Math.abs( refMin - refTemp );
    const refProportion = refRangeTarget / refRange;

    // calculations for final output
    let outRange = [], outSlope = [], finalVal = [];
    const loopLen = ( Array.isArray( outStart ) ) ? outStart.length : 1;
    if (loopLen == 1) { outStart = [outStart], outEnd = [outEnd]; }

    for (let i = 0; i < loopLen; i++) {
        outRange[i] = Math.abs( outStart[i] - outEnd[i] );
        outSlope[i] = ( outStart[i] <= outEnd[i] ) ? 1 : -1;
        finalVal[i] = ( outSlope[i] * (outRange[i] * refProportion) + outStart[i] );
    }

    return ( loopLen == 1 ) ? finalVal[0] : finalVal;
}

Solution

  • Yes this is a function which does Linear Interpolation some languages have a lerp() function or equivilent. But there does no seem to be anything in the javascript Math class.