Skip to main content
Participating Frequently
April 1, 2026
Answered

Need someone to use Scriptlistener when a Mask is translated

  • April 1, 2026
  • 1 reply
  • 34 views

Hi, I had issues with Scriptlistener not making logs for years and gave up trying to fix

 

I do need the ActionDescriptor when a Mask is being transformed and moved, basically the equivalent of 

app.activeDocument.selection.translate(x,y);

Asking for this instead of using the above code since for some reason my code keeps breaking under suspendHistory, so giving AM a go.

    Correct answer Stephen Marsh

    @Crystal33276269zcyj 

     

    Here is the raw code:

     

    var idTrnf = charIDToTypeID( "Trnf" );
    var desc270 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
    var ref7 = new ActionReference();
    var idLyr = charIDToTypeID( "Lyr " );
    var idOrdn = charIDToTypeID( "Ordn" );
    var idTrgt = charIDToTypeID( "Trgt" );
    ref7.putEnumerated( idLyr, idOrdn, idTrgt );
    desc270.putReference( idnull, ref7 );
    var idFTcs = charIDToTypeID( "FTcs" );
    var idQCSt = charIDToTypeID( "QCSt" );
    var idQcsa = charIDToTypeID( "Qcsa" );
    desc270.putEnumerated( idFTcs, idQCSt, idQcsa );
    var idOfst = charIDToTypeID( "Ofst" );
    var desc271 = new ActionDescriptor();
    var idHrzn = charIDToTypeID( "Hrzn" );
    var idPxl = charIDToTypeID( "#Pxl" );
    desc271.putUnitDouble( idHrzn, idPxl, -123.000000 );
    var idVrtc = charIDToTypeID( "Vrtc" );
    var idPxl = charIDToTypeID( "#Pxl" );
    desc271.putUnitDouble( idVrtc, idPxl, 42.000000 );
    var idOfst = charIDToTypeID( "Ofst" );
    desc270.putObject( idOfst, idOfst, desc271 );
    var idLnkd = charIDToTypeID( "Lnkd" );
    desc270.putBoolean( idLnkd, true );
    var idIntr = charIDToTypeID( "Intr" );
    var idIntp = charIDToTypeID( "Intp" );
    var idBcbc = charIDToTypeID( "Bcbc" );
    desc270.putEnumerated( idIntr, idIntp, idBcbc );
    executeAction( idTrnf, desc270, DialogModes.NO );

     

    Although it would be safer to ensure that there is a layer mask active, rather than the composite channel.

    1 reply

    Stephen Marsh
    Community Expert
    Stephen MarshCommunity ExpertCorrect answer
    Community Expert
    April 1, 2026

    @Crystal33276269zcyj 

     

    Here is the raw code:

     

    var idTrnf = charIDToTypeID( "Trnf" );
    var desc270 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
    var ref7 = new ActionReference();
    var idLyr = charIDToTypeID( "Lyr " );
    var idOrdn = charIDToTypeID( "Ordn" );
    var idTrgt = charIDToTypeID( "Trgt" );
    ref7.putEnumerated( idLyr, idOrdn, idTrgt );
    desc270.putReference( idnull, ref7 );
    var idFTcs = charIDToTypeID( "FTcs" );
    var idQCSt = charIDToTypeID( "QCSt" );
    var idQcsa = charIDToTypeID( "Qcsa" );
    desc270.putEnumerated( idFTcs, idQCSt, idQcsa );
    var idOfst = charIDToTypeID( "Ofst" );
    var desc271 = new ActionDescriptor();
    var idHrzn = charIDToTypeID( "Hrzn" );
    var idPxl = charIDToTypeID( "#Pxl" );
    desc271.putUnitDouble( idHrzn, idPxl, -123.000000 );
    var idVrtc = charIDToTypeID( "Vrtc" );
    var idPxl = charIDToTypeID( "#Pxl" );
    desc271.putUnitDouble( idVrtc, idPxl, 42.000000 );
    var idOfst = charIDToTypeID( "Ofst" );
    desc270.putObject( idOfst, idOfst, desc271 );
    var idLnkd = charIDToTypeID( "Lnkd" );
    desc270.putBoolean( idLnkd, true );
    var idIntr = charIDToTypeID( "Intr" );
    var idIntp = charIDToTypeID( "Intp" );
    var idBcbc = charIDToTypeID( "Bcbc" );
    desc270.putEnumerated( idIntr, idIntp, idBcbc );
    executeAction( idTrnf, desc270, DialogModes.NO );

     

    Although it would be safer to ensure that there is a layer mask active, rather than the composite channel.

    Stephen Marsh
    Community Expert
    Community Expert
    April 1, 2026

    Here it is with a check for the layer mask being selected, rather than the composite channel:

     

    layerMaskIsSelected();
    function layerMaskIsSelected() {
    s2t = stringIDToTypeID;

    (r = new ActionReference()).putProperty(s2t('property'), p = s2t('hasUserMask'));
    r.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
    if (executeActionGet(r).getBoolean(p)) {

    (r = new ActionReference()).putProperty(s2t('property'), p = s2t('name'));
    (r = new ActionReference()).putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
    layerName = executeActionGet(r).getString(p);

    (r = new ActionReference()).putProperty(s2t('property'), p = s2t('channelName'));
    r.putEnumerated(s2t("channel"), s2t("ordinal"), s2t("targetEnum"));
    channelName = executeActionGet(r).getString(p);

    (r = new ActionReference()).putProperty(s2t('property'), p = s2t('alphaChannelOptions'));
    r.putEnumerated(s2t("channel"), s2t("ordinal"), s2t("targetEnum"));
    alphaChannel = executeActionGet(r).hasKey(p);

    if (channelName.indexOf(layerName) === 0 && !alphaChannel) {
    transform(-123, 42, true); // Move the layer mask
    } else {
    alert("Layer mask is NOT selected.");
    }
    }
    }

    function transform(horizontal, vertical, linked) {
    var c2t = function (s) {
    return app.charIDToTypeID(s);
    };

    var s2t = function (s) {
    return app.stringIDToTypeID(s);
    };

    var descriptor = new ActionDescriptor();
    var descriptor2 = new ActionDescriptor();
    var reference = new ActionReference();

    reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
    descriptor.putReference( c2t( "null" ), reference );
    descriptor.putEnumerated( s2t( "freeTransformCenterState" ), s2t( "quadCenterState" ), s2t( "QCSAverage" ));
    descriptor2.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), horizontal );
    descriptor2.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), vertical );
    descriptor.putObject( s2t( "offset" ), s2t( "offset" ), descriptor2 );
    descriptor.putBoolean( s2t( "linked" ), linked );
    descriptor.putEnumerated( c2t( "Intr" ), s2t( "interpolationType" ), s2t( "bicubic" ));
    executeAction( s2t( "transform" ), descriptor, DialogModes.NO );
    }

     

    Or this alternative variation, which is more practical as it actually checks if the layer mask exists, rather than being active (it doesn’t need to be active, just that it exists):

     

    // Check for layer mask
    sTT = stringIDToTypeID;
    var ref = new ActionReference();
    ref.putEnumerated(
    sTT('layer'),
    sTT('ordinal'),
    sTT('targetEnum')
    );
    var hasMask = executeActionGet(ref).getBoolean(sTT('hasUserMask'));
    if (!hasMask) {
    alert("No layer mask found");
    } else {
    transform(-123, 42, true); // Move the layer mask
    }


    function transform(horizontal, vertical, linked) {
    var c2t = function (s) {
    return app.charIDToTypeID(s);
    };

    var s2t = function (s) {
    return app.stringIDToTypeID(s);
    };

    var descriptor = new ActionDescriptor();
    var descriptor2 = new ActionDescriptor();
    var reference = new ActionReference();

    reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
    descriptor.putReference( c2t( "null" ), reference );
    descriptor.putEnumerated( s2t( "freeTransformCenterState" ), s2t( "quadCenterState" ), s2t( "QCSAverage" ));
    descriptor2.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), horizontal );
    descriptor2.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), vertical );
    descriptor.putObject( s2t( "offset" ), s2t( "offset" ), descriptor2 );
    descriptor.putBoolean( s2t( "linked" ), linked );
    descriptor.putEnumerated( c2t( "Intr" ), s2t( "interpolationType" ), s2t( "bicubic" ));
    executeAction( s2t( "transform" ), descriptor, DialogModes.NO );
    }

     

    Although not necessary to select the mask channel if it exists, this uses code to explicitly select the layer mask, which could be handy in another situation:

     

    // Check for layer mask
    sTT = stringIDToTypeID;
    var ref = new ActionReference();
    ref.putEnumerated(
    sTT('layer'),
    sTT('ordinal'),
    sTT('targetEnum')
    );
    var hasMask = executeActionGet(ref).getBoolean(sTT('hasUserMask'));
    if (!hasMask) {
    alert("No layer mask found");
    } else {
    selectLayerCompositeChannel("mask"); // "RGB" or "mask"
    transform(-123, 42, true); // Move the layer mask
    }


    function selectLayerCompositeChannel(chanPara) {
    var s2t = function (s) {
    return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    var reference = new ActionReference();
    reference.putEnumerated( s2t( "channel" ), s2t( "channel" ), s2t( chanPara ));
    descriptor.putReference( s2t( "null" ), reference );
    descriptor.putBoolean( s2t( "makeVisible" ), false );
    executeAction(s2t( "select" ), descriptor, DialogModes.NO);
    }

    function transform(horizontal, vertical, linked) {
    var c2t = function (s) {
    return app.charIDToTypeID(s);
    };

    var s2t = function (s) {
    return app.stringIDToTypeID(s);
    };

    var descriptor = new ActionDescriptor();
    var descriptor2 = new ActionDescriptor();
    var reference = new ActionReference();

    reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
    descriptor.putReference( c2t( "null" ), reference );
    descriptor.putEnumerated( s2t( "freeTransformCenterState" ), s2t( "quadCenterState" ), s2t( "QCSAverage" ));
    descriptor2.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), horizontal );
    descriptor2.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), vertical );
    descriptor.putObject( s2t( "offset" ), s2t( "offset" ), descriptor2 );
    descriptor.putBoolean( s2t( "linked" ), linked );
    descriptor.putEnumerated( c2t( "Intr" ), s2t( "interpolationType" ), s2t( "bicubic" ));
    executeAction( s2t( "transform" ), descriptor, DialogModes.NO );
    }

     

    Enjoy!