有希望支持交换位置的同时等比交换大小吗

功能建议 · 35 次浏览
祥睿御免 创建于 19天22小时前

AI写了个,就是流畅度不是很好

// swapPositionAndSize-mirror-centered.jsx - Adobe Photoshop Script
// Version: 0.4.0
// 居中对齐交换位置,并等比例互换尺寸的 Photoshop JSX 脚本

#target photoshop
app.bringToFront();

var doc = app.activeDocument;
var selectedLayers = getSelectedLayersIndex(doc);

if (selectedLayers.length == 2) {
    try {
        var sLayers = [];

        // 获取选中的两个图层的信息
        for (var i = 0; i < selectedLayers.length; i++) {
            selectLayerByIndex(selectedLayers[i], false);
            var layer = app.activeDocument.activeLayer;
            
            var xLeft = layer.bounds[0].value;
            var yTop = layer.bounds[1].value;
            var xRight = layer.bounds[2].value;
            var yBottom = layer.bounds[3].value;
            var width = xRight - xLeft;
            var height = yBottom - yTop;
            var centerX = xLeft + width / 2;
            var centerY = yTop + height / 2;

            sLayers.push({ layer: layer, centerX: centerX, centerY: centerY, width: width, height: height });
        }

        // 安全检查:防止图层宽高为0导致除以零的报错
        if (sLayers[0].width === 0 || sLayers[0].height === 0 || sLayers[1].width === 0 || sLayers[1].height === 0) {
            throw new Error("图层宽度或高度为0,无法计算缩放比例。");
        }

        // 1. 计算位置变化量
        var deltaX = sLayers[1].centerX - sLayers[0].centerX;
        var deltaY = sLayers[1].centerY - sLayers[0].centerY;

        // 2. 计算等比例缩放系数 (单位为百分比 %)
        // 使用 Math.min 确保等比缩放后的图层能完美适配目标区域
        var scale0 = Math.min(sLayers[1].width / sLayers[0].width, sLayers[1].height / sLayers[0].height) * 100;
        var scale1 = Math.min(sLayers[0].width / sLayers[1].width, sLayers[0].height / sLayers[1].height) * 100;

        // 3. 交换图层位置 (位移)
        sLayers[0].layer.translate(deltaX, deltaY);
        sLayers[1].layer.translate(-deltaX, -deltaY);

        // 4. 等比例互换尺寸 (以中心点为基准进行缩放)
        sLayers[0].layer.resize(scale0, scale0, AnchorPosition.MIDDLECENTER);
        sLayers[1].layer.resize(scale1, scale1, AnchorPosition.MIDDLECENTER);

        // 重新选中原来的图层
        for (var i = 0; i < selectedLayers.length; i++) {
            selectLayerByIndex(selectedLayers[i], true);
        }

    } catch (e) {
        alert("发生错误,无法交换图层位置与尺寸:" + e.message);
    }
} else {
    alert("请选中两个图层进行交换!");
}

// 获取选中图层的索引
function getSelectedLayersIndex(doc) {
    var selectedLayers = [];
    var ref = new ActionReference();
    ref.putEnumerated(cTID('Dcmn'), cTID('Ordn'), cTID('Trgt'));
    var desc = executeActionGet(ref);
    if (desc.hasKey(sTID('targetLayers'))) {
        desc = desc.getList(sTID('targetLayers'));
        var count = desc.count;
        for (var i = 0; i < count; i++) {
            try {
                doc.backgroundLayer;
                selectedLayers.push(desc.getReference(i).getIndex());
            } catch (e) {
                selectedLayers.push(desc.getReference(i).getIndex() + 1);
            }
        }
    } else {
        var ref = new ActionReference();
        ref.putProperty(cTID('Prpr'), cTID('ItmI'));
        ref.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
        try {
            doc.backgroundLayer;
            selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')) - 1);
        } catch (e) {
            selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')));
        }
    }
    return selectedLayers;
}

// 通过索引选中图层
function selectLayerByIndex(index, add) {
    var ref = new ActionReference();
    ref.putIndex(charIDToTypeID("Lyr "), index);
    var desc = new ActionDescriptor();
    desc.putReference(charIDToTypeID("null"), ref);
    if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection"));
    desc.putBoolean(charIDToTypeID("MkVs"), false);
    try {
        executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
    } catch (e) {}
}

function cTID(s) { return app.charIDToTypeID(s); }
function sTID(s) { return app.stringIDToTypeID(s); }

祥睿御免 最后更新于 2026/3/3

回复内容
Anlv 19天21小时前
#1
已更新。
回复主贴