Copy link to clipboard
Copied
I use the following script to move an item with an opacity mask in illustrator.
var activeDoc = app.activeDocument;
var selectedItem = activeDoc.selection[0];
selectedItem.translate(-10, -10);
The item will move, but the opacity mask stays in the same place. I have confirmed that the opacity mask is locked with the item. I also only see a compound shape item in the data browser. The vector object that was used to create the opacity mask is no longer present in the data view. Any ideas?
My script actually ended up erroring out when an item you are trying to reselect has a hidden sub item. To work around this I actually used Silly-V's move dialog script to replace my alignment actions. The result was as follows. I confirmed that it works with hidden sub items and opacity masks.
function ActionManager(){
this.currentLoadedSets = [];
this.checkLoadedSets = function(setName){
if(this.currentLoadedSets.length > 0 && this.currentLoadedSets.join("").match(setName)){
...
Copy link to clipboard
Copied
Always state what version you are using. You say you are dealing with an Opacity Mask, but only see a Compound Shape in the data browser. So you also need to clearly state exactly what kind of construct you have created. Have you used a vector path as an Opacity Mask on a Compound Shape?
Assuming CS6:
A search of the CS6 Javascript Reference for "Opacity Mask" or "Compound Shape" returns no ocurrences. So that implies that the scripting engine simply does not support those kind of objects. So boil the problem down to its essence and do a little testing to figure out what the scripting engine is "thinking."
1. New document.
2. Create a single closed path.
3. Create a filled rectangle overlapping it.
4. Select both.
5. Transparency palette: Make Mask.
6. Select the resulting object. Note what kind of object is selected in the Layers palette. To the program, it's listed as a Path, not an "Opacity Mask Group" or any other special construct.
If you add an alert(selectedItem.itemtype) to your script, when you run the script you will see what kind of object the scripting engine considers your seletedItem to be. In the above scenario, the itemtype for selectedItem is a "PathItem".
Dismissing the alert and letting the script complete, the PathItem moves, but its Opacity Mask does not.
7. Transparency palette: Release the mask.
8. Pathfinder palette: AltClick one of the ShapeModes buttons.
9. Note what kind of object is selected in the Layers palette. To the program, it's listed as a Compound Shape.
10. Run the script. The alert will tell you that the itemtype of selectedItem is "PluginItem".
Dismissing the alert and letting the script complete, the whole Compound Shape moves, including all its subpaths, so its effective "mask" moves with it.
If you add an alert(pageItems.length) to your script, you will see how many objects are considered to be in the document. In both scenarios, the count will be 1.
If you add an alert(pathItems.length) to your script, you will see how many paths are considered to be in the document. In the first scenario, there will be 1. (So the scripting engine does not include the path that was used as an Opacity Mask to be among its pathItems.) In the second scenario, the alert will return 0. So the scripting engine does not consider the elements of a the PluginItem to be pathItems. It treats the PluginItem as a kind of "foreign object."
So I don't see this as a bug. The Javascript model does not cover every feature, object, and command in the program.
So in the first scenario, the path which has an opacity mask applied is considered a path, and the Javascript engine references just the path and moves just the path. It doesn't "know anything about" an Opacity Mask. This kind of makes sense, because an Opacity Mask does not have to be just one single path. It can be pretty much anything; paths, raster images, live text. It can even be a group including all of those kinds of objects. Apply such a Group to a single path as an Opacity Mask, and the Layers palette will still list the construct as a path, and the Javascript engine will still address just the pathItem.
In the second scenario, it's clear that Compound Shapes created by the Pathfinder palette are constructs created by a plugin (an external program). So it also makes sense in that it is treated as a whole object, much like a placed external EPS or other foreign object.
JET
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Always like JET's detailed explanation.
A dirty workaround can be like this:
var activeDoc = app.activeDocument;
var selectedItem = activeDoc.selection[0];
var gb = selectedItem.geometricBounds;
var cx = gb[0] + (gb[2] - gb[0]) / 2;
var cy = gb[1] + (gb[3] - gb[1]) / 2;
activeDoc.views[0].centerPoint = [cx, cy];
app.cut();
activeDoc.views[0].centerPoint = [cx - 10, cy - 10];
app.paste();
Copy link to clipboard
Copied
And I love dirty workarounds! The dirtier the better!
In this case if CS6+ is being used, we can use the move dialog via actions to move those opacity masks.
*Interestingly, the transform effect also fails to move the opacity masks.
#target illustrator
function test(){
/* ========================================= ACTION MANAGER ============================================ */
function ActionManager(){
this.currentLoadedSets = [];
this.checkLoadedSets = function(setName){
if(this.currentLoadedSets.length > 0 && this.currentLoadedSets.join("").match(setName)){
return true;
} else {
return false;
}
};
this.alertLoadedSets = function(){
var arr = [];
for (var i = 0; i < this.currentLoadedSets.length; i++) {
arr.push(this.currentLoadedSets);
}
alert(arr.join("\n"));
};
this.loadSet = function(setString, setName){
this.removeSet(setName);
var aiaFile;
if(typeof setString == "string"){
aiaFile = new File('~/ScriptAction.aia');
aiaFile.open("w");
aiaFile.write(setString);
aiaFile.close();
app.loadAction(aiaFile);
this.currentLoadedSets.push(setName);
aiaFile.remove();
return true;
} else if(setString instanceof File){
aiaFile = setString;
if(aiaFile.exists){
app.loadAction(aiaFile);
this.currentLoadedSets.push(setName);
return true;
} else {
alert("File '" + decodeURI(aiaFile) + "' was not found!");
return false;
}
}
};
this.playAction = function(actionName, setName, force){
if(this.checkLoadedSets(setName) || (force === true)){
app.doScript(actionName, setName);
return true;
} else {
if(typeof this.debugLevel != "undefined" && this.debugLevel === true){
alert("ActionManager: the set '" + setName + "' is not found to be currently loaded.");
}
return false;
}
};
this.removeSet = function(setName){
var errorFlag = false;
while(!errorFlag){
try {
app.unloadAction(setName, "");
} catch (e) {
errorFlag = true;
}
}
var arr = [];
var nm;
for (var i = 0; i < this.currentLoadedSets.length; i++) {
nm = this.currentLoadedSets;
if(nm != setName){
arr.push(nm);
}
};
this.currentLoadedSets = arr;
};
};
/* ================================================================================================================ */
var MOVE_VALUE = 100;
var actionString = [
"/version 3",
"/name [ 8",
" 4d6f76654974656d",
"]",
"/isOpen 1",
"/actionCount 1",
"/action-1 {",
" /name [ 8",
" 6d6f76654974656d",
" ]",
" /keyIndex 0",
" /colorIndex 0",
" /isOpen 1",
" /eventCount 1",
" /event-1 {",
" /useRulersIn1stQuadrant 0",
" /internalName (adobe_move)",
" /localizedName [ 4",
" 4d6f7665",
" ]",
" /isOpen 0",
" /isOn 1",
" /hasDialog 1",
" /showDialog 0",
" /parameterCount 3",
" /parameter-1 {",
" /key 1752136302",
" /showInPalette -1",
" /type (unit real)",
" /value " + MOVE_VALUE + (MOVE_VALUE.toString().indexOf(".") == -1 ? ".0" : ""), // has to be a decimal number to work
" /unit 592476268",
" }",
" /parameter-2 {",
" /key 1987339116",
" /showInPalette -1",
" /type (unit real)",
" /value -0.0",
" /unit 592476268",
" }",
" /parameter-3 {",
" /key 1668247673",
" /showInPalette -1",
" /type (boolean)",
" /value 0",
" }",
" }",
"}"
].join("\n");
var doc = app.activeDocument;
var actionManager = new ActionManager();
actionManager.loadSet(actionString, "MoveItem");
var p = doc.pageItems[0];
//p.translate(100, 0); // doesn't move opacity mask with art.
p.selected = true;
actionManager.playAction("moveItem", "MoveItem");
actionManager.removeSet("MoveItem");
}
test();
Copy link to clipboard
Copied
The version I'm working in is CC 2015.2.1. I am working with a vector object as the opacity mask over a vector object.
There are some great ideas here on how to work around it and using the move dialog seems like it would be the best workaround.
I was able to solve it another way. My final goal was to align the "art" with a "cut line". Finding that I could call actions with the script I did the following. It gathers the "cut lines" and finds the "art". Then, because you cannot select a key object for aligning with a script it copies the cut line and makes another in the equal but opposite direction of the art so that when it aligns, it aligns to the original cut line. This script allows you to have multiple cut lines and place the art in them.
var selectedItems = app.activeDocument.selection;
var cutLines = [];
var artItem;
for (var i = 0; i<selectedItems.length; i++){
if (selectedItems.layer.name == 'DRT copy'){
cutLines.push(selectedItems)
}else{
artItem = selectedItems;
}
selectedItems.selected = false;
}
for (var e = 0; e<cutLines.length; e++){
var cLeft = cutLines
var cTop = cutLines
cutLines
var offsetLeft = cLeft - artItem.pageItems[0].left;
var offsetTop = cTop - artItem.pageItems[0].top;
app.copy();
app.paste()
var offsetCut = app.activeDocument.selection[0];
offsetCut.left = cLeft + offsetLeft;
offsetCut.top = cTop + offsetTop;
offsetCut.selected = false;
artItem.selected = true;
//app.doScript('Align Vertical', 'DevActions');
app.copy();
offsetCut.selected = true;
cutLines
app.doScript('Lock Pattern', 'DevActions');
app.doScript('Align Horizontal', 'DevActions');
app.doScript('Align Vertical', 'DevActions');
app.doScript('Align Horizontal', 'DevActions');
app.doScript('Align Vertical', 'DevActions');
offsetCut.remove();
artItem.selected = false;
cutLines
app.paste();
artItem = app.activeDocument.selection[0];
artItem.selected = false;
if(e+1 == cutLines.length){
artItem.selected = true;
if(confirm('Are you done setting this peice?')){
artItem.remove();
}
}
}
Copy link to clipboard
Copied
Hye I think your method is much like what I consider to be the best method to move things around in a document when using actions.
I call it "traversing document with artboard" and it entails repeatedly fitting an artboard to different artwork bounds and using the alignment actions to center-align the needed items to the target artboard.
Too bad I can't figure out how to change the align-to-artboard/selection preference.
I tried this, but no changes appeared to my UI:
app.preferences.setIntegerPreference("plugin/Align/StickyAlignOption", 2);
Copy link to clipboard
Copied
My script actually ended up erroring out when an item you are trying to reselect has a hidden sub item. To work around this I actually used Silly-V's move dialog script to replace my alignment actions. The result was as follows. I confirmed that it works with hidden sub items and opacity masks.
function ActionManager(){
this.currentLoadedSets = [];
this.checkLoadedSets = function(setName){
if(this.currentLoadedSets.length > 0 && this.currentLoadedSets.join("").match(setName)){
return true;
} else {
return false;
}
};
this.alertLoadedSets = function(){
var arr = [];
for (var i = 0; i < this.currentLoadedSets.length; i++) {
arr.push(this.currentLoadedSets);
}
alert(arr.join("\n"));
};
this.loadSet = function(setString, setName){
this.removeSet(setName);
var aiaFile;
if(typeof setString == "string"){
aiaFile = new File('~/ScriptAction.aia');
aiaFile.open("w");
aiaFile.write(setString);
aiaFile.close();
app.loadAction(aiaFile);
this.currentLoadedSets.push(setName);
aiaFile.remove();
return true;
} else if(setString instanceof File){
aiaFile = setString;
if(aiaFile.exists){
app.loadAction(aiaFile);
this.currentLoadedSets.push(setName);
return true;
} else {
alert("File '" + decodeURI(aiaFile) + "' was not found!");
return false;
}
}
};
this.playAction = function(actionName, setName, force){
if(this.checkLoadedSets(setName) || (force === true)){
app.doScript(actionName, setName);
return true;
} else {
if(typeof this.debugLevel != "undefined" && this.debugLevel === true){
alert("ActionManager: the set '" + setName + "' is not found to be currently loaded.");
}
return false;
}
};
this.removeSet = function(setName){
var errorFlag = false;
while(!errorFlag){
try {
app.unloadAction(setName, "");
} catch (e) {
errorFlag = true;
}
}
var arr = [];
var nm;
for (var i = 0; i < this.currentLoadedSets.length; i++) {
nm = this.currentLoadedSets;
if(nm != setName){
arr.push(nm);
}
};
this.currentLoadedSets = arr;
};
};
/* ================================================================================================================ */
var selectedItems = app.activeDocument.selection;
var cutLines = [];
var artItem;
for (var i = 0; i<selectedItems.length; i++){
if (selectedItems.layer.name == 'DRT copy'){
cutLines.push(selectedItems)
selectedItems.selected=false;
}else{
artItem = selectedItems;
}
}
for (var e = 0; e<cutLines.length; e++){
var cLeft = cutLines
var cTop = cutLines
var offsetX = cLeft - artItem.pageItems[0].left;
var offsetY = cTop - artItem.pageItems[0].top;
$.writeln("X: " + offsetX + " Y: " + offsetY);
app.copy();
var actionString = [
"/version 3",
"/name [ 8",
" 4d6f76654974656d",
"]",
"/isOpen 1",
"/actionCount 1",
"/action-1 {",
" /name [ 8",
" 6d6f76654974656d",
" ]",
" /keyIndex 0",
" /colorIndex 0",
" /isOpen 1",
" /eventCount 1",
" /event-1 {",
" /useRulersIn1stQuadrant 0",
" /internalName (adobe_move)",
" /localizedName [ 4",
" 4d6f7665",
" ]",
" /isOpen 0",
" /isOn 1",
" /hasDialog 1",
" /showDialog 0",
" /parameterCount 3",
" /parameter-1 {",
" /key 1752136302",
" /showInPalette -1",
" /type (unit real)",
" /value " + offsetX, // has to be a decimal number to work
" /unit 592476268",
" }",
" /parameter-2 {",
" /key 1987339116",
" /showInPalette -1",
" /type (unit real)",
" /value " + offsetY,
" /unit 592476268",
" }",
" /parameter-3 {",
" /key 1668247673",
" /showInPalette -1",
" /type (boolean)",
" /value 0",
" }",
" }",
"}"
].join("\n");
var actionManager = new ActionManager();
actionManager.loadSet(actionString, "MoveItem");
actionManager.playAction("moveItem", "MoveItem");
actionManager.removeSet("MoveItem");
app.paste();
artItem = app.activeDocument.selection[0];
if(e+1 == cutLines.length){
if(confirm('Are you done setting this peice?')){
artItem.remove();
}
}
}
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi @Ancolie94
This has nothing to do with a script.
We also need the layer panel or a sample file to see where the transparency has been applied.
A shot in the dark:
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Please show more of the layers panel (parent groups and layers)
Or upload the file on a hoster of your choice and link to here.
Copy link to clipboard
Copied
You're right, I found, it's applied on the group 🙂 Thank you so much for your help!