Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
1

how to space out key-frames evenly?

Community Beginner ,
Dec 05, 2018 Dec 05, 2018

My question is fairly simple but haven't found a good solution yet.

The image below shows all key-frames have been placed on a layer

I am wondering is there any ways that can quickly space out those dots evenly. like this image below:

I use photoshop / illustrator as well. they have a series of buttons like this:

Does After Effect has something similar tools like that as well? if not, how can i quickly achieve the evenly space out dots.

Thanks, Appreciated

60.2K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

New Here , Jan 22, 2023 Jan 22, 2023

Hi there, Use this Script.

function adjustKeyframeSpace() {
    var selectedLayers = app.project.activeItem.selectedLayers;
    if (selectedLayers.length == 0) {
        alert("Please select a layer with keyframes to run this script");
        return;
    }
    var selectedProperties = selectedLayers[0].selectedProperties;
    if (selectedProperties.length == 0) {
        alert("Please select a property with keyframes to run this script");
        return;
    }
    var selectedKeyframes = selecte
...
Translate
Explorer ,
Nov 05, 2020 Nov 05, 2020

Thankyou

 

This is a good workaround, I wish AE had an option to evenly space out keyframes in a given area. I downloaded rift plugin and I can't even work that plugin out!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 10, 2021 Oct 10, 2021

Nice one, thank you!  Staight answers.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 30, 2021 Nov 30, 2021

Thank you, your video was very helpful!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 04, 2022 Nov 04, 2022

yes its a workaround, but its just not an efficient method at all, its so simple, all the OP want to do was distribute keyframes evenly from the start to the end of his selection.. like you say, if your trying to manage many keyframes.. its a problem..

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 17, 2022 Jan 17, 2022

I've checked all the replies below and none answers his question.

 

does anyone know how to do it?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 25, 2022 Oct 25, 2022

select your keyframes, right-click and select "Keyframe Interpolation", then choose "Linear" for both Temporal Interpolation & Spatial Interpolation.

 

Screenshot_1.jpg

 

i hope this helps 🙂

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 25, 2022 Oct 25, 2022

this does not space out keyframes.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 05, 2024 Sep 05, 2024

Hello, it's far the best advice of the topic, but i have an issues. The spatial interpolation and roving appears grey and not editable, do you know why ?

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 02, 2023 Feb 02, 2023
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jan 24, 2022 Jan 24, 2022

Meanwhile I wrote an expression that has the same effect. Though not distributing the actual keyframe dots, it does distribute the values evenly when rendering. Thanks for inspiring me to do so 🙂

Still longing for a script that distributes the actual keyframes.

 

// Distribute keyframe values evenly (not the actual keyframes)
//
// Create markers at the Start and End times
// Create any number of keyframes, don't care about the exact timing
// Paste this expression in the property's expression field

// Expression by jaydude.nl / 2022

var mS = marker.key(1).time;
var mE = marker.key(2).time;
var kValue = [];
var n = numKeys;
var i;


for (i = 1; i < n + 1; i++) { 
  kValue[i] = valueAtTime(key(i).time);
};

k = Math.round(linear(time , mS , mE , 1 , n));

kValue[k];

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 24, 2022 Feb 24, 2022

I wanted a load of evenly spaced hold key frames with ascending position values. My work around is this:

 

1. create two key frames the required distance apart.

2. Create a null object. This will just be like a construction guide layer.

3. Select your two key frames and ctrl C to copy them. 
4. Use the K key to move the play head exactly on the second keyframe and with the Null object selected Ctrl V to paste. Keep pressing K to shift the play head along and pasting until you have a guide layer of evenly distributed keyframes. 
5. now on the layer you actually want keyframes you can use J and K to snap to your guides. And add your keyframes accordingly.

6. For the keyframe values I had to consider the maths but I put the equation in the value box. For example I wanted each hold keyframe to increase the X position by 200 pixels so I would add the keyframe and if the existing X value was 100 I would add "+200" in the little box, hit enter and it would be 300. The next KF I added would then also be 300 and I would "+200" to that. Etc.

 

7. You can delete the null layer if you don't need it anymore.

 

Its not automatic but it's precise and fairly painless.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 16, 2022 Nov 16, 2022

Wow, I can't believe this is so complicated.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 22, 2023 Jan 22, 2023

Hi there, Use this Script.

function adjustKeyframeSpace() {
    var selectedLayers = app.project.activeItem.selectedLayers;
    if (selectedLayers.length == 0) {
        alert("Please select a layer with keyframes to run this script");
        return;
    }
    var selectedProperties = selectedLayers[0].selectedProperties;
    if (selectedProperties.length == 0) {
        alert("Please select a property with keyframes to run this script");
        return;
    }
    var selectedKeyframes = selectedProperties[0].selectedKeys;
    if (selectedKeyframes.length == 0) {
        alert("Please select some keyframes to run this script");
        return;
    }

    var keyframeDuration = selectedProperties[0].keyTime(selectedKeyframes[selectedKeyframes.length - 1]) - selectedProperties[0].keyTime(selectedKeyframes[0]);
    var keyframeInterval = keyframeDuration / (selectedKeyframes.length - 1);

    for (var i = 0; i < selectedKeyframes.length; i++) {
        var newKeyframeTime = selectedProperties[0].keyTime(selectedKeyframes[0]) + (keyframeInterval * i);
        var easeIn = selectedProperties[0].keyInTemporalEase(selectedKeyframes[i])[0];
        var easeOut = selectedProperties[0].keyOutTemporalEase(selectedKeyframes[i])[0];
        var value = selectedProperties[0].valueAtTime(selectedProperties[0].keyTime(selectedKeyframes[i]), true);
        selectedProperties[0].removeKey(selectedKeyframes[i]);
        selectedProperties[0].setValueAtTime(newKeyframeTime,value);
        selectedProperties[0].setTemporalEaseAtKey(1, [easeIn], [easeOut]);
    }
}
adjustKeyframeSpace();
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 22, 2023 Jan 22, 2023

Hi there, Use this Script.

function adjustKeyframeSpace() {
    var selectedLayers = app.project.activeItem.selectedLayers;
    if (selectedLayers.length == 0) {
        alert("Please select a layer with keyframes to run this script");
        return;
    }
    var selectedProperties = selectedLayers[0].selectedProperties;
    if (selectedProperties.length == 0) {
        alert("Please select a property with keyframes to run this script");
        return;
    }
    var selectedKeyframes = selectedProperties[0].selectedKeys;
    if (selectedKeyframes.length == 0) {
        alert("Please select some keyframes to run this script");
        return;
    }

    var keyframeDuration = selectedProperties[0].keyTime(selectedKeyframes[selectedKeyframes.length - 1]) - selectedProperties[0].keyTime(selectedKeyframes[0]);
    var keyframeInterval = keyframeDuration / (selectedKeyframes.length - 1);

    for (var i = 0; i < selectedKeyframes.length; i++) {
        var newKeyframeTime = selectedProperties[0].keyTime(selectedKeyframes[0]) + (keyframeInterval * i);
        var easeIn = selectedProperties[0].keyInTemporalEase(selectedKeyframes[i])[0];
        var easeOut = selectedProperties[0].keyOutTemporalEase(selectedKeyframes[i])[0];
        var value = selectedProperties[0].valueAtTime(selectedProperties[0].keyTime(selectedKeyframes[i]), true);
        selectedProperties[0].removeKey(selectedKeyframes[i]);
        selectedProperties[0].setValueAtTime(newKeyframeTime,value);
        selectedProperties[0].setTemporalEaseAtKey(1, [easeIn], [easeOut]);
    }
}
adjustKeyframeSpace();
 
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 30, 2023 Mar 30, 2023

@Aryan244766988iej  Thank you for writing this script!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 13, 2023 Apr 13, 2023

Just what I need! In AE, I'm getting an error at line 13 "Undefined is not an object" when run.Not a strong coder, so I don't know how to fix it. Anyone else had that issue?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 09, 2023 Aug 09, 2023

Same here.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 09, 2023 Aug 09, 2023

Thanks for sharing anyway - maybe this wil evolve to a solution. 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 09, 2025 Mar 09, 2025

Thank you so much! God bless you!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 27, 2024 Nov 27, 2024

I love the comparison to illustrator and would find this an extremly helpful keyboard shortcut or tool in the properties panel!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Apr 30, 2025 Apr 30, 2025

I created this script (with the help of Perplexity...):

{
    function spaceOutSelectedKeyframesEvenly() {
        var comp = app.project.activeItem;
        if (!(comp && comp instanceof CompItem)) {
            alert("Please select a composition.");
            return;
        }

        var selectedLayers = comp.selectedLayers;
        if (selectedLayers.length === 0) {
            alert("Please select at least one layer.");
            return;
        }

        // Find first property with selected keyframes
        var targetProp = null;
        for (var i = 0; i < selectedLayers.length; i++) {
            var layer = selectedLayers[i];
            var selectedProps = layer.selectedProperties;
            for (var j = 0; j < selectedProps.length; j++) {
                var prop = selectedProps[j];
                if (prop.numKeys > 0 && prop.selectedKeys.length > 0) {
                    targetProp = prop;
                    break;
                }
            }
            if (targetProp) break;
        }

        if (!targetProp) {
            alert("Please select a property with selected keyframes.");
            return;
        }

        var intervalFramesStr = prompt("Enter interval between keyframes in frames:", "5");
        if (intervalFramesStr === null) return;

        var intervalFrames = parseInt(intervalFramesStr, 10);
        if (isNaN(intervalFrames) || intervalFrames <= 0) {
            alert("Invalid interval entered. Please enter a positive integer.");
            return;
        }

        app.beginUndoGroup("Space Out Selected Keyframes Evenly");

        var frameDuration = 1 / comp.frameRate;

        // Get selected keyframe indices sorted ascending
        var selectedKeyIndices = targetProp.selectedKeys.slice(0).sort(function(a, b) { return a - b; });

        // Save original keyframe data (time, value, easing, interpolation)
        var keyData = [];
        for (var i = 0; i < selectedKeyIndices.length; i++) {
            var idx = selectedKeyIndices[i];
            keyData.push({
                originalTime: targetProp.keyTime(idx),
                value: targetProp.keyValue(idx),
                inInterp: targetProp.keyInInterpolationType(idx),
                outInterp: targetProp.keyOutInterpolationType(idx),
                temporalEaseIn: targetProp.keyInTemporalEase(idx),
                temporalEaseOut: targetProp.keyOutTemporalEase(idx),
                spatialInterp: (typeof targetProp.keySpatialInterpolationType === "function") ? targetProp.keySpatialInterpolationType(idx) : null,
                roving: (typeof targetProp.keyRoving === "function") ? targetProp.keyRoving(idx) : false
            });
        }

        // Calculate new times spaced evenly starting at the first selected keyframe's original time
        var startTime = keyData[0].originalTime;
        var newTimes = [];
        for (var i = 0; i < keyData.length; i++) {
            newTimes.push(startTime + i * intervalFrames * frameDuration);
        }

        // Remove selected keyframes from highest index to lowest to avoid reindexing issues
        for (var i = selectedKeyIndices.length - 1; i >= 0; i--) {
            targetProp.removeKey(selectedKeyIndices[i]);
        }

        // Add new keyframes at new evenly spaced times with original values and restore easing/interpolation
        for (var i = 0; i < keyData.length; i++) {
            targetProp.setValueAtTime(newTimes[i], keyData[i].value);
            var newKeyIndex = targetProp.nearestKeyIndex(newTimes[i]);
            if (newKeyIndex > 0) {
                targetProp.setTemporalEaseAtKey(newKeyIndex, keyData[i].temporalEaseIn, keyData[i].temporalEaseOut);
                targetProp.setInterpolationTypeAtKey(newKeyIndex, keyData[i].inInterp, keyData[i].outInterp);
                if (keyData[i].spatialInterp !== null) {
                    targetProp.setSpatialInterpolationTypeAtKey(newKeyIndex, keyData[i].spatialInterp);
                }
                if (keyData[i].roving !== undefined) {
                    targetProp.setRovingAtKey(newKeyIndex, keyData[i].roving);
                }
            }
        }

        app.endUndoGroup();
    }

    spaceOutSelectedKeyframesEvenly();
}
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines