Forum Replies Created

Page 14 of 32
  • Xavier Gomez

    September 27, 2015 at 5:38 pm in reply to: Loop through motion tracker points

    Yes you can define several variables in a row like above.

    var x=0, y=0, z=3; // OK

    …also works. It declares 3 variables and assigns them a value each;
    But use with caution. For instance:

    var x=y=0, z=3; // WRONG

    isnt too good because it only declares x (and z) but not y.
    If y has been declared, it will overwrite it, and if not it will create a variable y in the global workspace.

  • Xavier Gomez

    September 27, 2015 at 1:07 pm in reply to: Loop through motion tracker points

    To access the feature center (say) of a tracker point :

    myLayer.motionTracker(identifier1)(identifier2).featureCenter

    where the identifiers are the name (string) or propertyIndex (number).
    To loop through all trackers of a layer:

    var i, I, tracker;
    var j, J, trackerPoint;
    for (I=myLayer.motionTracker.numProperties, i=1; i<=I; i++){
    tracker = myLayer.motionTracker(i); // If not renamed, this is the thing called "Tracker i"
    for (J=tracker.numProperties, j=1; j<=J; j++){
    trackerPoint = tracker(j); // If not renamed, this is the thing called "Tracker Point j"
    /* do something with that tracker point*/
    };
    };

    Xavier

  • Xavier Gomez

    September 22, 2015 at 3:29 pm in reply to: Stop code running, until precomp isn’t ready

    It’s not very clear what you are trying to do and where the problem comes from.

    I think that, in a script, an instruction is not executed before the previous one is not actually finished, including what it may represent inside After Effects (“precomping”, rendering, whatever). What error do you have ? Any chance that you refer to objects (layers) that dont exist anymore because of the precomp operation?

    Xavier.

  • Xavier Gomez

    September 18, 2015 at 6:05 pm in reply to: Link only x position to Rotation

    Good that you ask, i realize that it was sort of wrong. It should be more like this:

    a = 100/360;
    pos = value;
    r = thisComp.layer(“GEAR”).transform.rotation;
    pos[0] += a *(r.value-r.valueAtTime(inPoint));
    pos;

    it adds something that is proportionnal to the rotation variation to the x component (component 0) of the position. For a = 100/360 it will add 100 pixel for one complete turn, etc.

    The first 3 lines simply define some variable to be used.
    pos stores the current value (before expression).
    The the variation is added to the component 0.
    To calculate a variation, one needs a reference value, i assumed that the reference should determined at the layer’s inPoint, but you might need something else.
    Then the last line, just ‘pos’, tells what is the final result to be retained.

  • Xavier Gomez

    September 18, 2015 at 2:11 pm in reply to: Link only x position to Rotation

    I think that this should work:

    pos = value;
    r = thisComp.layer(“GEAR”).transform.rotation;
    pos[0] += (time-inPoint)*(r.value-r.valueAtTime(inPoint));
    pos;

    Xavier.

  • Xavier Gomez

    September 11, 2015 at 6:23 am in reply to: check if property is active

    In this case, p.canSetExpression should work.
    (If true the property is visible and can be modified, else it is not activated).

    Xavier.

  • Xavier Gomez

    September 7, 2015 at 2:52 pm in reply to: After Effects Script problem with text layers

    The value of text property must be a TextDocument (see Guide).
    You have to create one ( var t = new TextDocument() ), assign its attributes, then set it as the value.

    Xavier

    Edit : Sorry, i misread your post. Ignore !

  • Xavier Gomez

    September 5, 2015 at 5:29 pm in reply to: Mutual recursion: this.function is undefined. error.

    It’s possible to give a uniform treatment to layers and items since they belong to a collection, but there is no seach thing as a PropertyCollection, so that properties/propertyGroups would have to be handled differently.

    For instance i do use something like your spider object, and it is organized like this:

    var $coll = {

    forEach : function forEach(coll, callback){
    var n, N=coll.length;
    for (n=1; n<=N; n++){
    callback(coll[n], n, coll);
    };
    return;
    },

    find : function find(coll, filter){
    var n, N=coll.length;

    if (filter(coll[n], n, coll)) return coll[n];
    },
    return null;
    },

    indexOf : function indexOf(coll, x){
    var n, N=coll.length;
    for (n=1; n<=N; n++){
    if (coll[n]==x) return n;
    },
    return 0;
    },

    // etc,, etc
    };

    So $coll.forEach would be the equivalent of your spider.crawl
    I find it usefull too, so you can write things like :

    var footageFolder = $coll.find(app.project.items, function(element, index, collection){return element.name === “Footage” && element.typeName === “Folder”;}) || app.project.items.addFolder(“Footage”);

    (this searches a folder called “Footage” and creates it if not found).

    But as soon as recursions are involved i found it a lot clearer to write full code, since there are many ways to recurse through a folder architecture.

    Here is a very basic starting block to import and then create.
    It only import basic footage (image, video) and creates comps at a fixed size/duration (not based on content!).
    It would require quite a lot of work to turn it ito what you actually want, but it can help to start with:

    function recursiveImport(sysFolder, aeFolder){
    // create a AE folder and parent it to aeFolder:
    var folder = app.project.items.addFolder(sysFolder.name);
    folder.parentFolder = aeFolder || app.project.rootFolder;

    var files = sysFolder.getFiles();
    var n, N=files.length;

    for (n=0; n<=N; n++){ if (files[n] instanceof Folder){ recursiveImport(files[n], folder); } else{ try{app.project.importFile(new ImportOptions(files[n])).parentFolder = folder;}catch(e){}; }; }; return folder; }; function recursiveCreate(aeFootageFolder, aeCompFolder, compSpec){ var N=aeFootageFolder.items.length, n, item; var comp = aeCompFolder.items.addComp(aeFootageFolder.name, compSpec.width, compSpec.height, compSpec.pixelAspect, compSpec.duration, compSpec.frameRate); for (n=N; n>0; n--){
    item = aeFootageFolder.items[n];
    if (item instanceof FolderItem){
    comp.layers.add(recursiveCreate(item, aeCompFolder.items.addFolder(item.name), compSpec));
    }
    else{
    comp.layers.add(item);
    };
    };
    return comp;
    };

    (function(){

    var sysFolder = Folder.selectDialog();
    if (!sysFolder) return;

    var allFootageFolder = $coll.find(app.project.items, function(element, index, collection){return element.name === "Footage" && element.typeName === "Folder";}) || app.project.items.addFolder("Footage");
    var thisFootageFolder = recursiveImport(sysFolder, allFootageFolder);

    var allCompFolder = $coll.find(app.project.items, function(element, index, collection){return element.name === "Comps" && element.typeName === "Folder";}) || app.project.items.addFolder("Comps");
    var thisCompFolder = allCompFolder.items.addFolder(thisFootageFolder.name);
    var compSpec = {
    width : 1280,
    height : 720,
    pixelAspect : 1.0,
    duration : 10,
    frameRate : 25
    };

    recursiveCreate(thisFootageFolder, thisCompFolder, compSpec);

    return;

    })();

    Xavier.

    Edit: tried to correct the <= bugs, if failed again i give up.

  • Xavier Gomez

    September 4, 2015 at 10:22 am in reply to: Mutual recursion: this.function is undefined. error.

    What would you like it to do exactly ?

  • 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.

Page 14 of 32

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