Forum Replies Created

Page 1 of 2
  • Christian Geijer

    December 16, 2019 at 8:37 am in reply to: Editing graph when an ‘ease’ expression is used

    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

  • This maybe isn’t exactly what you want but it might help you on your way.

    One way could be to create a .json-file with all the different positions mapped to the corresponding slider value like this:
    {
    "positions": {
    "1": {
    "x": 2,
    "y": 54
    },
    "2": {
    "x": -4,
    "y": -174
    }
    }
    }

    Place the .json-file (here named data.json) in your composition and then, with the value from Master slider (in my example placed on a null layer named “Control”), change the position of the object you want to move around with an expression that looks something like this:
    id = thisComp.layer("Control").effect("Master slider")("Slider").toString;
    x = thisComp.layer("data.json").source.sourceData.positions[id].x;
    y = thisComp.layer("data.json").source.sourceData.positions[id].y;
    [x,y]

    This, however, only works with the slider being set to whole numbers that you also have defined in data.json and does not work if the slider animates between the different values. You maybe can define the first and second positions and use linear() to animate between them, but I’m not sure how you’d want that to work in your specific case.

  • Christian Geijer

    April 24, 2019 at 7:31 am in reply to: Text Size Constrained By Width X

    This is one way. Apply this to the scale property.

    L = thisLayer;
    w = L.sourceRectAtTime().width;

    maxW = 500;
    sca = (maxW/w) * 100;

    [sca, sca]

  • Christian Geijer

    October 19, 2018 at 7:22 am in reply to: Change time between keyframes

    I just wanted to return to this in case any stray googler finds this and wonders the same thing.
    I think I’ve solved it. I’m going to expand on this and build some more control over the timings, but the foundation that I’ve built is this. If anyone have some tips for improvement, I appreciate any pointers. But as for now, I think it works.

    Cheers!

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

    tAnimInStart = 1;
    tAnimInDuration = 0.5;

    tAnimOutDuration = 0.5;
    tAnimOutStart = 3;

    holdVal = 880;
    inVal = 200;
    outVal = 540;

    if (time < tAnimInStart){
    inVal

    } else if (time >= tAnimInStart && time < (tAnimInStart + tAnimInDuration)) {
    t = time - tAnimInStart;
    d = iAnimInKeys.key(2).time - iAnimInKeys.key(1).time;
    linear(iAnimInKeys.valueAtTime(iAnimInKeys.key(1).time + d*t/tAnimInDuration), 0, 100, inVal, holdVal)

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

    } else if (time >= tAnimOutStart && time < (tAnimOutStart + tAnimOutDuration)) {
    t = time - tAnimOutStart;
    d = iAnimOutKeys.key(2).time - iAnimOutKeys.key(1).time;
    linear(iAnimOutKeys.valueAtTime(iAnimOutKeys.key(1).time + d*t/tAnimOutDuration), 0, 100, outVal, holdVal);

    } else {
    outVal

    }

  • Christian Geijer

    October 5, 2018 at 7:11 am in reply to: Change time between keyframes

    Awesome. Thanks for the tip!

  • Christian Geijer

    October 4, 2018 at 12:22 pm in reply to: Change time between keyframes

    Hi,

    A large and late bump, but I thought to reply here instead of starting a new thread.

    I have a template where I’ve placed two sliders with two keyframes each on a control null.
    These two sliders are the “masters” for different animations within the comp. One for “build in” and one for “build out”:

    I’ve written an expression that I can apply to every layer and property I want to control with a linear-function mapped to the “masters”.

    It looks like this:

    animIn = thisComp.layer("Control").effect("Anim in")("Slider");
    animOut = thisComp.layer("Control").effect("Anim out")("Slider");
    dur = thisComp.layer("Control").effect("Duration")("Slider");

    inBuffer = 0;
    outBuffer = 0;

    animInTime = animIn.key(2).time - animIn.key(1).time;
    animOutTime = animOut.key(2).time - animOut.key(1).time;

    animInStart = 0 + inBuffer;
    animOutStart = dur - animOutTime - outBuffer;

    // calculations for inVal, holdVal, outVal, if needed

    holdVal = 100;
    inVal = 0;
    outVal = inVal;

    if(time <= animInStart) {
    inVal
    } else if(time >= animInStart && time < animInStart + animInTime) {
    linear(animIn.valueAtTime(time - animInStart), 0, 100, inVal, holdVal)
    } else if(time >= animOutStart) {
    linear(animOut.valueAtTime(time - animOutStart), 0, 100, outVal, holdVal)
    } else {
    holdVal
    }

    animIn and animOut are the master sliders that go from 0-100 and 100-0 respectively.

    The expression uses the animIn-slider to shift from inVal to holdVal and then holds holdVal.
    It holds holdVal until it’s time to shift, with the animOut-slider, from holdVal to outVal.

    I’ve also built in inBuffer and outBuffer so I can stagger the animation if I want to.

    I’ve tried to integrate your expression in this thread with mine, but I really can’t get it to work. Both due to that I’m not an expert on expressions and that I really don’t understand how yours works.

    In short; I would like to be able to change the duration between the keyframes within animIn and animOut individually with sliders. Is it possible to marry these two expressions together? If yes, how would I go about doing that? Any tips or help you can give me would be appreciated.

    Best regards,
    /C

  • Of course! Thank you so much for your help.
    Have a great week!

    /C

  • Great stuff! Thank you for your help!

    /C

  • Christian Geijer

    March 8, 2018 at 8:31 am in reply to: changing text color within a “tag”

    Hi again.

    I appreciate the help, but is it okay if I ask another question regarding this?
    Your solution works, but it takes about ten times more time to preview and render. Is that something that is solvable, or are these kinds of looping expressions just too heavy for After Effects? is it possible to reduce the times in any way?

    Thanks
    /C

  • Christian Geijer

    March 7, 2018 at 8:38 pm in reply to: changing text color within a “tag”

    Amazing! It works perfectly!

    The only thing is that we import the sourceText value from a .json file embedded in the project. When changing the text in that file I get an error.
    “Error at line 7 in property ‘Amount’ (…) property or method named 62 in Class ‘TextProperty’ is missing or does not exist.”
    But when I enter edit mode in the expression on ‘Amount’ and just apply the expression again, everything works. It somehow doesn’t like having the text changed externally.

    However, if I import the text value on a different text layer, and point to that sourceText from my first layer, everything works even when updating the values.

    If the external connection doesn’t like the .json connection, this is a way to go around it.

    Thank you once again. I really appreciate the help.

    /C

Page 1 of 2

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