Layer Transformation in a For Loop

I have a plugin that scales a layer to certain pixel width and it can either take one layer or a bunch of layers.

When I do it for one layer it works fine but when I do multiple layers it scales them as a group. I’m using a for loop and then batchplaying them but for the life of me I can’t figure out where the problem is. Has anyone encountered this problem?

Could you post a code example?

Yeah. just kind of long.


async function transformHandle() {
    if (doc.activeLayers.length === 1) {
        async function resize() {
            return await batchPlay(transform(doc.activeLayers[0]), {});
        }
        core.executeAsModal(resize, {"commandName": "Scale One Layer"});
    } else {
        for (let i = 0; i < doc.activeLayers.length; i++) {
            async function resizeAll() {
                await batchPlay(transform(doc.activeLayers[i], i), {});
            }
            await core.executeAsModal(resizeAll, {"commandName": "Scale Multiple Layers"});
        }
    }
}

Here’s the transform in a different module


const transform = (el) => { 

    let {width, height} = calcDim(el);
    let widthPercent = (300 * 100) / Math.abs(width);
    let heightPercent = widthPercent;

    return [{
            _obj: "transform",
            _target: [
                {
                    _ref: "layer",
                    _enum: "ordinal",
                    _value: "targetEnum"
                }
            ],
            freeTransformCenterState: {
                _enum: "quadCenterState",
                _value: "QCSAverage"
            },
            width: {
                _unit: "percentUnit",
                _value: widthPercent
            },
            height: {
                _unit: "percentUnit",
                _value: heightPercent
            },
            interfaceIconFrameDimmed: {
                _enum: "interpolationType",
                _value: "bicubic"
            },
            _options: {
                dialogOptions: "dontDisplay"
            }
        }]
}

And the calc function (in a different module)


function calcDim(lay) {
    return {
        "width": lay.bounds.right - lay.bounds.left,
        "height": lay.bounds.top - lay.bounds.bottom
    }
}

Transformations in Photoshop only work on the active layer(s). With the current state of the code you’re just transforming all the active layers (all together) X times. You’ll have to select them first.

Something like this should work:

async function transformHandle() {
  const layerCount = doc.activeLayers.length
  await core.executeAsModal(() => {
    batchPlay(doc.activeLayers.flatMap(layer => ([
      selectByID(layer.id), // <- ActionDescriptor
      transform(layer) // <- ActionDescriptor
    ])), {})
  }, {"commandName": `Scale ${layerCount} Layer${layerCount > 1 ? 's' : ''}`});
}

Amazing, thanks so much, Simon. They really need to improve their documentation.