Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions keyframe from x to y, with controlled variation – how?

  • keyframe from x to y, with controlled variation – how?

    Posted by Ling Talfi on July 6, 2016 at 1:21 pm

    Hi,
    my goal here is to find an expression for the following scenario.

    I have a layer with 2 (manually set) keyframes for property p, with values x and y.
    But now I want to introduce some variation on x and y.

    Why?
    Because I plan to:
    – save this animation as a preset
    – create multiple layers
    – apply the preset to all the layers at once so that I have some kind of organic feel to the layers rather than just the EXACT same animation preset applied

    So, if v is the variation and v=10, then the expression I’m looking for should re-set the value of x to x +-10, and y to y +-10.

    So far, I only have thoughts about it:

    – find a fixed number based on the layer name (n1, n2, n3…) that whould be used to choose a fixed v variation number
    – find the two keyframes on the layer, and store their base values in variables
    – then apply the variation to those numbers, and re-set x and y depending on which frame (relative position between x and y using linear interpolation) the current time indicator is at
    – hope that works

    I’ll be able to work on it tomorrow, but maybe in the meantime somebody already knows how to do it?
    Otherwise I’ll put the results of my experiments hereafter…

    Ling Talfi replied 9 years, 10 months ago 2 Members · 3 Replies
  • 3 Replies
  • Kalleheikki Kannisto

    July 6, 2016 at 2:25 pm

    So, if I understand this correctly, you want to affect the x and y positions of keyframes only by +-v ?

    In my mind, that will require an array (of the same lenght as how many keyframes there are) to store random numbers for x and y offsets per keyframe, then a linear interpolation between the offsets are added to the x, y position depending on where you are between keyframes.

    Do you want to be able to control this amount by the layer name for each layer individually, or is a global setting enough? For a global variable, I’d use a slider.

  • Ling Talfi

    July 7, 2016 at 10:36 am

    @Kalle Kannisto
    In other words, I want to be able to apply the preset to any layer, and it would basically re-use
    the existing keyframes’ position, but actually change their values from x,y to x+-v, y+-v.

  • Ling Talfi

    July 7, 2016 at 4:50 pm

    Organic animation preset script
    ================================

    Goal
    ———
    You have an existing animation between two keyframes A and B.
    This script adds some variation on A and B values.
    It actually only works with linear interpolation between A and B.

    Use case, why?
    ———–
    I have a video with two guys fighting.
    In order to make the fight more spectacular, I want to create some impacts on every punch, like on a “street fighter” game.
    So I manage to create an impact glow on a layer, using the “CC Light Burst 2.5” and Glow effects.
    To add more realism, I add some short animation on those effects (using a start and end keyframe on different props of the effects).

    Now I know that I need to repeat the process for every punch, so I save the layer’s effects as an animation preset.
    Then I just need to re-apply the animation preset on every layer, …
    the only problem with that is that the effects will look exactly the same on each layer,
    so I want to induce little variation on them: instead of having keyframe A=>x and B=>y, I want A => x+-v and B => y+-v.

    So, that’s what the script below basically does, it chooses a variation number and applies it to the keyframes.

    How
    ———
    Animate a property using two keyframes A and B.
    Set the value of the property at keyframe A to x,
    and the value of the property at keyframe B to y.

    Then, add the script below as an expression to the property (alt+click).
    You need to understand the script and configure it accordingly too.

    Here are some insights.
    The script expects that your layers are named n1, n2, n3…
    Good luck.

    Script
    ————
    // docs: https://forums.creativecow.net/thread/227/33228
    var prefixLength = 1; // a layer is named
    var startVariationFactor = 1; // the layerNumber will first be multiplied by this startVariationFactor…
    var startVariationDelta = 30; // …then modulo-ed to this startVariationDelta…
    // … then if the layer number is odd, the variation will be subtracted from the keyframe’s base value,
    // or added if the layer number is even.

    var endVariationFactor = 1; // the number of the layer will first be multiplied by this endVariationFactor…
    var endVariationDelta = 30; // …then moduloed to this endVariationDelta…
    // … then if the layerNumber modulo 3 is equal to 0, then the sign of the variation will be the same
    // as the one of the start variation, and if not, it will be of the reverse sign

    var useRemote = false; // default=false, set to true when you want to debug and apply this script on a remote text layer which displays the debug var…

    // set the variables below ONLY IF you are debugging and you apply this script to a text layer
    var layerName = “n1”;
    var effectName = “CC Light Burst 2.5”;
    var effectName = “Glow”;
    var effectParamId = “Ray Length”;
    var effectParamId = “Glow Intensity”;

    /**
    * SCRIPT
    * ———————————————-
    * You shouldn’t have to edit below this line…
    */
    // define fxProp
    if(true === useRemote){
    theLayer = thisComp.layer(layerName);
    fxProp = theLayer.effect(effectName).param(effectParamId);
    }
    else{
    layerName = thisLayer.name;
    fxProp = thisProperty;
    }

    var theLayer = thisComp.layer(layerName);
    var layerNumber = parseInt(layerName.substr(prefixLength));

    // getting the frame number of the 2 keyframes
    var fxStartFrame = theLayer.timeToFrames(fxProp.key(1).time);
    var fxEndFrame = theLayer.timeToFrames(fxProp.key(2).time);

    // getting the 2 keyframes’ values
    var fxStartValue = fxProp.key(1);
    var fxEndValue = fxProp.key(2);

    var debug = “”;
    debug += “Raw: ” + fxStartFrame + ” => ” + fxStartValue[0] + “; ” + fxEndFrame + ” => ” + fxEndValue[0];

    // creating the variation values
    var startVariationValue = (layerNumber * startVariationFactor) % startVariationDelta;
    var isNegative = (1 === layerNumber % 2);
    debug += “\nisNegative: ” + isNegative;
    debug += “\nstartVariationValue: ” + startVariationValue;

    var endVariationValue = (layerNumber * endVariationFactor) % endVariationDelta;
    var isSameSign = (0 === layerNumber % 3);
    debug += “\nendVariationValue: ” + endVariationValue;
    debug += “\nsameVariationSign: ” + isSameSign;

    // update the values using variation
    if(isNegative){
    fxStartValue -= startVariationValue;
    }
    else{
    fxStartValue += startVariationValue;
    }
    if(isSameSign){
    if(isNegative){
    fxEndValue -= endVariationValue;
    }
    else{
    fxEndValue += endVariationValue;
    }
    }
    else{
    if(isNegative){
    fxEndValue += endVariationValue;
    }
    else{
    fxEndValue -= endVariationValue;
    }
    }

    debug += “\nProcessed: ” + fxStartFrame + ” => ” + fxStartValue + “; ” + fxEndFrame + ” => ” + fxEndValue;

    // now get the current frame
    var curFrame = thisLayer.timeToFrames(time);
    debug += “\ncurFrame: ” + curFrame;

    // prepare the linear interpolation values
    var nbSteps = fxEndFrame – fxStartFrame; // assert this is >0
    debug += “\nnbSteps: ” + nbSteps;
    var valueRange = (fxEndValue – fxStartValue);
    debug += “\nvalueRange: ” + valueRange;
    var stepIncrement = (fxEndValue – fxStartValue) / nbSteps;
    debug += “\nstepIncrement: ” + stepIncrement;

    // apply to the current frame
    var newValue = (curFrame – fxStartFrame) * stepIncrement + fxStartValue;
    debug += “\ncurValue: ” + newValue;

    var ret = newValue;
    if(true === useRemote){
    ret = debug;
    }
    ret

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