PlayChart Script

 avatar
unknown
plain_text
5 months ago
5.2 kB
23
Indexable
// This script redistributes keyframe pairs on the Slider property of the "Morpher" effect
// maintaining the internal spacing between the keyframes of the pair and equally distributing the pairs in the work area

// Function to find the first Null Object layer with the Morpher effect
function getMorpherLayer(comp) {
    for (var i = 1; i <= comp.numLayers; i++) {
        var layer = comp.layer(i);
        if (layer.nullLayer && layer.property("Effects").property("Morpher")) {
            return layer;
        }
    }
    return null;
}

app.beginUndoGroup("Redistribute Keyframe Pairs Slider Morpher");

// Loop through selected compositions
var selectedComps = app.project.selection;  // Get the selected compositions
for (var i = 0; i < selectedComps.length; i++) {
    if (selectedComps[i] instanceof CompItem) {
        var myLayer = getMorpherLayer(selectedComps[i]);  // Get the first Null Object with Morpher effect
        if (myLayer) {
            var myEffect = myLayer.property("Effects").property("Morpher").property("Slider");  // Gets the Slider property of the Morpher effect
            var myKeyframes = [];  // Array to store keyframe information (time, value, easing)
            var pairDurations = [];  // Array to store the durations of the pairs

            // Collect all keyframes (assuming there are always 16 keyframes, 8 pairs)
            for (var j = 1; j <= myEffect.numKeys; j++) {
                // Save the keyframe time, value and easing
                var keyTime = myEffect.keyTime(j);
                var keyValue = myEffect.keyValue(j);
                var easeIn = myEffect.keyInTemporalEase(j);
                var easeOut = myEffect.keyOutTemporalEase(j);
                var keyInterpolation = {
                    inType: myEffect.keyInInterpolationType(j),
                    outType: myEffect.keyOutInterpolationType(j)
                };
                myKeyframes.push({
                    time: keyTime,
                    value: keyValue,
                    easeIn: easeIn,
                    easeOut: easeOut,
                    interpolation: keyInterpolation
                });
            }

            // Check that there are exactly 16 keyframes
            if (myKeyframes.length === 16) {

                // Calculate durations between keyframe pairs
                for (var k = 0; k < myKeyframes.length - 1; k += 2) {
                    pairDurations.push(myKeyframes[k + 1].time - myKeyframes[k].time);  // Durata di ogni coppia
                }

                // Calculate the total duration of the work area
                var workAreaStart = selectedComps[i].workAreaStart;
                var workAreaEnd = selectedComps[i].workAreaStart + selectedComps[i].workAreaDuration;
                var totalWorkAreaDuration = workAreaEnd - workAreaStart;

                var totalPairDuration = pairDurations.reduce(function (a, b) { return a + b; }, 0);  // Sum of the durations of the pairs
                var totalGap = totalWorkAreaDuration - totalPairDuration;  // Total duration of gaps
                var pairGap = totalGap / ((myKeyframes.length / 2) - 1);  // Gap between couples

                // Start redistributing keyframes in the work area
                var currentTime = workAreaStart; // The first pair will be placed at the beginning of the work area

                // Remove all existing keyframes and then move them without adding new keyframes
                for (var k = myEffect.numKeys; k > 0; k--) {
                    myEffect.removeKey(k);
                }

                // Move keyframes while maintaining pair spacing, values, and easing properties
                for (var k = 0; k < myKeyframes.length; k += 2) {
                    // Reset the first keyframe of the pair with its value and easing
                    myEffect.setValueAtTime(currentTime, myKeyframes[k].value);
                    var keyIndex1 = myEffect.nearestKeyIndex(currentTime);
                    myEffect.setTemporalEaseAtKey(keyIndex1, myKeyframes[k].easeIn, myKeyframes[k].easeOut);
                    myEffect.setInterpolationTypeAtKey(keyIndex1, myKeyframes[k].interpolation.inType, myKeyframes[k].interpolation.outType);

                    // Reset the second keyframe of the pair with its value and easing
                    var secondKeyTime = currentTime + pairDurations[k / 2];
                    myEffect.setValueAtTime(secondKeyTime, myKeyframes[k + 1].value);
                    var keyIndex2 = myEffect.nearestKeyIndex(secondKeyTime);
                    myEffect.setTemporalEaseAtKey(keyIndex2, myKeyframes[k + 1].easeIn, myKeyframes[k + 1].easeOut);
                    myEffect.setInterpolationTypeAtKey(keyIndex2, myKeyframes[k + 1].interpolation.inType, myKeyframes[k + 1].interpolation.outType);

                    // Adds the gap between pairs
                    currentTime += pairDurations[k / 2] + pairGap;
                }
            } else {
                alert("There must be exactly 16 keyframes.");
            }
        } else {
            alert("No valid Null Object with Morpher effect found in composition: " + selectedComps[i].name);
        }
    }
}

app.endUndoGroup();
Editor is loading...
Leave a Comment