Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Passing a function as an argument to another function issue

  • Passing a function as an argument to another function issue

    Posted by Anton Kosarchyn on September 3, 2015 at 1:58 pm

    Hi, guys! I’ve an issue with passing a function as an argument to my own custom function. Appears error message with text: ‘Error at line 6. Function property .speedAtTime() cannot work with this class’ though the code below works just perfect outside of the function body. Please, help! Thanks!

    function eventTime (property){
    var frame = timeToFrames(time);
    var controller = true;
    while (controller){
    var t = framesToTime(frame);
    var s = Math.floor(property(t));
    var prevs = Math.floor(property(framesToTime(frame-1)));
    if(frame==0){
    break;
    };
    if(prevs!=s){
    if(s==0){
    controller=false;
    };
    };
    --frame;
    };
    if(!controller){
    t;
    }else{
    t=null;
    };
    return t;
    };
    eventTime(thisComp.layer("card 2").position.speedAtTime);

    Anton Kosarchyn replied 10 years, 12 months ago 2 Members · 2 Replies
  • 2 Replies
  • Xavier Gomez

    September 3, 2015 at 9:28 pm

    I don’t think you can pss this kind of methods as argument to a function.
    But passing the actual property (in your example : thisComp.layer(“card 2”).position), not a method, and then using

    var s = Math.floor(property.speedAtTime(t));
    var prevs = Math.floor(property.speedAtTime(framesToTime(frame-1)));

    in the function body, will probably work (didnt check).

    If you want to keep the possibility to use the same function for values (not speed), you could do:
    (i didnt try to undertand the code so i dont know if it’s relevant):

    function eventTime (property, isSpeed){
    var frame = timeToFrames(time);
    var controller = true;
    var meth = isSpeed ? "speedAtTime" : "valueAtTime";
    while (controller){
    var t = framesToTime(frame);
    var s = Math.floor(property[meth](t));
    var prevs = Math.floor(property[meth](framesToTime(frame-1)));
    if(frame==0){
    break;
    };
    if(prevs!=s){
    if(s==0){
    controller=false;
    };
    };
    --frame;
    };
    if(!controller){
    t;
    }else{
    t=null;
    };
    return t;
    };
    eventTime(thisComp.layer("card 2").position, true);

    Xavier.

  • Anton Kosarchyn

    September 7, 2015 at 11:18 am

    Thanks for the reply! Your solution works great but I expanded it a bit with switch conditions, so now you can pass up to 3 properties (speed, velocity, value). So the extended code are below if anyone needs it:)
    Thanks again!)

    /*
    Function can obtain time when some action happens (eg time when object speed was 0 etc.) It's based on algorithm of Dan Ebberts expression. You can pass 4 arguments:

    1. property - eg layer.transform.position etc;

    2. method - string value. eg 'speed', 'velocity', 'value'. Buy default function will obtain 'value';

    3. axis of property - you can pass 0(x-axis) or 1(y-axis) for methods 'velocity' and 'value'. For the 'speed' method it doesn't matter, but you still should pass something(0 or 1)or function will return error;

    4. triggerValue - numeric value, which triggers the function.

    For example, you want someLayer to fade out in half of a second when layer's position will be 600px at y-axis:
    eventT = eventTime (thisComp.layer("someLayer").position, 'value', 1, 600);
    thisComp.layer("someLayer").opacity = easeOut(time,eventT,eventT+0.5,100,0);
    */

    function eventTime (property, method, axis, triggerValue){
    switch(method){
    case "speed":
    method = "speedAtTime";
    var isSpeed = true;
    break;
    case "velocity":
    method = "velocityAtTime";
    var isSpeed = false;
    break;
    default:
    method = "valueAtTime";
    var isSpeed = false;
    break;
    };
    var frame = timeToFrames(time);
    var controller = true;
    while (controller){
    var t = framesToTime(frame);
    var s = !isSpeed ? Math.floor(property[method](t)[axis]) : Math.floor(property[method](t));
    var prevs = !isSpeed ? Math.floor(property[method](framesToTime(frame-1))[axis]) : Math.floor(property[method](framesToTime(frame-1)));
    if(frame==0){
    break;
    };
    if(prevs!=s){
    if(s==triggerValue){
    controller=false;
    };
    };
    --frame;
    };
    if(!controller){
    t;
    }else{
    t=0;
    };
    return t;
    };

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