Skip to main content
Ku11
Inspiring
January 3, 2022
Answered

How to change the StrokeCap of all objects in a few layers

  • January 3, 2022
  • 1 reply
  • 1209 views

hello,everyone.

i want to change the strokeCap of all objects in a particular layer.

var document = app.activeDocument;
var allLayers = app.activeDocument.layers; 
var testLayer = ["a", "b"];


function lineFormat(LayerName) {
    //Select objects in layer
    document.activeLayer = document.layers[LayerName]; 
    //document.activeLayer.hasSelectedArtwork = true; 
    //Change Style
    document.activeLayer.pathItems.stroked = true;    // open stroke
    document.activeLayer.pathItems.strokeCap = StrokeCap.BUTTENDCAP;//ROUNDENDCAP, PROJECTINGENDCAP
    document.activeLayer.pathItems.strokeJoin = StrokeJoin.ROUNDENDJOIN;//BEVELENDJOIN, MITERENDJOIN

    //Deselect objects in layer
    //document.activeLayer.hasSelectedArtwork = false;
}


for (var i = 0, il = allLayers.length; i < il; i++) {
    var curLayer = allLayers[i]
    if (curLayer = testLayer[i]) {
        //if layer name found
        lineFormat(testLayer[i]) 
    }
}   

then,i wrote the code as I understood it, but nothing happened to it for now, I don't know how to fix this code

Anyone can help me?

 

 

This topic has been closed for replies.
Correct answer Inventsable

Here is the test file

https://file.io/mbKXVsChYCgn


Sorry, had a typo and a faulty condition. Serves me right for so confidently offering recursion thinking I had cracked it so easily ha, I've verified the below on your file:

 

var targetLayers = ["Test"];

function getAllPathItems(parent) {
  var list = [];
  for (var i = 0; i < parent.pageItems.length; i++) {
    var item = parent.pageItems[i];
    if (item.pageItems && item.pageItems.length)
      list = [].concat(list, getAllPathItems(item));
    else if (/path/i.test(item.typename) && !/compound/i.test(item.typename))
      list.push(item);
  }
  return list;
}

function getLayer(layerName) {
  try {
    return app.activeDocument.layers.getByName(layerName);
  } catch (err) {
    return null;
  }
}

function restyleAllPathItemsWithin(layers) {
  app.selection = null;
  for (var i = 0; i < layers.length; i++) {
    var layer = getLayer(layers[i]);
    if (!layer) continue;
    else {
      var list = getAllPathItems(layer);
      for (var index = 0; index < list.length; index++) {
        var pathItem = list[index];
        pathItem.stroked = true; // open stroke
        pathItem.strokeCap = StrokeCap.BUTTENDCAP; //ROUNDENDCAP, PROJECTINGENDCAP
        pathItem.strokeJoin = StrokeJoin.ROUNDENDJOIN; //BEVELENDJOIN, MITERENDJOIN
      }
    }
  }
}

restyleAllPathItemsWithin(targetLayers);

 I'm not sure if you're wanting to target only specific layers by name or if you're just trying to change all document strokes -- you could do that though. If the goal is to change all strokes we could just feed a list of all the layers into the main function, and it might be easier to choose which layers (or names of annotation like "LWPOLYLINE") to exclude rather than include. Or target all "LINE" group children, etc.

1 reply

Inventsable
Legend
January 3, 2022

Hello, consider this:

 

var document = app.activeDocument;
var allLayers = app.activeDocument.layers;
var testLayers = ["Test"];

// Why do this? Because if we query a layer name that doesn't exist, it causes silent failure.
function getLayer(layerName) {
    try {
        return document.layers.getByName(layerName);
    } catch(err) {
        return null;
    }
}

function restyleAllPathItemsWithin(layers) {
    // An alternative to deselect all artwork, though it shouldn't actually matter here
    // because we can change the strokes regardless of whether other art is selected
    app.selection = null;

    // Iterate through our layer list:
    for (var i = 0; i < layers.length; i++) {
        // Get our target layer:
        var layer = getLayer(layers[i]);

        // If a layer wasn't found or there are no items to restyle, continue looping:
        if (!layer || !layer.pathItems.length) continue;
        else {
            // Layer.pathItems is a collection of objects, not a single one.
            // To restyle any given object, we have to iterate over them individually:
            for (var index = 0; index < layer.pathItems.length; index++) {
                var pathItem = layer.pathItems[index];
                pathItem.stroked = true;    // open stroke
                pathItem.strokeCap = StrokeCap.BUTTENDCAP;//ROUNDENDCAP, PROJECTINGENDCAP
                pathItem.strokeJoin = StrokeJoin.ROUNDENDJOIN;//BEVELENDJOIN, MITERENDJOIN
            }
        }
    }
}

restyleAllPathItemsWithin(testLayers);

Essentially you have everything correct here, but the issue is that you're trying to assign properties to an Array-like collection (pathItems) rather than one entry of that collection (i.e., pathItems[0]).

Ku11
Ku11Author
Inspiring
January 3, 2022

thanks you for you help!!!but it seems that the straight lines I import from DWG still need to be ungrouped before they work.

Ku11
Ku11Author
Inspiring
January 3, 2022

Sorry, had a typo and a faulty condition. Serves me right for so confidently offering recursion thinking I had cracked it so easily ha, I've verified the below on your file:

 

var targetLayers = ["Test"];

function getAllPathItems(parent) {
  var list = [];
  for (var i = 0; i < parent.pageItems.length; i++) {
    var item = parent.pageItems[i];
    if (item.pageItems && item.pageItems.length)
      list = [].concat(list, getAllPathItems(item));
    else if (/path/i.test(item.typename) && !/compound/i.test(item.typename))
      list.push(item);
  }
  return list;
}

function getLayer(layerName) {
  try {
    return app.activeDocument.layers.getByName(layerName);
  } catch (err) {
    return null;
  }
}

function restyleAllPathItemsWithin(layers) {
  app.selection = null;
  for (var i = 0; i < layers.length; i++) {
    var layer = getLayer(layers[i]);
    if (!layer) continue;
    else {
      var list = getAllPathItems(layer);
      for (var index = 0; index < list.length; index++) {
        var pathItem = list[index];
        pathItem.stroked = true; // open stroke
        pathItem.strokeCap = StrokeCap.BUTTENDCAP; //ROUNDENDCAP, PROJECTINGENDCAP
        pathItem.strokeJoin = StrokeJoin.ROUNDENDJOIN; //BEVELENDJOIN, MITERENDJOIN
      }
    }
  }
}

restyleAllPathItemsWithin(targetLayers);

 I'm not sure if you're wanting to target only specific layers by name or if you're just trying to change all document strokes -- you could do that though. If the goal is to change all strokes we could just feed a list of all the layers into the main function, and it might be easier to choose which layers (or names of annotation like "LWPOLYLINE") to exclude rather than include. Or target all "LINE" group children, etc.


that cool !!!and you are right, we can narrow down the scope of the code to work