问题
TLDR: I need to run Pathfinder > Crop
on all art in a file that has a clipping mask applied but can’t seem to get Crop to fire correctly.
UPDATE: After HOURS of chipping away at this I came to realize that the Crop option in the main menu (“Effect > Pathfinder > Crop”) does something entirely different than the Crop button in the Pathfinder panel. I’m using app.executeMenuCommand('Live Pathfinder Crop');
to crop the image, but this apparently fires the menu action. I need to access the crop action from the Pathfinder panel.
I have several layers of art that have clipping masks applied. The masks cause several issues in the end product, so I need to:
- Loop through each layer;
- Copy the contents to a new layer (optional maybe, but working with the original layers seemed very problematic);
- Loop through all groups in the layer to find any with
pathItem[0].clipping === true
; - Remove the clipping mask;
- Select and group everything that’s left on the layer;
- Create a rectangle on top of the art that has the same dimensions and coordinates that the clipping mask had;
- Select both the group and the rectangle; and
- Run
Outline Stroke
,Pathfinder > Crop
, andExpand
on the selected items.
Here is my script as it stands.
#target illustrator
var doc = app.activeDocument;
var tempName = '-temp';
function cropGroups() {
var layers = doc.layers;
var layerCount = layers.length;
// Lock all layers
for (var i = 0; i < layerCount; i++) {
layers[i].locked = true;
}
for (var i = 0; i < layerCount; i++) {
var layer = layers[i];
// Create new empty layer
var layerCopy = layers.add();
layerCopy.name = layer.name + tempName;
// Copy all objects from original layer to new layer
var pageItems = layer.pageItems;
var pageItemCount = pageItems.length;
for (var a = pageItemCount - 1; a >= 0; a--) {
pageItems[a].duplicate(layerCopy, ElementPlacement.PLACEATBEGINNING);
}
// Loop through the new layer’s groups
var groups = layerCopy.groupItems;
var totalGroups = groups.length;
for (var g = totalGroups - 1; g >= 0; g--) {
var group = groups[g];
// Ensure group isn’t empty and has a clipping mask
if (group.pathItems.length && group.pathItems[0].clipping) {
var clippingMask = group.pathItems[0];
var clippingRect = { left: clippingMask.left, top: clippingMask.top, height: clippingMask.height, width: clippingMask.width };
clippingMask.remove();
// Time to start the selection dance…
layerCopy.hasSelectedArtwork = true;
// Add selected items to a new group
var selectedItems = doc.selection;
var cropGroup = layerCopy.groupItems.add(); // Create empty group
for (var s = 0; s < selectedItems.length; s++) {
selectedItems[s].move( cropGroup, ElementPlacement.PLACEATEND ); // Add all selected items to the new group
}
doc.selection = null;
// Create a new rectangle that matches the size of the clipping mask
var tile = layerCopy.pathItems.rectangle(clippingRect.top, clippingRect.left, clippingRect.width, clippingRect.height);
var tileColor = new RGBColor;
tile.fillColor = tileColor;
tile.move(layerCopy, ElementPlacement.PLACEATBEGINNING);
// Select all layer art again
// layerCopy.hasSelectedArtwork = true;
tile.selected = true;
cropGroup.selected = true;
// Live Pathfinder Crop
app.executeMenuCommand('OffsetPath v22');
app.executeMenuCommand('Live Pathfinder Crop');
app.executeMenuCommand('expandStyle');
doc.selection = null;
}
}
// Return the layer name back to it’s original
layerCopy.name = layerCopy.name.replace(tempName, '');
// Remove the original layer
layer.locked = false;
layer.remove();
}
}
cropGroups();
It technically works well, but the cropping action isn’t at all what I expect. When I run the script without executeMenuCommand
lines, then run those commands manually in Illustrator everything gets cropped perfectly.
What am I missing here?
SOLUTION:
It seems that the “Crop” function from the actual Pathfinder panel isn’t available via ExtendScript, so I ended up making an action that handles only that task and saving it as a file. Then I call it for each Clipping Mask in the document:
function cropTiles(cb) {
// Load the action file relative to the location of this script
var thisFile = new File($.fileName);
var basePath = thisFile.path;
app.unloadAction('action','');
app.loadAction(new File(basePath + '/actions/action.aia'));
doc.selection = null;
app.executeMenuCommand("Clipping Masks menu item");
var thisClipItem;
var esc = 50;
while (doc.selection.length != 0 && esc > 0) {
esc--;
thisClipItem = doc.selection[0];
doc.selection = null;
thisClipItem.parent.selected = true;
app.executeMenuCommand('Live Outline Stroke');
app.doScript('Crop Gallery Tile', 'action');
app.executeMenuCommand('expandStyle');
doc.selection = null;
app.executeMenuCommand("Clipping Masks menu item");
}
cb && typeof cb === 'function' && cb();
}
回答1:
Yes, you can execute Pathfinder > Crop via creating Action and running it from code.
- open Action panel and create new Action Set, for example PathfinderSet
- create new empty Action, for example act-crop
- start recording and record one step - applying pathfinder crop to some objects
- open Action context menu and save PathfinderSet to file, for example 'pathfinder-actions.aia'
Run this action from script:
var fAction = new File('pathfinder-actions.aia');
app.loadAction(fAction);
app.doScript("act-crop", "PathfinderSet", false);
app.unloadAction("PathfinderSet","");
来源:https://stackoverflow.com/questions/42912799/can-i-execute-pathfinder-crop-from-the-pathfinder-panel-and-not-the-effects