addKeyframe_test.jsx

addKeyframeUI_test.jsx

addKeyframeUI_relative.jsx

AddKeyframeUI.jsx

function createKeyframeUI() {
    var win = new Window("palette", "Keyframe Setter", undefined, {resizeable: true});
    win.orientation = "column";
    
    var tabPanel = win.add("tabbedpanel");
    var positionTab = tabPanel.add("tab", undefined, "位置");
    var scaleTab = tabPanel.add("tab", undefined, "スケール");
    var rotationTab = tabPanel.add("tab", undefined, "回転");
    var opacityTab = tabPanel.add("tab", undefined, "透明度");
    
    function createTabContent(tab, type) {
        var inputGroup = tab.add("group");
        inputGroup.orientation = "column";
        
        var frameInputs = [];
        var xInputs = [];
        var yInputs = [];
        
        for (var i = 0; i < 10; i++) {
            var row = inputGroup.add("group");
            row.orientation = "row";
            
            var frameInput = row.add("edittext", undefined, "");
            frameInput.characters = 5;
            frameInputs.push(frameInput);
            
            if (type === "position" || type === "scale") {
                var xInput = row.add("edittext", undefined, "");
                xInput.characters = 10;
                xInputs.push(xInput);
                
                var yInput = row.add("edittext", undefined, "");
                yInput.characters = 10;
                yInputs.push(yInput);
            } else {
                var valueInput = row.add("edittext", undefined, "");
                valueInput.characters = 10;
                xInputs.push(valueInput);
            }
        }
        
        var applyBtn = tab.add("button", undefined, "適用");
        
        applyBtn.onClick = function() {
            var comp = app.project.activeItem;
            if (!(comp instanceof CompItem)) {
                alert("コンポジションを選択してください。");
                return;
            }
            
            var layers = comp.selectedLayers;
            if (layers.length === 0) {
                alert("レイヤーを選択してください。");
                return;
            }
            
            app.beginUndoGroup("Add Custom Keyframes");
            
            for (var i = 0; i < layers.length; i++) {
                var layer = layers[i];
                var prop = null;
                
                switch (type) {
                    case "position": prop = layer.property("ADBE Transform Group").property("ADBE Position"); break;
                    case "scale": prop = layer.property("ADBE Transform Group").property("ADBE Scale"); break;
                    case "rotation": prop = layer.property("ADBE Transform Group").property("ADBE Rotate Z"); break;
                    case "opacity": prop = layer.property("ADBE Transform Group").property("ADBE Opacity"); break;
                }
                
                if (!prop) continue;
                
                var baseTime = comp.time; // 現在のCTIの位置
                
                for (var j = 0; j < frameInputs.length; j++) {
                    if (frameInputs[j].text === "") continue;
                    var keyTime = baseTime + parseFloat(frameInputs[j].text) / comp.frameRate;
                    
                    if (type === "position" || type === "scale") {
                        var xValue = xInputs[j].text === "" ? prop.value[0] : parseFloat(xInputs[j].text);
                        var yValue = yInputs[j].text === "" ? prop.value[1] : parseFloat(yInputs[j].text);
                        
                        if (!isNaN(keyTime) && !isNaN(xValue) && !isNaN(yValue)) {
                            prop.setValueAtTime(keyTime, [xValue, yValue]);
                        }
                    } else {
                        var value = xInputs[j].text === "" ? prop.value : parseFloat(xInputs[j].text);
                        
                        if (!isNaN(keyTime) && !isNaN(value)) {
                            prop.setValueAtTime(keyTime, value);
                        }
                    }
                }
            }
            
            app.endUndoGroup();
        };
    }
    
    createTabContent(positionTab, "position");
    createTabContent(scaleTab, "scale");
    createTabContent(rotationTab, "rotation");
    createTabContent(opacityTab, "opacity");
    
    win.center();
    win.show();
}

createKeyframeUI();