Copy link to clipboard
Copied
Hi,
I have a script to auto create different colors of a sign. The first part runs fine. But, I then need to copy the path items to a new file/layer that uses an image for the background. When I run my script, it works great until it hits compound path items. When it does, it's filling in the enclosed text characters (see attached).
Here is the code I'm using for the copy routine:
// Open the appropriate BMS file to process
var bmsFile = File.openDialog('Select the Brushed Stainless base image to use...');
if(bmsFile != null) {app.open(bmsFile);};
var srcDoc = app.documents[1];
var targetDoc = app.documents[0].layers.add();
var _sel = app.activeDocument.selection[0];
for (i=0; i<srcDoc.pathItems.length-1; i++) {
srcDoc.pathItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
I'm using Illustrator 2020
Thanks in advance for any help
1 Correct answer
Oh, duh, this could only work when targeting a specific layer.
Assuming your document has one layer, or the art is on the 1st layer,
for (i = 0; i < srcDoc.layers[0].pageItems.length - 1; i++) {
if (srcDoc.layers[0].pageItems[i].typename == "PathItem" || srcDoc.layers[0].pageItems[i].typename == "CompoundPathItem") {
srcDoc.layers[0].pageItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
}
Explore related tutorials & articles
Copy link to clipboard
Copied
The last three lines would copy the pathItems in compoundPathItems, not the compoundPathItems themselves. To copy the compoundPathItems themselves:
for (var i = 0; i < srcDoc.compoundPathItems.length; i++) {
srcDoc.compoundPathItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
Copy link to clipboard
Copied
Thanks femkeblanco,
Definitely headed in the right direction. I replaced the pathItem lines with your code and got the 1st image. Soooo, how do I get both the pathItems and the compoundPathItems. If I use my code and yours I still get the 2nd image. I'm guessing there needs some sort of typename check but am unclear how to do that.
Copy link to clipboard
Copied
for (var i = 0; i < srcDoc.pathItems.length; i++) {
if (srcDoc.pathItems[i].parent.typename == "CompoundPathItem") {
continue;}
srcDoc.pathItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
for (var i = 0; i < srcDoc.compoundPathItems.length; i++) {
srcDoc.compoundPathItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
Copy link to clipboard
Copied
Big thanks femkeblanco. That loop caught the different item types, but when it got to the 2nd for loop the script changed to the previous layer (which is white) and added the compound path items there. It didn't add the compound items to the new brushed stainless layer that the path items had been added.
No idea how it could go back to the previous layer when targetDoc is the new layer.
Thanks again.
Copy link to clipboard
Copied
Assuming you're running the script while in the last created document, and replacing the whole code in your original post with the below, what happens?
var file1 = File.openDialog();
var pic1 = activeDocument.placedItems.add();
pic1.file = file1;
var srcDoc = app.documents[1];
var targetDoc = app.documents[0].layers.add();
var _sel = app.activeDocument.selection[0];
for (var i = 0; i < srcDoc.pathItems.length; i++) {
if (srcDoc.pathItems[i].parent.typename == "CompoundPathItem") {
continue;}
srcDoc.pathItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
for (var i = 0; i < srcDoc.compoundPathItems.length; i++) {
srcDoc.compoundPathItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
Copy link to clipboard
Copied
I get the following error message:
Copy link to clipboard
Copied
And if you have your srcDoc open and your targetDoc open and you run the script while in targetDoc? Also, there was an "app" missing in the second line in the snippet I posted above. So it should be:
var file1 = File.openDialog();
var pic1 = app.activeDocument.placedItems.add();
pic1.file = file1;
var srcDoc = app.documents[1];
var targetDoc = app.documents[0].layers.add();
var _sel = app.activeDocument.selection[0];
for (var i = 0; i < srcDoc.pathItems.length; i++) {
if (srcDoc.pathItems[i].parent.typename == "CompoundPathItem") {
continue;}
srcDoc.pathItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
for (var i = 0; i < srcDoc.compoundPathItems.length; i++) {
srcDoc.compoundPathItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
Copy link to clipboard
Copied
Thanks, femkeblanco.
Unfortunately, I get the same error as before after using the latest code snippet.
Copy link to clipboard
Copied
I don't know where to take this next. It's working for me.
Copy link to clipboard
Copied
Thankfs for trying femkeblano.
Just one last question. What's the purpose of this line in your code:
pic1.file = file1;
I don't see pic1 referenced anywhere in the rest of the code snippet.
Thanks
Copy link to clipboard
Copied
pic1 is a placedItem, the background picture, and file1 is the file containing the picture.
Copy link to clipboard
Copied
if you provide a sample file it could help speed things up.
Copy link to clipboard
Copied
Salut!
Peut-être tout simplement:
Si les éléments à dupliquer sont contenus dans un groupe, sélectionnez ce groupe et lancer la sript qui suit.
// JavaScript Document for Illustrator
var srcDoc = app.activeDocument;
var _sel = selection[0]; // alert(_sel)
var bmsFile = File.openDialog();
var targetDoc = app.open(bmsFile);
var targetLayer = targetDoc.layers.add();
_ sel.duplicate(targetLayer, ElementPlacement.PLACEATBEGINNING);
Copy link to clipboard
Copied
Change this:
for (i=0; i<srcDoc.pathItems.length-1; i++) {
srcDoc.pathItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
To this:
for (i = 0; i < srcDoc.pageItems.length - 1; i++) {
if (srcDoc.pageItems[i].typename == "PathItem" || srcDoc.pageItems[i].typename == "CompoundPathItem") {
srcDoc.pageItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
}
Copy link to clipboard
Copied
Silly-V
When I run your snippet, the copied compound paths are released.
Copy link to clipboard
Copied
Maybe this will help...here's the full script. The basics are this...I open Illustrator, select this script, open a product AI file to change the background color/text colors (there are more colors, but wanted a simple test), then open a brushed stainless background template AI file and copy the black text and braille dots over. Because the word 'ROUTE' has 2 compound paths - the R & O, it fails to properly copy them over. The enclosed areas are filled in.
Results:
Full script
#target illustrator
// Color array
var pColorNames = ['blue', 'black', 'white'];
var pRed = [ 0, 16, 255];
var pGreen = [ 75, 24, 255];
var pBlue = [135, 32, 255];
// Returns just file name
//alert('File name: ' + app.activeDocument.name);
// Returns full path & file name
//alert('File name: ' + app.activeDocument.fullName);
// Open the file to porcess
var myFile = File.openDialog('Select the product file to process...');
if(myFile != null) {app.open(myFile);};
// Get file name without full path and change extension to 'jpg'
var tempFileName = myFile.name.replace('.ai','.png');
// Get active document
var doc = app.activeDocument;
// Extract destination directory and save
var fullName = myFile.fsName;
var dFolder = fullName.substring(0, fullName.lastIndexOf("\\"));
var destFolder = dFolder.concat('\\images\\');
// Create images folder if it doesn't exist
var imgFolder = Folder(destFolder);
if (!imgFolder.exists) imgFolder.create();
//////////////////////////////////////////////////////////////////////
// Loop for WHITE raised signs
//////////////////////////////////////////////////////////////////////
var NewFileName;
for (x=0; x<=1; x++) {
workTheMagic();
};
////////////////////////////////////////////////////////////////////
// Loop for BLACK raised signs
////////////////////////////////////////////////////////////////////
var blkColor = new CMYKColor();
blkColor.cyan = 75;
blkColor.magenta = 68;
blkColor.yellow = 67;
blkColor.black = 90;
// Change raised objects to black
for (x=0; x<doc.pathItems.length; x++) {
if (doc.pathItems[x].fillColor.cyan == 0 && doc.pathItems[x].fillColor.magenta == 0 && doc.pathItems[x].fillColor.yellow == 0 && doc.pathItems[x].fillColor.black == 0 ) {
doc.pathItems[x].fillColor = blkColor;
};
};
for (x=2; x<=2; x++) {
workTheMagic();
};
//////////////////////////////////////////////////////////////////////////////////
// Special stuff for BRUSHED STAINLESS sign
//////////////////////////////////////////////////////////////////////////////////
// Open the appropriate BMS file to process
var bmsFile = File.openDialog('Select the Brushed Stainless base image to use...');
if(bmsFile != null) {app.open(bmsFile);};
var srcDoc = app.documents[1];
var targetDoc = app.documents[0].layers.add();
for (i=0; i<srcDoc.pathItems.length-1; i++) {
srcDoc.pathItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
// Change file name
newFileName = tempFileName;
newFileName = newFileName.replace('xxx', 'brushed-stainless');
// Create new export file
var tFile = new File(destFolder + '/' + newFileName);
// Export file as GIF to product image folder
exportToPNGFile (tFile);
/////////////////////////////////////////////////////////////////////////////////////
// Close documents
//////////////////////////////////////////////////////////////////////////////////
var aiDocument;
aiDocument = app.activeDocument;
aiDocument.close( SaveOptions.DONOTSAVECHANGES );
aiDocument = null;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
function workTheMagic() {
// Change file name
newFileName = tempFileName;
newFileName = newFileName.replace('xxx', pColorNames[x]);
// Create new export file
var tFile = new File(destFolder + '/' + newFileName);
// Change color of background
doc.pathItems[doc.pathItems.length-1].fillColor = makeColor(pRed[x], pGreen[x], pBlue[x]);
// Export file as GIF to product image folder
exportToPNGFile (tFile);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create new RGB color object
function makeColor(r,g,b) {
var c = new RGBColor();
c.red = r;
c.green = g;
c.blue = b;
return c;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
function exportToPNGFile(dest) {
if ( app.documents.length > 0 ) {
var exportOptions = new ExportOptionsPNG8();
// set PNG export options
exportOptions.antiAliasing = true;
exportOptions.transparency = true;
exportOptions.artBoardClipping = true;
exportOptions.horizontalScale = 100;
exportOptions.verticalScale = 100;
// export and save file
doc.exportFile ( dest, ExportType.PNG8, exportOptions );
}
}
Copy link to clipboard
Copied
Oh, duh, this could only work when targeting a specific layer.
Assuming your document has one layer, or the art is on the 1st layer,
for (i = 0; i < srcDoc.layers[0].pageItems.length - 1; i++) {
if (srcDoc.layers[0].pageItems[i].typename == "PathItem" || srcDoc.layers[0].pageItems[i].typename == "CompoundPathItem") {
srcDoc.layers[0].pageItems[i].duplicate(targetDoc, ElementPlacement.PLACEATBEGINNING);
}
}
Copy link to clipboard
Copied
Hey Silly-V,
Just used your last script change (big thanks) and this is what I got:
The weirdness continues...
Copy link to clipboard
Copied
Ok, found the final piece of the puzzle.
The text 'EXIT ROUTE' was grouped. I ungrouped it, re-ran your script and BOOM. All is good with the world.
Massive thanks for your time and patience.
Copy link to clipboard
Copied
You've very welcome, don't hesitate to ask away on here. Adobe team are doing some work to fix the lost links after a forum update, so now our experts on here can still make use of their linked bookmarks for some specific topics (hopefully).

