Copy link to clipboard
Copied
Hello all,
First off, I'm new to this and I've gone through tons of posts concerning this, but to no avail.
Here is what I'm trying to achieve:
That is the core of my script. I can create the three layers. I can paste what is selected. My issue is I can't paste into the new layers, and paste places the selected items in the center of the page. I don't want to duplicate the layer because there are things on the layer I don't want copied to the other 3 layers.
Another Issue I'd like to resolve is placing the 3 new layers above a layer called Original.
I haven't dug into this either, but how would I go about selecting all the pasted items in the 3 new layers as the last thing the script does?
Illustrator CC 2017 / PC
Thanks all.
//My added Layers;
sourceDoc = activeDocument;app.copy();
targetLayer = sourceDoc.layers.add();
targetLayer.name = "Layer1";redraw();
app.paste();
targetLayer = sourceDoc.layers.add();
targetLayer.name = "Layer2";
redraw();
app.paste();
targetLayer = sourceDoc.layers.add();
targetLayer.name = "Layer3";
redraw();
app.paste();
So that's where things get a little bit stickier since we're creating the layers inside a group(typo.. sorry) loop. But here's a simple way to set that up if you know ahead of time what you want the layers to be called. Now it's perfectly plausible to abstract this process so that you could determine the names at runtime via some kind of dialog or by reading an existing file etc, but that's getting a little bit into the weeds and is kind of off topic. (feel free to open a new discussion on that
...Copy link to clipboard
Copied
*EDIT*
I forgot to explain.
First of all, there's a differentiation between app.paste(); and the "pasteInPlace" functionality you're talking about. app.paste() just pastes the copied artwork in the center of the window (not necessarily the artboard). To my knowledge, there is no "app.pasteInPlace();" method. If you're using CS6+, you can use:
app.executeMenuCommand("pasteInPlace");
but for performance reasons, i tend to avoid the executeMenuCommand() method when possible.
Below i've illustrated the usage of the object.duplicate() method and passed in the argument "newLay" which represents the destination layer. the duplicate() method does not move the art, so by default, the art is duplicated "in place".
Hope this works well for you. Good luck. 😃
function test()
{
var docRef = app.activeDocument;
var layers = docRef.layers;
//how many new layers do you want?
var numLayers = 3;
var sel = docRef.selection;
//save the original layer to a variable so we can put it at the bottom of the list
var originalLayer = layers[0];
//create new layers
for(var x=0;x<numLayers;x++)
{
var newLay = layers.add();
//now copy the selection into the newly created layer
for(var y = sel.length-1;y >-1; y--)
{
var thisItem = sel
.duplicate(newLay); }
}
originalLayer.zOrder(ZOrderMethod.SENDTOBACK);
}
test();
Copy link to clipboard
Copied
Wow William, that was fast. Thank you so very much. Looking at your script, I don't think I would have gone that way. Yours looks clean and easy. I tested it, and it does what I want it to do. How can I name the layers something specific like Alpha, Beta and Delta? I can't really just rename them in the script because Layer11 might change to 12 or 13. I use 10 layers and Original is one of the layers, but sometimes it varies, usually one or two more.
I didn't mention this in my post but after this script, I will run another script to change numbers that are in a text file created by an Excel macro. Basically I have callouts to parts, numbered 1 to whatever, the second scripts changes those numbers I copied to the three new layers to other numbers like part numbers, customer numbers, and part ordering numbers. It's a time consuming manual process.
Hope this wasn't to confusing, I kinda jumped round.
Copy link to clipboard
Copied
So that's where things get a little bit stickier since we're creating the layers inside a group(typo.. sorry) loop. But here's a simple way to set that up if you know ahead of time what you want the layers to be called. Now it's perfectly plausible to abstract this process so that you could determine the names at runtime via some kind of dialog or by reading an existing file etc, but that's getting a little bit into the weeds and is kind of off topic. (feel free to open a new discussion on that topic)
But for the simple purposes of this specific snippet, we can use an array of layer names to use from inside the loop.
function test()
{
var docRef = app.activeDocument;
var layers = docRef.layers;
//how many new layers do you want?
var numLayers = 3;
//what are the names of the layers
//be careful that the number of names you put in here matches the
//numLayers variable above. If numLayers = 3, but you only put 2 layer
//names in this array, you'll get an error.
var layerNames = ["Alpha", "Beta", "Delta"];
var sel = docRef.selection;
//save the original layer to a variable so we can put it at the bottom of the list
var originalLayer = layers[0];
//create new layers
for(var x=0;x<numLayers;x++)
{
var newLay = layers.add();
newLay.name = layerNames
; //now copy the selection into the newly created layer
for(var y = sel.length-1;y >-1; y--)
{
var thisItem = sel
.duplicate(newLay); }
}
originalLayer.zOrder(ZOrderMethod.SENDTOBACK);
}
test();
Copy link to clipboard
Copied
William, two thumbs way up. My hats off to you sir. I struggled two days with this, but couldn't get anywhere.
Many thanks.
Copy link to clipboard
Copied
about 2 years ago i was in exactly the same spot. i spent days and days trying to debug the simplest of things. But thanks to all the helpful folks on this here forum, I clawed my way into a full time gig scripting illustrator.
Do come back at any time with your questions. There will always be somebody to help.
Copy link to clipboard
Copied
Thanks for the encouragement. I've been using Illustrator since the release of CS. Scripting is like a whole different world.
I did notice the send to back crashes. It doesn't work. It's not a deal breaker. I can manually move the 3 layers as needed. That only takes a second. It was really something on my 'wish list', but I'm happy with it either way.
Thanks again William.
Thanks to Pixxxel as well. I noticed I didn't send a thank you earlier.
Copy link to clipboard
Copied
Hmm. I don't get any errors on that functionality. Try restarting illustrator and running again.
What is the error that you get? Or does it literally crash illustrator?
Copy link to clipboard
Copied
Illustrator doesn't crash, or exit out, or give an error. I restarted and it does the same thing.
What I did is placed the new script on top of the other script that renumbers things. When I ran it, the renumbering didn't run. With some testing with alerts, I reduced it to the sendtoback line. When I comment out that line, the script works fine all the way through.
There are groups, but no compound items. I tested with 4 grouped items, and then 30. It didn't matter. The grouped items are a text box and multiple paths. Basically a number, a line, and a arrowhead (not the stroke arrowhead though). The groups are in the Original layer.
Thanks William
Copy link to clipboard
Copied
Did you try my snippet in meantime? Does this works for you?
Copy link to clipboard
Copied
Can you post the exact code that you're running? Sounds like there's a function call missing.
Copy link to clipboard
Copied
Sorry William, I can't post my code. Intellectual property I'm told. But I think I found the issue. For some reason the template I use has a locked item in that layer. When I run your exact code, on a newly opened template, it pops up with an error saying there is something locked. When I go through and make sure everything is unlocked, the script works fine, and the layering is as it should. I have to figure out what is locked in the template and make sure it's not when others use it with my script.
***Pixxxel - I tried your code and it worked the same as Williams. Didn't care for the toggling of the Paste Remembers Layers. I appreciate the effort though.
Copy link to clipboard
Copied
just to join the party, let's have the script find the layer named Original and let's create the new layers above it.
function test()
{
var docRef = app.activeDocument;
var layers = docRef.layers;
//how many new layers do you want?
var numLayers = 3;
//what are the names of the layers
//be careful that the number of names you put in here matches the
//numLayers variable above. If numLayers = 3, but you only put 2 layer
//names in this array, you'll get an error.
var layerNames = ["Alpha", "Beta", "Delta"];
var sel = docRef.selection;
//save the original layer to a variable so we can put it at the bottom of the list
var originalLayer = layers['Original']; // **edited
//create new layers
for(var x=0;x<numLayers;x++)
{
var newLay = layers.add();
newLay.name = layerNames
;
// move new layer above Original layer
newLay.move(originalLayer, ElementPlacement.PLACEBEFORE); // **added
//now copy the selection into the newly created layer
for(var y = sel.length-1;y >-1; y--)
{
var thisItem = sel
.duplicate(newLay); }
}
//originalLayer.zOrder(ZOrderMethod.SENDTOBACK); // **commented out
}
test();
Copy link to clipboard
Copied
Is there a way to turn this into a dialogue box when script runs so you can live edit the variables?
Copy link to clipboard
Copied
How many items are in your selection?
Are the selected items on the same layer?
Are there nested Groups or Compound items or Compound items in nested groups?
Copy link to clipboard
Copied
Hi michaelk97081953,
here is another way
// copySelectionToThreeNewLayers.jsx
alert("At first: disable Remember the Layers in the options of your layers palette"); // if so, you can comment out this alert
///////////////////////////////////////////////////////////////////////////
var numberOfNewLayers = 3;
///////////////////////////////////////////////////////////////////////////
// required: an opened document with one selected item as minimum
var aDoc = app.activeDocument;
var aSel = aDoc.selection;
app.executeMenuCommand ('copy');
for (i = 0; i < numberOfNewLayers; i++) {
pasteInLayer ();
}
function pasteInLayer () {
var aLay = aDoc.layers.add();
app.executeMenuCommand ('pasteInPlace');
return;
}
Have fun
Copy link to clipboard
Copied
That's a nice concise way to do it, pixxxel.
For future reference, app.pasteRemembersLayers is a settable property. So if you're doing something that requires a certain setting, you can use:
app.pasteRemembersLayers = true/false;
Copy link to clipboard
Copied
Hi williamadowling,
I know the property as well.
But in this simple snippet I don't use error management like
if ( documents.length …
if ( selection.length …
if ( app.pasteRemembersLayers …
And thats why the alert was the "best" solution in this case for me. Because of: no requirement to restore the original state in my script snippet.
But thanks.
And I'm so sorry. But Jive (the forum software) is buggy for me. Impossible for me to edit my own answers or mark answers as helpful or, or, or …