Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Script needs some code cleaning to work as expected

  • Script needs some code cleaning to work as expected

    Posted by David Cabestany on July 21, 2023 at 12:24 am

    I used an AI to write a script that I use all the time. It works 95% as expected. I humbly ask if anyone here could help me fix what’s wrong with it.

    The script copies the values of the last keyframe(s) on any given property or properties on a single layer or multiple layers at once, then deletes the keyframes and pastes the copied values on the immediately prior keyframes, regardless of when in the timeline they are.

    This is extremely useful when you have staggered or random animations that need to be adjusted at a later point in time, for example when all the layers have completed their animation and you can see their final state, then you do whatever tweakings you need on all of the layers at once, a new keyframe is generated for each layer/property and instead of having to manually drag each keyframe to their correct position (the last, previous keyframe for each property), they all get moved there with the click of a button.

    The script I got from the AI works almost as desired except for two things:

    1) it opens two separate panels, an empty one that can be docked but has no buttons or anything in it and an another one that cannot be docked but has the clickable button to make the script work. This is not a huge issue, and I always close the empty panel and the other, single button panel works fine the rest of the time I’m working on my project.

    2) With some properties, it returns an error warning “That there must be at least two keyframes on the selected property” and then it gets stuck there. If I click ok, the warning appears again and it keeps appearing, and I have to force quit the program in order to open my project again. There are two problems here:

    1, The property I am selecting has two or more keyframes, so the error message is invalid and I tested it on another comp in the same project and it worked fine.

    2, I should be able to just click ok on the warning and be able to continue working, instead of having to force quit the program.

    If anyone would be so kind to look into it and fix these two issues I would be extremely grateful, as I use this every single day.

    Thanks in advance.

    (function () {

    var copyLastKeyframe = function (prop) {

    var numKeys = prop.numKeys;

    if (numKeys < 2) {

    alert("There must be at least two keyframes on the selected property.");

    return;

    }

    var lastKeyframeValue = prop.keyValue(numKeys);

    prop.setValueAtTime(prop.keyTime(numKeys - 1), lastKeyframeValue);

    prop.removeKey(numKeys);

    };

    var main = function () {

    var comp = app.project.activeItem;

    if (!(comp && comp instanceof CompItem)) {

    alert("Please select a composition.");

    return;

    }

    var selectedProps = comp.selectedProperties;

    if (selectedProps.length === 0) {

    alert("Please select at least one property to modify.");

    return;

    }

    app.beginUndoGroup("Jump KF");

    for (var i = 0, il = selectedProps.length; i < il; i++) {

    var prop = selectedProps[i];

    if (prop.propertyType === PropertyType.PROPERTY) {

    copyLastKeyframe(prop);

    } else if (prop.propertyType === PropertyType.INDEXED_GROUP || prop.propertyType === PropertyType.NAMED_GROUP) {

    for (var j = 1, jl = prop.numProperties; j <= jl; j++) {

    var subProp = prop.property(j);

    if (subProp.propertyType === PropertyType.PROPERTY) {

    copyLastKeyframe(subProp);

    }

    }

    }

    }

    app.endUndoGroup();

    };

    var dockableWindow = new Window("palette", "Jump KF", undefined, {

    resizeable: true,

    });

    var button = dockableWindow.add("button", undefined, "Jump KF");

    button.onClick = main;

    dockableWindow.layout.layout(true);

    dockableWindow.layout.resize();

    dockableWindow.onResizing = dockableWindow.onResize = function () {

    this.layout.resize();

    };

    if (dockableWindow instanceof Panel) {

    dockableWindow.show();

    } else {

    dockableWindow.center();

    dockableWindow.show();

    }

    })();

    Andrei Popa replied 1 year, 11 months ago 2 Members · 1 Reply
  • 1 Reply
  • Andrei Popa

    July 27, 2023 at 1:36 pm

    Hi David.

    Here is a version that makes the script work correctly as panel.

    If you could give me a project in which the error is present, I could try to debug that.

    (function (thisObj) {
    var copyLastKeyframe = function (prop) {
    var numKeys = prop.numKeys;
    if (numKeys < 2) {
    alert("There must be at least two keyframes on the selected property.");
    return;
    }
    var lastKeyframeValue = prop.keyValue(numKeys);
    prop.setValueAtTime(prop.keyTime(numKeys - 1), lastKeyframeValue);
    prop.removeKey(numKeys);
    };
    var main = function () {
    var comp = app.project.activeItem;
    if (!(comp && comp instanceof CompItem)) {
    alert("Please select a composition.");
    return;
    }
    var selectedProps = comp.selectedProperties;
    if (selectedProps.length === 0) {
    alert("Please select at least one property to modify.");
    return;
    }
    app.beginUndoGroup("Jump KF");
    for (var i = 0, il = selectedProps.length; i < il; i++) {
    var prop = selectedProps[i];
    if (prop.propertyType === PropertyType.PROPERTY) {
    copyLastKeyframe(prop);
    } else if (prop.propertyType === PropertyType.INDEXED_GROUP || prop.propertyType === PropertyType.NAMED_GROUP) {
    for (var j = 1, jl = prop.numProperties; j <= jl; j++) {
    var subProp = prop.property(j);
    if (subProp.propertyType === PropertyType.PROPERTY) {
    copyLastKeyframe(subProp);
    }
    }
    }
    }
    app.endUndoGroup();
    };
    var dockableWindow = thisObj instanceof Panel ? thisObj : new Window("palette", "Jump KF", undefined, {
    resizeable: true,
    });
    var button = dockableWindow.add("button", undefined, "Jump KF");
    button.onClick = main;
    dockableWindow.layout.layout(true);
    dockableWindow.layout.resize();
    dockableWindow.onResizing = dockableWindow.onResize = function () {
    this.layout.resize();
    };
    if (dockableWindow instanceof Panel) {
    dockableWindow.layout.layout(true);
    dockableWindow.layout.resize();
    } else {
    dockableWindow.center();
    dockableWindow.show();
    }
    })(this);

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