Help creating Text Layer via BatchPlay. How to set "layerKind"?

In Extended Script I would execute the following code:

    var layers = app.activeDocument.artLayers;
    var layer = layers.add();
    layer.kind = LayerKind.TEXT;

I’m trying to do the same via batchPlay command in UXP:

const batchPlay = require("photoshop").action.batchPlay;
const result = await batchPlay
(
[
    {
        "_obj": "make",
        "_target":
        [
            {
                "_ref":"layer"
            }
        ],
        "using":
        {
            "_obj": "layer",
            "name": "MyTextLayer",
            "layerKind": 3
        },
        "_isCommand": true,
        "_options":
        {
            "dialogOptions": "dontDisplay"
        }
    }
],
    {
        "synchronousExecution": false,
        "modalBehavior": "fail"
    }
)

The layer gets created, but as layerKind:1 and not 3. Any advice how to set it to 3?

Thank you.

You do not set layerKind I think you set something like class in reference section.

You might want to try this:

const batchPlay = require("photoshop").action.batchPlay;

const result = await batchPlay(
    [{
        "_obj": "make",
        "_target": [{
            "_ref": "textLayer"
        }],
        "using": {
            "_obj": "textLayer",
            "textKey": "MyTextLayer",

            "bounds": {
                "_obj": "bounds",
                "left": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                },
                "top": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                },
                "right": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                },
                "bottom": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                }
            },
            "boundingBox": {
                "_obj": "boundingBox",
                "left": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                },
                "top": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                },
                "right": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                },
                "bottom": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                }
            },
            "textShape": [{
                "_obj": "textShape",
                "char": {
                    "_enum": "char",
                    "_value": "paint"
                },
                "orientation": {
                    "_enum": "orientation",
                    "_value": "horizontal"
                },
                "transform": {
                    "_obj": "transform",
                    "xx": 1,
                    "xy": 0,
                    "yx": 0,
                    "yy": 1,
                    "tx": 0,
                    "ty": 0
                },
                "rowCount": 1,
                "columnCount": 1,
                "rowMajorOrder": true,
                "rowGutter": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                },
                "columnGutter": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                },
                "spacing": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                },
                "frameBaselineAlignment": {
                    "_enum": "frameBaselineAlignment",
                    "_value": "alignByAscent"
                },
                "firstBaselineMinimum": {
                    "_unit": "pixelsUnit",
                    "_value": 0
                },
                "base": {
                    "_obj": "paint",
                    "horizontal": 0,
                    "vertical": 0
                }
            }],
            "textStyleRange": [{
                "_obj": "textStyleRange",
                "from": 0,
                "to": 12,
                "textStyle": {
                    "_obj": "textStyle",
                    "styleSheetHasParent": true,
                    "fontPostScriptName": "MyriadPro-Regular",
                    "fontName": "Myriad Pro",
                    "fontStyleName": "Regular",
                    "fontScript": 0,
                    "fontTechnology": 0,
                    "fontAvailable": true,
                    "size": {
                        "_unit": "pixelsUnit",
                        "_value": 249
                    },
                    "impliedFontSize": {
                        "_unit": "pixelsUnit",
                        "_value": 249
                    },
                    "horizontalScale": 100,
                    "verticalScale": 100,
                    "syntheticBold": false,
                    "syntheticItalic": false,
                    "autoLeading": true,
                    "tracking": 0,
                    "baselineShift": {
                        "_unit": "pixelsUnit",
                        "_value": 0
                    },
                    "impliedBaselineShift": {
                        "_unit": "pixelsUnit",
                        "_value": 0
                    },
                    "fontCaps": {
                        "_enum": "fontCaps",
                        "_value": "normal"
                    },
                    "digitSet": {
                        "_enum": "digitSet",
                        "_value": "arabicDigits"
                    },
                    "kashidas": {
                        "_enum": "kashidas",
                        "_value": "kashidaDefault"
                    },
                    "diacXOffset": {
                        "_unit": "pixelsUnit",
                        "_value": 0
                    },
                    "diacYOffset": {
                        "_unit": "pixelsUnit",
                        "_value": 0
                    },
                    "markYDistFromBaseline": {
                        "_unit": "pixelsUnit",
                        "_value": 0
                    },
                    "baseline": {
                        "_enum": "baseline",
                        "_value": "normal"
                    },
                    "otbaseline": {
                        "_enum": "otbaseline",
                        "_value": "normal"
                    },
                    "strikethrough": {
                        "_enum": "strikethrough",
                        "_value": "strikethroughOff"
                    },
                    "underline": {
                        "_enum": "underline",
                        "_value": "underlineOff"
                    },
                    "ligature": false,
                    "altligature": false,
                    "contextualLigatures": true,
                    "fractions": false,
                    "ordinals": false,
                    "swash": false,
                    "titling": false,
                    "connectionForms": true,
                    "stylisticAlternates": false,
                    "stylisticSets": 0,
                    "ornaments": false,
                    "justificationAlternates": false,
                    "figureStyle": {
                        "_enum": "figureStyle",
                        "_value": "normal"
                    },
                    "proportionalMetrics": false,
                    "kana": false,
                    "italics": false,
                    "baselineDirection": {
                        "_enum": "baselineDirection",
                        "_value": "withStream"
                    },
                    "textLanguage": {
                        "_enum": "textLanguage",
                        "_value": "englishLanguage"
                    },
                    "japaneseAlternate": {
                        "_enum": "japaneseAlternate",
                        "_value": "defaultForm"
                    },
                    "mojiZume": 0,
                    "gridAlignment": {
                        "_enum": "gridAlignment",
                        "_value": "roman"
                    },
                    "noBreak": false,
                    "color": {
                        "_obj": "RGBColor",
                        "red": 147.00164794921875,
                        "grain": 157.99758911132812,
                        "blue": 79.002685546875
                    },
                    "strokeColor": {
                        "_obj": "RGBColor",
                        "red": 0,
                        "grain": 0,
                        "blue": 0
                    },
                    "baseParentStyle": {
                        "_obj": "textStyle",
                        "fontPostScriptName": "MyriadPro-Regular",
                        "fontName": "Myriad Pro",
                        "fontStyleName": "Regular",
                        "fontScript": 0,
                        "fontTechnology": 0,
                        "fontAvailable": true,
                        "size": {
                            "_unit": "pixelsUnit",
                            "_value": 12
                        },
                        "impliedFontSize": {
                            "_unit": "pixelsUnit",
                            "_value": 12
                        },
                        "horizontalScale": 100,
                        "verticalScale": 100,
                        "syntheticBold": false,
                        "syntheticItalic": false,
                        "autoLeading": true,
                        "tracking": 0,
                        "baselineShift": {
                            "_unit": "pixelsUnit",
                            "_value": 0
                        },
                        "impliedBaselineShift": {
                            "_unit": "pixelsUnit",
                            "_value": 0
                        },
                        "characterRotation": 0,
                        "autoKern": {
                            "_enum": "autoKern",
                            "_value": "metricsKern"
                        },
                        "fontCaps": {
                            "_enum": "fontCaps",
                            "_value": "normal"
                        },
                        "digitSet": {
                            "_enum": "digitSet",
                            "_value": "defaultDigits"
                        },
                        "dirOverride": {
                            "_enum": "dirOverride",
                            "_value": "dirOverrideDefault"
                        },
                        "kashidas": {
                            "_enum": "kashidas",
                            "_value": "kashidaDefault"
                        },
                        "diacVPos": {
                            "_enum": "diacVPos",
                            "_value": "diacVPosOpenType"
                        },
                        "diacXOffset": {
                            "_unit": "pixelsUnit",
                            "_value": 0
                        },
                        "diacYOffset": {
                            "_unit": "pixelsUnit",
                            "_value": 0
                        },
                        "markYDistFromBaseline": {
                            "_unit": "pixelsUnit",
                            "_value": 100
                        },
                        "baseline": {
                            "_enum": "baseline",
                            "_value": "normal"
                        },
                        "otbaseline": {
                            "_enum": "otbaseline",
                            "_value": "normal"
                        },
                        "strikethrough": {
                            "_enum": "strikethrough",
                            "_value": "strikethroughOff"
                        },
                        "underline": {
                            "_enum": "underline",
                            "_value": "underlineOff"
                        },
                        "underlineOffset": {
                            "_unit": "pixelsUnit",
                            "_value": 0
                        },
                        "ligature": true,
                        "altligature": false,
                        "contextualLigatures": false,
                        "alternateLigatures": false,
                        "oldStyle": false,
                        "fractions": false,
                        "ordinals": false,
                        "swash": false,
                        "titling": false,
                        "connectionForms": false,
                        "stylisticAlternates": false,
                        "stylisticSets": 0,
                        "ornaments": false,
                        "justificationAlternates": false,
                        "figureStyle": {
                            "_enum": "figureStyle",
                            "_value": "normal"
                        },
                        "proportionalMetrics": false,
                        "kana": false,
                        "italics": false,
                        "ruby": false,
                        "baselineDirection": {
                            "_enum": "baselineDirection",
                            "_value": "rotated"
                        },
                        "textLanguage": {
                            "_enum": "textLanguage",
                            "_value": "englishLanguage"
                        },
                        "japaneseAlternate": {
                            "_enum": "japaneseAlternate",
                            "_value": "defaultForm"
                        },
                        "mojiZume": 0,
                        "gridAlignment": {
                            "_enum": "gridAlignment",
                            "_value": "roman"
                        },
                        "enableWariChu": false,
                        "wariChuCount": 2,
                        "wariChuLineGap": 0,
                        "wariChuScale": 0.5,
                        "wariChuWidow": 2,
                        "wariChuOrphan": 2,
                        "wariChuJustification": {
                            "_enum": "wariChuJustification",
                            "_value": "wariChuAutoJustify"
                        },
                        "tcyUpDown": 0,
                        "tcyLeftRight": 0,
                        "leftAki": -1,
                        "rightAki": -1,
                        "jiDori": 0,
                        "noBreak": false,
                        "color": {
                            "_obj": "RGBColor",
                            "red": 0,
                            "grain": 0,
                            "blue": 0
                        },
                        "strokeColor": {
                            "_obj": "RGBColor",
                            "red": 0,
                            "grain": 0,
                            "blue": 0
                        },
                        "fill": true,
                        "stroke": false,
                        "fillFirst": true,
                        "fillOverPrint": false,
                        "strokeOverPrint": false,
                        "lineCap": {
                            "_enum": "lineCap",
                            "_value": "buttCap"
                        },
                        "lineJoin": {
                            "_enum": "lineJoin",
                            "_value": "miterJoin"
                        },
                        "lineWidth": {
                            "_unit": "pixelsUnit",
                            "_value": 1
                        },
                        "miterLimit": {
                            "_unit": "pixelsUnit",
                            "_value": 4
                        },
                        "lineDashoffset": 0
                    }
                }
            }]
        },
        "_ref": "document",
        "_enum": "ordinal",
        "_value": "targetEnum",
        "_isCommand": true,
        "_options": {
            "dialogOptions": "dontDisplay"
        }
    }], {
        "synchronousExecution": false,
        "modalBehavior": "fail"
    });
1 Like

In addition to creating layers :smiley:
https://www.adobe.io/photoshop/uxp/ps_reference/classes/document

const myEmptyLayer = await doc.createLayer()
const myLayer = await doc.createLayer({ name: "myLayer", opacity: 80, mode: "colorDodge" })

For a Text layer, it’s a tad more complex :wink:

Finally:
Note that layerKind is read-only:

2 more notes:

  • You don’t need every single text layer property when creating a new text layer. Just copy-pasting these descriptors makes the code X times bigger than it actually has to be.
  • If you want to create a text at a specific position, be aware that the "textClickPoint" property (of a text layer descriptor) can only process percent-values. So if you want to put it at a specific pixel position you’ve got to either do some unit conversion or move it after it’s been created.
1 Like

Thanks Pierre_G, that script works. How did you come up with that script? Is there a reference guide somewhere? How would I go about learning how to write the Descriptor code? The Alchemist tool is great in observing the various events, but some things are not very clear, e.g. your example of creating TextLayer. I’m not sure how I could replicate the action in Photoshop in order for Alchemist to capture it and show me the code you posted. Thank you.

I used Alchemist.
Alchemist is your best friend :wink:
In that case, I used it in “Listen” mode.

I started in a PS new document.
I put Alchemist in Listen mode.
Then made a new layer, hit “T” on the keyboard to bring the Type tool, clicked on the image and renamed the Type layer, then ESCcaped. Finally I stopped Alchemist listening.
Copied and edited the code that Alchemist gives in the “Code” tab.

I quickly amended the whole code, getting rid of several descriptors. I left in the ones that doesnt’ break the code. That can probably be a bit more optimized if I had spent more time dissecting the codes. In the bounds I set all values to zero just to be safe. That can be changed either by hand and programmatically.

I also made sure that the code will target the current document by replacing

"_ref": "document",
"layerID": 3027,

by

"_ref": "document",
"_enum": "ordinal",
"_value": "targetEnum",

This is to avoid the fact that the code will create a layer with the ID of 3027, which you might not want. Instead you want to target the current opened document :wink:

Further, I recommend these links:

https://www.adobe.io/photoshop/uxp/uxp/
https://www.adobe.io/photoshop/uxp/uxp/known-issues/

1 Like

Thank you again Pierre. I tried using Alchemist to catch the events when drawing a text layer, but for some reason it gave me different code than what your steps produced. Unfortunately I didn’t save it to compare to yours. But I just tried your steps and got the same Alchemist code as you. Thank you for the detailed follow ups and the links. Really appreciate it.

Pavel

You’re most welcome !

Is it even possible to manually define a layers ID? I think its just information that gets added to the descriptor after it has been executed and that IDs are always assigned by Photoshop (only).
I never tested it though, maybe someone has? But I already had several use cases where I needed the ID of a layer that gets created in a batchPlay call to use it in further descriptors - I think you have to do it in two calls then.

Is it even possible to manually define a layers ID?

As far as I tested, I can’t see how to manually define a layer ID. It’s a “serial” number that PS somehow implements. However, you can read it, no problem. I always try to keep an organized layerTree using this kind of code

All the layers in the document, in a flat list

const layers = currentDocument.layers
const topLayer = layers[0]

Then you can parse the PS stack layers and ‘get’ the ID you need. Since batchPlay ‘manages’ IDs, they shoud be unique in your layer stack.

But I already had several use cases where I needed the ID of a layer that gets created in a batchPlay call to use it in further descriptors - I think you have to do it in two calls then.

Yep. In fact what i was trying to say about this trick is when you capture something layer-related for example in Alchemist, it’s default behaviour is to refer by the layer ID. Later, when you’ll call your script in UXP, you want your script to be layer-id-agnostic, and work on the current opened document. I hope it makes sense :wink:

This layer ID is read-only. Because in theory… Adobe could change implementation and do not automatically select the newly created layer. If you made that layer from returned ID then you don’t need to care. Otherwise good luck.

The only thing how you could specify layer ID is to make a blank document and add layers until incrementor hits the value you want and then remove other layers. That is of course nonsense for any practical use.

I tried to create a layer with ID and Photoshop ignored it and created its own layer ID. Not a problem for me, just reporting…

Correct. Expected PS behavior.

Sounds fun :laughing: