Copy link to clipboard
Copied
I'm brand new to ExtendScript, but know my way around expressions pretty well. I have a situation where I have mulitple AI vector layers in a comp that I want to convert to shape layers then add an expression to the stroke property of each. I've read some guides, posts, and the scripting reference, but am finding it hard getting any where.
The steps I would like to put in the script are:
- Take the selected layer AI vector layer and create a shape layer from it (i.e. Create > Create paths from vector layer). I know I can use app.executeCommand(3973) for this.
- Remove the " Outlines" text from the new layer name.
- On the new shape layer, for all objects in all groups, add the following expression to the Stroke Width property:I'm hoping some smart scripters out there can get me started.scaler = transform.scale[0];sWidth = thisComp.layer("control").effect("Stroke Width")("Slider").value;sWidth * (100/scaler);
Thanks!
1 Correct answer
I haven't tested this, but I'd try wrapping the stroke access in a try/catch and just skip that property (with continue) if there's an error:
myGroup = myContents.property(i);
try{
myStrokeWidth = myGroup.property("ADBE Vectors Group").property("ADBE Vector Graphic - Stroke").property("ADBE Vector Stroke Width");
myStrokeWidth.expression = myExpr;
}catch (err){
continue;
}
Copy link to clipboard
Copied
This may not be exactly right for your situation but it should get you headed in the right direction:
function test(){
var myExpr = 'scaler = transform.scale[0];\r' +
'sWidth = thisComp.layer("control").effect("Stroke Width")("Slider").value;\r' +
'sWidth * (100/scaler);';
var myComp = app.project.activeItem;
var myLayers = myComp.selectedLayers;
if (myLayers.length == 0){
alert("No layer selected.");
return;
}
var myLayer = myLayers[0];
var oldName = myLayer.name;
var oldIndex = myLayer.index;
app.executeCommand(3973);
var newLayer = myComp.layer(oldIndex);
newLayer.name = oldName;
var myContents = newLayer.property("ADBE Root Vectors Group");
var myGroup;
var myStrokeWidth;
for (var i = 1; i <= myContents.numProperties; i++){
myGroup = myContents.property(i);
myStrokeWidth = myGroup.property("ADBE Vectors Group").property("ADBE Vector Graphic - Stroke").property("ADBE Vector Stroke Width");
myStrokeWidth.expression = myExpr;
}
}
test();
Copy link to clipboard
Copied
Thanks Dan. This works great and I was able to understand it well enough to make some minor modifications for my specific needs. I do have a couple of questions to clarify what's going on.
- Is the following a correct correlation of the layer properties to the ExtendScript equivalent for a shape layer?
- Contents = property("ADBE Root Vectors Group")
- Group = property("ADBE Vectors Group")
- Stroke = property("ADBE Vector Graphic - Stroke")
- If I had multiple Strokes applied to a Group (Stroke 1, Stroke 2, Stroke 3, etc.), how would I target a specific one (say Stroke 2)? Would I use:
- property("ADBE Vector Graphic - Stroke"[2])
Copy link to clipboard
Copied
OK, so here's the same path to Stroke Width in both match name format:
layer("test.ai").property("ADBE Root Vectors Group").property("ADBE Vector Group").property("ADBE Vectors Group").property("ADBE Vector Graphic - Stroke").property("ADBE Vector Stroke Width")
and regular name format:
layer("test.ai").property("Contents").property("Group 1").property("Contents").property("Stroke 1").property("Stroke Width")
The problem with match names, is when you have multiples of the same element, they have the same name, so you might have to go to index numbers, so in this case,
.property("ADBE Vector Graphic - Stroke")
would become:
.property(4)
or something like that. Or you could just use the regular names, which might be:
.property("Stroke 2")
It's hard to be definitve because a lot depends on the structure of that particular shape layer--how many levels of contents, groups, etc.
Copy link to clipboard
Copied
Fabulous. Thanks for the detailed description, Dan.
Copy link to clipboard
Copied
I've been working with this script for a while and it's been running great. However, this week I've been receiving an error on some files: "Unable to execute script at line 29. Null is not an object."
After some investigation of the script and files, I see that some objects in the AI file are filled but do not have strokes. When the script converts this to the shape in AE, the AE shape layer group only contains a fill and no stroke. So the script gives an error and stops processing the rest of the groups.
I tried adding an if/then/else statemement to the for loop at the end as follows :
for (var i = 1; i <= myContents.numProperties; i++){
if (myStrokeWidth == null) {i = i + 1} else { // If there is no stroke, move to next group;
myGroup = myContents.property(i);
myStrokeWidth = myGroup.property("ADBE Vectors Group").property("ADBE Vector Graphic - Stroke").property("ADBE Vector Stroke Width");
myStrokeWidth.expression = myExpr;
}
}
However, this doesn't work and doesn't add the expression to any of the groups with strokes. What am I missing in this error checking?
Thanks
Copy link to clipboard
Copied
I haven't tested this, but I'd try wrapping the stroke access in a try/catch and just skip that property (with continue) if there's an error:
myGroup = myContents.property(i);
try{
myStrokeWidth = myGroup.property("ADBE Vectors Group").property("ADBE Vector Graphic - Stroke").property("ADBE Vector Stroke Width");
myStrokeWidth.expression = myExpr;
}catch (err){
continue;
}
Copy link to clipboard
Copied
That worked. Thanks Dan!

