Copy link to clipboard
Copied
In this script that moves layers with the same name I would like to include layers that are locked and hidden while maintaining their state once transferred. I am failing at retrieving the push value and using it as a boolean.
/--------------------------------------------------
// MergeLayers
//--------------------------------------------------
function MergeLayers() {
if (!documents.length) return;
var doc = app.activeDocument;
var layerGroups = collectSameLayers(doc);
moveLayersToNew(doc, layerGroups);
}
// Collect layers with the same name
function collectSameLayers(doc) {
var layerGroups = [];
for (var i = 0; i < doc.layers.length; i++) {
var currLayer = doc.layers[i];
var currName = currLayer.name;
var isFound = false;
var isLocked = false;
var isVisible = true;
if (currLayer.locked === true) {
isLocked = [true];
currLayer.locked = false;
}
if (currLayer.visible === false) {
isVisible = [false];
currLayer.visible = true;
}
for (var j = 0; j < layerGroups.length; j++) {
if (layerGroups[j].name === currName) {
layerGroups[j].layers.push(currLayer);
isFound = true;
break;
}
}
if (!isFound) {
layerGroups.push({name: currName,layers: [currLayer],lockStatus: [isLocked],visibleStatus: [isVisible]});
}
}
return layerGroups;
}
// Create new layer and move inside original layers
function moveLayersToNew(doc, layerGroups) {
for (var i = layerGroups.length - 1; i >= 0; i--) {
var currGroup = layerGroups[i];
; // Only process if there are multiple layers with the same name
if (currGroup.layers.length > 1) {
var newLayer = doc.layers.add();
newLayer.name = currGroup.name;
for (var j = currGroup.layers.length - 1; j >= 0; j--) {
currGroup.layers[j].move(newLayer, ElementPlacement.INSIDE);
// need help using the lockStatus and visibleStatus boolean from the layerGroups array
currGroup.layers[j].locked =
currGroup.layers[j].visible =
}
}
}
}
There were a few issues with the way you were trying to do things so I wrote some code to accomplish the task you are attempting.
A few things to note...
var doc = app.activeDocument;
var
...
Copy link to clipboard
Copied
There were a few issues with the way you were trying to do things so I wrote some code to accomplish the task you are attempting.
A few things to note...
var doc = app.activeDocument;
var groups = groupLayersByName();
// sanity check
for (var i = 0; i < groups.length; i++) {
$.writeln(
"Group " + (i + 1) + "\nName: " + groups[i][0].name + "\nCount: " + groups[i].length
);
}
moveGroupedLayersToNewLayer(groups);
function groupLayersByName() {
var groups = [];
var group, cur, found, comp;
// iterate over each layer
for (var i = 0; i < doc.layers.length; i++) {
cur = doc.layers[i];
found = false;
// iterate over groups of layer with same names
for (var j = 0; j < groups.length; j++) {
group = groups[j];
comp = group[0];
// check if the current layer name matches the group
if (cur.name === comp.name) {
found = true;
group.push(cur);
break;
}
}
// if the current layer didn't match any groups create a new group
if (!found) groups.push([cur]);
}
return groups;
}
function moveGroupedLayersToNewLayer(groups) {
var group, commonName, parent, layer;
// iterate over commong layer groups
// please note the iteration is going in reverse to
// try and keep the inital layer similar (not exact because of method)
for (var i = groups.length - 1; i >= 0; i--) {
group = groups[i];
// skip groups with only one layer
if (group.length === 1) continue;
commonName = group[0].name;
// create a new layer to hold common layers
parent = doc.layers.add();
parent.name = commonName;
// iterate over common layer and move each into new parent layer
// going in reverse again to keep layer order similar
var locked, visible;
for (var j = group.length - 1; j >= 0; j--) {
layer = group[j];
// get layer locked and visible status
locked = layer.locked;
visible = layer.visible;
// unlock and make layer visible for move
layer.locked = false;
layer.visible = true;
// move the layer into the parent layer
layer.move(parent, ElementPlacement.INSIDE);
// reset the layer locked and visible status
layer.locked = locked;
layer.visible = visible;
}
}
}
And, to answer your question about a boolean inside of an array, you can certainly store and retrieve a boolean value from an array. There were multiple reasons you were getting tripped up but about the boolean specifically, you were storing an array of an array of the boolean.
// you were doing something like
var isLocked = [false}
// then adding that to another array like
{...lockStatus: [isLocked]} // which really equals [[false]]
// so to access the boolean value you would need to go two levels deep
var boolValue = lockStatus[0][0]
Copy link to clipboard
Copied
Thanks so much brother ... specially for the explanation which now makes total sense. The code that you wrote in it of itself teaches me a lot as well. I'm new to arrays and I tried [0] to no end.
Copy link to clipboard
Copied
The only drawback that I noticed is that after you merge the layers .... if you had another instance where you created a new layer with the same name as that of one already merged, the previously merged sublayers become subsublayers.
Copy link to clipboard
Copied
I'm not sure I follow... Are you running the script which "merges" common named layers then independently creating a new layer in the file with same common name as one of the groups, then running the script again? Could you share your file here as a pdf or even do a screen recording so I can follow your steps?
Copy link to clipboard
Copied
1 - Original layers with redundant names.
2 - After first merge ... perfect results.
3 - Created another layer with existing name.
4 - During second merge, as per highlight,
all sublayers get moved another level down.
This is not a big deal and it would be a highly unusual occurance. I do want to run this script as a workflow maintenance script and ideally I would leave the existing contents of the parent layer intact.
Copy link to clipboard
Copied
Ok, this is what I thought you were describing. The script is working as expected, it is just that the requirements the second time you run it (after adding the new layer) have changed. You could certainly adjust the script to account for this occurrence but it would be (imho) overly complex for its original job. My suggestion would be to either just create the new layer inside of the parent layer of the already merged group, or drag your new layer into the parent after you create and finish working with it. Let me know if you are interested in the more complex version and I'm sure we can work through it here. Cheers!
Copy link to clipboard
Copied
I think it is not necessary to spend any more time on this given that from a utility perspective the initial solution works just fine and from an educational one we really would'nt be expanding on any new concepts. Thanks for your help.