如何在调整对象大小时保持边距(位置)相同

How to keep margin(Positions) same while resizing objects

什么是问题?

我不想让社区与我的问题混淆,所以我会说我的问题是基于 Javascript(特别是 Photoshop's DOM)。因此,如果有人可以在需要基本 javascript 的 function/logic 上帮助我,而不是他们可以努力进一步阅读,谢谢。

现在;情况是我正在免费赠送名为“PS Blender”的 Photoshop 插件(HTML 面板),它将模拟 Illustrator Blend Tool 的相同功能,尽管 Illustrator 具有非常复杂和强大的功能混合选项,而我只打算使用位置、旋转、缩放和透明度进行基本混合。第一个原型已经准备就绪,我已经测试了除了比例混合之外一切正常的地方。在我们继续之前,请观看下面的 GIF 以便您了解案例。

我关于问题的代码

所以生成 Blend 的整个函数是......

function generateBlend(data) {
    //Get user's input from panel
    var newLayerPositionX = data.split("&&&&")[0];
    var newLayerPositionY = data.split("&&&&")[1];
    var newLayerScaleX = data.split("&&&&")[2];
    var newLayerScaleY = data.split("&&&&")[3];
    var newLayerRotation = data.split("&&&&")[4];
    var newLayerTransparency = data.split("&&&&")[5];
    var steps = parseInt(data.split("&&&&")[6]);
    //calculates the difference between values where start values are the real data and new values are user input
    var xTransform = parseFloat(newLayerPositionX) - parseFloat(startLayerPositionX);
    var yTransform = parseFloat(newLayerPositionY) - parseFloat(startLayerPositionY);
    var xScale = parseFloat(newLayerScaleX) - parseFloat(startScaleX); //if positive then increase size and on negative decrease
    var yScale = parseFloat(newLayerScaleY) - parseFloat(startScaleY);
    var rot = parseFloat(newLayerRotation) - parseFloat(startRotation);
    var trans = parseFloat(newLayerTransparency) - parseFloat(startTransparency);
    //dummy variables to call after every increment in for loop
    var masterScaleX = parseFloat(startScaleX);
    var masterScaleY = parseFloat(startScaleY);
    var masterRotation = parseFloat(startRotation);
    var masterTransparency = parseFloat(startTransparency);
    //create a new smart object to start copying and cloning layers (steps)
    editSmartObject();
    duplicateLayer();
    moveLayerBelow();
    convertToSmart();
    renameLayer("SmartObject");
    //define masterPositionX and Y because startPositionX is the value of layers bound which lies in original document while our current layer lies in the smart object of original document so bounds need to be updated
    var docRef = app.activeDocument;
    var curLayer = docRef.activeLayer;
    var curLayerBounds = curLayer.bounds;
    var curLayerPositionX = curLayerBounds[0].value + ((curLayerBounds[2].value - curLayerBounds[0].value) / 2);
    var curLayerPositionY = curLayerBounds[1].value + ((curLayerBounds[3].value - curLayerBounds[1].value) / 2);
    var masterPositionX = parseFloat(curLayerPositionX);
    var masterPositionY = parseFloat(curLayerPositionY);
    //generates incremental values i.e. 50px move in 5 steps gives 10px per step.
    var splitPositionX = parseFloat(xTransform) / steps;
    var splitPositionY = parseFloat(yTransform) / steps;
    var splitScaleX = parseFloat(xScale) / steps;
    var splitScaleY = parseFloat(yScale) / steps;
    var splitRotation = parseFloat(rot) / steps;
    var splitTransparency = parseFloat(trans) / steps;
    //the main code for generating blends starts here
    for (var i = 0; i < steps; i++) {
        //updates masterPositing by adding splits
        masterPositionX = masterPositionX + parseFloat(splitPositionX);
        masterPositionY = masterPositionY + parseFloat(splitPositionY);
        //Photoshop DOM Scale method is relative rather than absolute so if we will change scale to 50 then it won't resize object by 50% but it will resize objects half by it's current size so we need to tweak resize method
        var masterScaleX = parseFloat(((masterScaleX + splitScaleX) * 100) / masterScaleX);
        var masterScaleY = parseFloat(((masterScaleY + splitScaleY) * 100) / masterScaleY);
        var masterRotation = masterRotation + parseFloat(splitRotation);
        var masterTransparency = masterTransparency + parseFloat(splitTransparency);
        //starts looping in where order will be duplicate SO-clear mask-move downside-apply transformation-select above layer-select bound-below layer mask (This all steps are what makes blend layers)
        try {
            duplicateLayer();
            moveLayerBelow();
            if (hasMask() == true) {
                selectLayerMask();
                deleteLayerMask();
            }
            transformLayer(parseFloat(splitPositionX), parseFloat(splitPositionY))
            resizeLayer(masterScaleX, masterScaleY);
            rotateLayer(masterRotation);
            changeTransparency(masterTransparency);
            revealAll();
            selectAboveLayer();
            selectBoundOfLayer()
            selectBelowLayer();
            createMask();
            invert();
            trim();
        } catch (e) {
            alert(e);
        }
    }
}

正如您在上面的 try 部分中看到的那样,我通过调用单独的方法来完成所有工作;现在您可能只对 Resize 方法感兴趣,代码是....

function resizeLayer(xScale, yScale) {
    app.activeDocument.activeLayer.resize(xScale, yScale, AnchorPosition.MIDDLECENTER);
}

看到这是直接从官方 JS 参考派生的非常基本的功能。

我尝试了什么?

好吧,我已经尝试了一些不同的方法,例如更改 AnchorPosition 等,但是由于混合方向可以是任何方向,所以我无法真正找到使其工作的方法。好吧,这个功能正在做它的工作。让我们举一个简单的例子:认为该层应该每一步移动 10px 并且应该调整 5%,现在如果没有任何调整大小那么它将每 10px 移动克隆但是如果我们现在要调整它那么我们需要将克隆移动 10px+ 由于调整大小而减少的区域,该区域似乎无法弄清楚,因为我根本不是开发人员并且对 JS 非常了解。

我需要什么?

我所需要的只是一些关于如何编写调整大小逻辑代码以解决此问题的指导。您的所有贡献都将非常有帮助,因为这是我为社区制作的免费赠品,如果您也需要,我可以共享源代码。感谢您花时间回答我的问题。

此致!

过程很简单,问题本身也有答案,但我从来没有从那个角度想过。问题是即使对象按比例缩小时如何保持边距,我所要做的就是将按比例缩小的像素添加到 xDisplacement 并且效果很好。

这甚至是一件好事,我决定不自己制作插件,因为我担心我可能会收到数百个问题,因为我是开发方面的新手,已更新代码和第一个原型可在 PS Blender GitHub 页面上找到。 (我将其作为开源发布,也许我可以 post link)