Using variables across different scripts

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Tom, Kukurykus

User avatar
StoryCave
Posts: 20
Joined: Wed Sep 21, 2016 2:14 pm

Using variables across different scripts

Post by StoryCave »

Hi everyone,

I just recently got into Photoshop scripting with JavaScript and I would like to know if there's a way I could use the variables of an active document across other scripts.
It's my first time asking a question of that nature, I hope I'll make myself understandable ;)

I wrote a script to create a template file and use another script to apply to the active document.
I plan on writing more scripts that will affect that same active document, and although I could just paste the value over all scripts I would like to let people change the template's variable without breaking the other scripts.

Is it possible to create a .jsx file that stores the variables and load it in each script ?

Before showing the full code to run, here's an example of my issue :

I would like to apply the Camera Layer script to the Storyboard template, so the stroke selection just takes the top white space and not the black bar at the bottom.

It does work if I set the selection by manually entering the value in the array of the code snippets below :

Code: Select all


var shapeRef = [
[0,0], [0,h - 284], [w,h - 284], [w,0]
]
docRef.selection.select(shapeRef)
But doesn't work if I do this :

Code: Select all


var shapeRef = [
[0,0], [0,h - bar], [w,h - bar], [w,0]
]
docRef.selection.select(shapeRef)
...which is a variable I created based on a global variable present in the Template script.
Somehow it isn't recognized.

This is the template.

Code: Select all


//Storyboard Template

//Unit settings
var originalUnit = preferences.rulerUnits
preferences.rulerUnits = Units.PIXELS

//Setting up global values
width = 1920
heigth = 1364
res = 150
barHeigth = 284 // <-- THIS IS THE GLOBAL VARIABLE I REFER TO IN THE CAMERA SCRIPT
FontSize = 60

//Set canvas size and resolution,
var docRef = app.documents.add(width, heigth, res)

//Folder and Layers creation for the dialog group
var layerSet = docRef.layerSets.add()
layerSet.name = "SQ_00_SH_000_000"

var artLayerDraw = layerSet.artLayers.add()
artLayerDraw.name = "drawing"

var layerSetB = layerSet.layerSets.add()
layerSetB.name = "dialog"

var artLayerBar = layerSetB.artLayers.add()
artLayerBar.name = "dialog_mask"
docRef.activeLayer = artLayerBar
barHeigth = 284

//Set Selection
shapeRef = [
[0, 0],
[0, heigth - barHeigth],
[width, heigth - barHeigth],
[width, 0]
]
docRef.selection.select(shapeRef)
docRef.selection.invert(shapeRef)

//Set Stroke Color
fillColor = new SolidColor()
fillColor.rgb.red = 0
fillColor.rgb.green = 0
fillColor.rgb.blue = 0
app.activeDocument.selection.fill(fillColor, ColorBlendMode.NORMAL, 100, false)
docRef.selection.deselect()

//Create Text layer for dialog
var artLayerRef = layerSetB.artLayers.add()
artLayerRef.kind = LayerKind.TEXT
var textItemRef = artLayerRef.textItem
textItemRef .contents = '""'
textItemRef.size = FontSize

textColor = new SolidColor()
textColor.rgb.red = 255
textColor.rgb.green = 255
textColor.rgb.blue = 255
textItemRef.color = textColor

textItemRef.justification = Justification.CENTER
artLayerRef.textItem.position = Array(width/2, heigth - barHeigth/2)
artLayerRef.positionLocked = true

// Release references
docRef = null
artLayerRef = null
textItemRef = null


// Restore original ruler unit setting
app.preferences.rulerUnits = originalUnit

Here's the script that applies a layer with a stroke selection :

Code: Select all


//Camera Layer

//Set Document
var docRef = activeDocument
var w = app.activeDocument.width
var h = app.activeDocument.height
var bar = app.activeDocument.barHeigth // <-- THIS IS THE VARIABLE FROM THE TEMPLATE I HOPED I COULD USE

//Create Camera layer
var newCamLayer = docRef.artLayers.add()
newCamLayer.name = "CAM"
newCamLayer.move(docRef.layerSets[0], ElementPlacement.INSIDE)
docRef.activeLayer = newCamLayer

//Set Selection
var shapeRef = [
[0,0],
[0,h - bar],
[w,h - bar],
[w,0]
]
docRef.selection.select(shapeRef)

//Set Stroke Color
strokeColor = new SolidColor
strokeColor.rgb.red = 0
strokeColor.rgb.green = 165
strokeColor.rgb.blue = 63

activeDocument.selection.stroke (strokeColor, 10, StrokeLocation.INSIDE, ColorBlendMode.NORMAL, 100, false)
docRef.selection.deselect()
I hope it was not tedious to read, thanks a lot for bearing with me and look forward to your feedback.

The Caveman.
User avatar
Kukurykus
Posts: 528
Joined: Mon Jul 25, 2016 12:36 pm

Re: Using variables across different scripts

Post by Kukurykus »

This is template script saved on your desktop:

Code: Select all

alert('Hello')

Following part should be placed on top of user script.
(for a test just paste it - without saving - to ExtendScript editor and play to see how it's calling alert from "other" script:

Code: Select all

eval(eval("'#include' + File('~/Desktop/alert.jsx')"))

NOTE:

If you don't know that user script called nothing else beside template script variables or something like alert from my example you must specify it in both (template and user) script. So when you run your template script (not by user, but itself) then all content inside will be executed, but when user calls the template script, only part of it (you decided which one before) will be available for the user. Example:

Template script:

Code: Select all

var bol

if (!bol) alert('The part of its condition is available for person launching template script in first instance.')

// following part will be executed if template script was run as main script as well as user called it from its script:

alert('This part is available both for creator and user.')

User script:

Code: Select all

var bol = true
eval(eval("'#include' + File('~/Desktop/alert.jsx')"))
User avatar
StoryCave
Posts: 20
Joined: Wed Sep 21, 2016 2:14 pm

Re: Using variables across different scripts

Post by StoryCave »

Hi Kukurykus,

Thanks a lot for your reply, I've tested your script and calling alert.jsx from another file did work so I made a test with my scripts and I couldn't get to make it work :/

That's what I did :

1. I created a StoryCaveCore.jsx file in which I wrote the global variables I want the other scripts to use :

Code: Select all


width = 1920 // Document's width
heigth = 1364 // Document's heigth
res = 150 // Document's resoultion
barHeigth = 284 // Dialog Bar height
FontSize = 60 //if changing this value don't forget to adjust artLayerRef.textItem.position
2. Then in my StoryCaveCam.jsx script I added this :

Code: Select all


eval(eval("'#include' + File('~/Adobe Scripts/StoryCaveCore.jsx')"))
on top of this :

Code: Select all


//Set Document
var docRef = activeDocument
var w = app.activeDocument.width
var h = app.activeDocument.height
var bar = app.activeDocument.barHeigth

//Create Camera layer
var newCamLayer = docRef.artLayers.add()
newCamLayer.name = "CAM"
newCamLayer.move(docRef.layerSets[0], ElementPlacement.INSIDE)
docRef.activeLayer = newCamLayer

//Set Selection
var shapeRef = [
[0,0],
[0,h - bar],
[w,h - bar],
[w,0]
]
docRef.selection.select(shapeRef)

//Set Stroke Color
strokeColor = new SolidColor
strokeColor.rgb.red = 0
strokeColor.rgb.green = 165
strokeColor.rgb.blue = 63

activeDocument.selection.stroke (strokeColor, 10, StrokeLocation.INSIDE, ColorBlendMode.NORMAL, 100, false)
docRef.selection.deselect()
3. and this is the message I got running the StoryCaveCam.jsx script in my activeDocument created with StoryCaveTemplate.jsx :
Cannot execute script in target engine 'main'!
(#48) File or folder does not exist
It's the first time I use this function so I might have done something wrong, for example I'm not sure about this line :

Code: Select all

var bar = app.activeDocument.barHeigth
barHeight is a variable I created in the template and reference script (StoryCaveCore.jsx) just the same way I used app.activeDocument.width and app.activeDocument.height.

Do you think there is an easier way to retrieve the barHeight variable from the activeDocument ?

Sorry again if it's unclear, I hope you'll be able to help ;)

Thanks.

K.
User avatar
Kukurykus
Posts: 528
Joined: Mon Jul 25, 2016 12:36 pm

Re: Using variables across different scripts

Post by Kukurykus »

'~/Adobe Scripts/StoryCaveCore.jsx' is a wrong path, as that sign "~" is reserved between other things for Desktop only.

If should use full path, and the best way to check it is simply to save some .psd file in the folder where you store your scripts. Then open this file in Photoshop, and finally when you are in ExtendScript in PS mode type and play:

Code: Select all

activeDocument.path

You'll get a path of current psd. file, so where your scripts are then copy the path you got (it may be for ex. something starting on your c drive):

c/Program Files/Adobe/Photoshop/Presets/Adobe Scripts/StoryCaveCore.jsx

or

d/Adobe Scripts/StoryCaveCore.jsx


Use that in eval, so like:

eval(eval("'#include' + File('/c/Program Files/Adobe/Photoshop/Presets/Adobe Scripts/StoryCaveCore.jsx')"))

or just:

eval(eval("'#include' + File('/d/Adobe Scripts/StoryCaveCore.jsx')"))


If your users use your Template script in your company web from other computers then you have to start not from a disk letter but computer / server name. So if your computer is named for ex. "StoryCave" then the correct path put at top of user script will be:

eval(eval("'#include' + File(//StoryCave'/c/Program Files/Adobe/Photoshop/Presets/Adobe Scripts/StoryCaveCore.jsx')"))

REMEMBER about 2 slashes before computer name (in case of only disk letter there should be only 1 slash character)


When you simply want to check something really is where it seems it is but you're not sure try for ex. this:

File('/d/somefile.jsx').exists

It will give true or false result.
Last edited by Kukurykus on Thu Sep 22, 2016 4:38 pm, edited 1 time in total.
User avatar
StoryCave
Posts: 20
Joined: Wed Sep 21, 2016 2:14 pm

Re: Using variables across different scripts

Post by StoryCave »

Ahhhh alright !

Damn, that's not convenient if the .psd file needs to be in the same folder as the script files :(

I think that for the moment I'll stick with local variables and for the most advanced users to let them change the variables until there's a magical way to reference the activeDocument's variables.

Thanks again Kukurykus, I'll keep digging and learning.

Cheers.
User avatar
Kukurykus
Posts: 528
Joined: Mon Jul 25, 2016 12:36 pm

Re: Using variables across different scripts

Post by Kukurykus »

No you didn't understand. You don't have to keep your .psd files in the same folder you keep your scripts.

I wanted only to make easy to check a path of script. There is no completely need to copy psd files to scripts folder.

Anyway I updated last post, you can read it again.
User avatar
StoryCave
Posts: 20
Joined: Wed Sep 21, 2016 2:14 pm

Re: Using variables across different scripts

Post by StoryCave »

Thanks again for breaking down your explanation, I'll study that carefully and get back asap ! ;)

Sorry if I'm a bit slow, I just started learning JS three weeks ago.
User avatar
DavideBarranca
Posts: 16
Joined: Tue Jul 26, 2016 2:12 pm

Re: Using variables across different scripts

Post by DavideBarranca »

I would substitute:

Code: Select all

eval(eval("'#include' + File('/path/to/StoryCaveCore.jsx')"))
with the simpler:

Code: Select all

$.evalFile("/path/to/StoryCaveCore.jsx");
Regards,

Davide
User avatar
StoryCave
Posts: 20
Joined: Wed Sep 21, 2016 2:14 pm

Re: Using variables across different scripts

Post by StoryCave »

Hey Kukurykus and Davide, just wanna thank you guys, I just added the code you suggested and it works perfectly ! :mrgreen:

The scripts have been updated on github to make them available.

My last question on this matter (which is very minor) : Is there a universal default script folder path line I could use across both PCs and MACs ? like this one : .../Photoshop CC 2015/Presets/ Scripts
A lot of animation/storyboard people aren't code-savvy so I'd like to make these scripts work in the photoshop's default script folder that they'll copy these scripts to.

A thousand thanks again !

K.
User avatar
Kukurykus
Posts: 528
Joined: Mon Jul 25, 2016 12:36 pm

Re: Using variables across different scripts

Post by Kukurykus »

You're rigth Davide it's simpler and I know it too. I just spent last year in CS2 where I started scripting from zero and there evalfile wasn't available yet so I found out this method. I had fun to write scripts for all versions of Photoshop starting from CS2 up to CS6 and trying to make them working in all of them. that wasn't easy each time but helped me to see nothing is impossible. Good practise and way to learn thinking when you try on your own something you can't read anywhere how to do that. Evalfile was implemented from CS3 but I did wanted at least try to see what I can do that some things from later versions could be reproduced by myself in earlier ones.