Skip to main content
oliverdead
Participating Frequently
July 20, 2014
Answered

Select Next Keyframe (in selected property) script

  • July 20, 2014
  • 1 reply
  • 3891 views

I find myself constantly crafting individual keyframes manually, so being able to automatically select the next/previous keyframe on a selected property with a shortcut (assigned to a script, since there's no such functionality in After Effects, being "Select Previous/Next Keyframes" the closest thing) instead of locating the keyframe and clicking on it, would save me, and everyone, hours of pointing and clicking.

After some research I thought It was not possible but after some more (looking at scripts like this AE ENHANCERS • View topic - Exponential Scaling and Re: How can I access the layer keyframes?) , I've started to wonder if it is scriptable.

Hope it is clear what I'm trying to achieve;

Basically I'd like that pressing Shift+K would take me to the next keyframe in the selected property AND select it (Shift+J for the previous one) and

pressing Ctrl+Shift+K would select the next keyframe in the selected property without actually moving the Current Time Indicator (Ctrl+Shift+J for the previous one).

(I think it makes sense and it is consistent with the almighty J and K shortcuts but I didn't know how to write the code or ask for this functionality. Haven't been lucky asking to fellow animators either).

Thanks,

Oliver

This topic has been closed for replies.
Correct answer UQg

Hi again,

i don't know how to reference a new short cut. As i said it might be somehow possible with an AppleScript but i don't know how that works, and it won't work on Windows anyway.

Here is another "solution", it works and is actually quite useful:

  1. Open After Effects.
  2. Open the script editor (File>Scripts>Open Script File)
  3. Copy paste the code below
  4. Save it in your Scripts folder (not the ScriptUI Panels folder, there is no UI) under a name for which you are sure it will be the first in your scripts collections (for the test, i used $01_SelectCurrentKeys.jsx)
  5. Close After Effects.
  6. Then Open your After Effects Shortcuts.txt (see this thread for details on where to find it, how to edit it: Re: Custom hotkeys)
  7. Choose a shortCut for "ExecuteScriptMenuItem01" (that's the hard part all combinations are taken already)
  8. Save and relaunch AE:

What the shorcut will do: select the keyframe right under the CTI for all selected properties. Any other key is deselected.

It's not exactly what you asked but... i think it's better: Use J/K to navigate and that new shortcut to actually select.

If you want to stick to your original idea, it gives you a base to start with.

Note: a script cannot know if a property is revealed or not in the timeline panel, so you have to actually select properties for it to work.

Xavier.

$.global.script_doSelectCurrentKeys || (script_doSelectCurrentKeys = function script_doSelectCurrentKeys(){

    var comp = app.project.activeItem, props, n, p, idx, DT;

    if (comp instanceof CompItem){

        DT = Math.min(0.01, comp.frameDuration/10.0);

        props = comp.selectedProperties;

        for (n=0; n<props.length; n++){

            p = props;

            if (!p.numKeys) continue;

            idx = p.nearestKeyIndex(comp.time);

            if (Math.abs(p.keyTime(idx)-comp.time)<DT){

                if (p.selectedKeys.length>0) p.selected = false;

                p.setSelectedAtKey(idx, true);

                }

            else if (p.selectedKeys.length>5){

                p.selected = false;

                p.setSelectedAtKey(1, true);

                p.setSelectedAtKey(1, false);

                }

            else{

                while (p.selectedKeys.length) p.setSelectedAtKey(p.selectedKeys[0], false);

                };

            };

        };

    return;

    });

script_doSelectCurrentKeys();

1 reply

UQg
Legend
July 20, 2014

Hi Oliver,

i think you should define precisely what you expect to happen in special situations like:

  • the layer has several keyframes selected
  • the last key is selected and you ask to select the next one (select no key? select only the last? do nothing ???)
  • same with first key already selected and you ask to select the previous.
  • Finally what to do in case several layers are selected and the key times dont match ? In particular if you ask the CTI to jump to next key time, where should it go ?

It's probably because of all these amibiguities that those shortcut do not exist.

If your "key" column is activated in the timeline panel, you can jump to prev/next key easily with the two buttons, and the action is always well-defined and unambiguous.

If you have a precise idea of what should happen in various situations, the code to achieve it through a UI button  is actually not difficult. Through a shortcut it is another story (probably possible with a Mac, with Windows i dont think so).

Xavier.

oliverdead
Participating Frequently
July 20, 2014

Hey Xavier!

Well as you can imagine, it would mainly be select next/previous keyframe of the active property (a keyframe should be selected), or else, do nothing. For example:

  • If there are several keyframes selected, determine which of the selected keyframes has a higher time value and then select the next one (higher time value, closest in time, not selected) in the property. (And viceversa for the 'Previous' shortcut).
  • If there are no unselected keyframes to jump to, do nothing.
  • If multiple properties/layers are selected, either do nothing or, ideally, determine the keyframe with higher time value and select the next one (closest in time, not selected) in any of the selected layers/property. (I can see how this one gets complicated, jumping between layers/properties).
  • If no keyframe is selected, of course, do nothing.

My priority would be the select the next keyframe, rather the select AND jump to because, like you say, J and K do that somehow (without the selecting part but hey, better than nothing).

And I guess if this works as a script (or button), you could assign it a shortcut, like you can do with your first scripts if I'm correct?

And thankss a lot! (as you can see, I have no idea of how to script this:$ ).

Oliver

UQg
UQgCorrect answer
Legend
July 21, 2014

Hi again,

i don't know how to reference a new short cut. As i said it might be somehow possible with an AppleScript but i don't know how that works, and it won't work on Windows anyway.

Here is another "solution", it works and is actually quite useful:

  1. Open After Effects.
  2. Open the script editor (File>Scripts>Open Script File)
  3. Copy paste the code below
  4. Save it in your Scripts folder (not the ScriptUI Panels folder, there is no UI) under a name for which you are sure it will be the first in your scripts collections (for the test, i used $01_SelectCurrentKeys.jsx)
  5. Close After Effects.
  6. Then Open your After Effects Shortcuts.txt (see this thread for details on where to find it, how to edit it: Re: Custom hotkeys)
  7. Choose a shortCut for "ExecuteScriptMenuItem01" (that's the hard part all combinations are taken already)
  8. Save and relaunch AE:

What the shorcut will do: select the keyframe right under the CTI for all selected properties. Any other key is deselected.

It's not exactly what you asked but... i think it's better: Use J/K to navigate and that new shortcut to actually select.

If you want to stick to your original idea, it gives you a base to start with.

Note: a script cannot know if a property is revealed or not in the timeline panel, so you have to actually select properties for it to work.

Xavier.

$.global.script_doSelectCurrentKeys || (script_doSelectCurrentKeys = function script_doSelectCurrentKeys(){

    var comp = app.project.activeItem, props, n, p, idx, DT;

    if (comp instanceof CompItem){

        DT = Math.min(0.01, comp.frameDuration/10.0);

        props = comp.selectedProperties;

        for (n=0; n<props.length; n++){

            p = props;

            if (!p.numKeys) continue;

            idx = p.nearestKeyIndex(comp.time);

            if (Math.abs(p.keyTime(idx)-comp.time)<DT){

                if (p.selectedKeys.length>0) p.selected = false;

                p.setSelectedAtKey(idx, true);

                }

            else if (p.selectedKeys.length>5){

                p.selected = false;

                p.setSelectedAtKey(1, true);

                p.setSelectedAtKey(1, false);

                }

            else{

                while (p.selectedKeys.length) p.setSelectedAtKey(p.selectedKeys[0], false);

                };

            };

        };

    return;

    });

script_doSelectCurrentKeys();