Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Layer movement in expression

  • Layer movement in expression

    Posted by Melissa Franch on April 19, 2024 at 9:14 am

    Hello!

    I want to make a graphical representation of an after curve.

    I have achieved this part, I have a shape layer with this expression in the path:

    var margen = thisComp.layer(“Controls”).effect(“Margen”)(“Slider”);

    var compSize = thisComp.width – margen;

    var point01 = thisComp.layer(“Point 01”).transform.position;

    var point02 = thisComp.layer(“Point 02”).transform.position;

    var handle01 = thisComp.layer(“Handle 01”).transform.position;

    var handle02 = thisComp.layer(“Handle 02”).transform.position;

    var hX01 = thisComp.layer(“Controls”).effect(“Handle 01”)(“Slider”);

    var convertX01 = linear(hX01,0,100,0,compSize);

    var hX02 = thisComp.layer(“Controls”).effect(“Handle 02”)(“Slider”);

    var convertX02 = linear(hX02,100,0,0,-compSize);

    var points = [

    fromComp(point01),

    fromComp(point02)

    ];

    var inTangents = [

    [0,0],

    [convertX02,0]

    ];

    var outTangents = [

    [convertX01,0],

    [0,0]

    ];

    createPath(points, inTangents, outTangents, false)

    There are some variables that are used to control the size of the graph or other things, but I want to focus my question on the curve that I have generated.

    This curve controls with two sliders that I have converted to values from 0% to 100% to make it more comfortable, but I could still convert them to values from 0 to 1 (cubic-bezier)

    The problem that I cannot solve is that now I want a ball to go along the path of the curve to show what movement that curve has, for this I have a layer with a ball that pays attention to a trim paths that I have in the layer of the curve:

    var linesLayer = thisComp.layer(“Lines”);

    var path = thisComp.layer(“Lines”).content(“Curve”).content(“Path 1”).path;

    var progress = thisComp.layer(“Lines”).content(“Trim Paths 1”).end / 100;

    var point = path.pointOnPath(progress);

    linesLayer.toComp(point);

    But I need the movement information of this ball to be in the expression and not in the keyframes graph, so that when configuring the curve the ball automatically reflects that movement.

    Brie Clayton replied 2 years, 2 months ago 3 Members · 5 Replies
  • 5 Replies
  • Filip Vandueren

    April 24, 2024 at 1:17 pm

    What do you mean by “the movement information of this ball” ?

  • Melissa Franch

    April 24, 2024 at 2:02 pm

    I want that if the curve has an in ease of 50% and an out ease of 50%, the ball travels the curve with those speeds, and that when the curve changes, the ball takes that information and moves along the curve with that curve of movement .

  • Filip Vandueren

    April 25, 2024 at 11:05 am

    OK, but there’s an important difference between spatial beziers and temporal easing.

    The spatial beziers are defining the shape of the path, and that’s not automatically the same as easing.

    That being said, if you do want to control both easing and the tangents with the same 0-100% controls, I think the ball’s position should still have the same expression, but the easing has to be done on the 0-100% end of the Trim Paths End-parameter.

    There is no built-in method in expressions to mimic keyframes’ custom easing functions with arbitrary velocity and influence, and after effects handles it in a rather quirky way that’s different than for example javascript or css animations.

    Even if we try to recreate a correct bezier-curve for the timing-parameters,
    bezier curves are evaluated in terms of t, while after effects’ easing is more like f(x) instead of f(t).

    Anyway, not to bore you with the theory; here is a hack that gives accurate results:

    – create a new shapelayer, I called it “bezier timing”.

    – add a Path to this layer, no stroke is necessary, it will need to be a hidden layer anyway.

    – the path gets this expression:

    p=createPath([[0,0],[100,100]],[[0,0],[-thisComp.layer("Controls").effect("Handle 02")("Slider").value,0]],[[thisComp.layer("Controls").effect("Handle 01")("Slider").value,0],[0,0]],false);

    – add a slider to the shapelayer, I named it “ease” and give it this expression:

    pt=content("Path 1").path;
    precision = 16;
    x=time/100;
    t=0;
    // binary search the best t-value for a given x
    for (i=0; i<precision; i++) {
    if (pt.pointOnPath(t+(0.5**i))[0]/100 <=x) {
    t+=0.5**i;
    }
    }
    // give y-value at that t
    pt.pointOnPath(t+(0.5**i))[1];

    Now we can get the correct eases via this expression:

    thisComp.layer("Bezier timing").effect("ease")("Slider").valueAtTime(value);

    where (value) is between 0 an 100.

    You could now set linear keyframes 0 to 100 on the trim Paths, and add that final expression to the trimpaths, and the actual trim and ball animation will follow the timing you want.

  • Melissa Franch

    April 25, 2024 at 11:52 am

    Woow!

    You are the best. It works perfectly!

  • Brie Clayton

    April 25, 2024 at 2:53 pm

    Thanks for this solve, Filip!

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