Skip to main content
Inspiring
December 21, 2022
Answered

How to Get a Script to work on multiple lines of Art

  • December 21, 2022
  • 2 replies
  • 464 views

I have a script that adjusts a single line of selected shapes. 
Currently, if there are 2 or more vertically stacked lines of shapes I  run the script for each line.  How can I structure a script so that I can select all of the lines and have it loop through each line?  My goal is to select everything at once and run my script 1 time.

https://community.adobe.com/t5/illustrator-discussions/adjust-spacing-without-adjusting-other-spacing/m-p/13349875#M343853

Thank you!

This topic has been closed for replies.
Correct answer Kernzy

Hey Bryan,

 

The script is used to group page items on a line. You can adjust the threshold however you may need. This gets the selected page items in the document and sorts them by their vertical position on the page. It then loops through all the selected page items, and for each page item, it checks if it should be added to a new group or not. If the page item is the first in a new group or if it is more than 18 points away from the previous page item in the group, then it creates a new group. Otherwise, it adds the page item to the current group. At the end of the loop, all the selected page items should be organized into groups based on their vertical position on the page.

// Set the Y coordinate threshold for grouping page items
var threshold = 18;

// Get the active document
var doc = app.activeDocument;

// Get the selected page items
var selectedPageItems = doc.selection;

// Sort the selected page items by their Y coordinate
selectedPageItems.sort(function(a, b) {
  var bottomLeftPointA = a.geometricBounds[3];
  var bottomLeftPointB = b.geometricBounds[3];
  return bottomLeftPointA - bottomLeftPointB;
});

// Create a variable to store the current group
var currentGroup = null;

// Loop through all selected page items
for (var i = 0; i < selectedPageItems.length; i++) {
  var pageItem = selectedPageItems[i];

  // Get the bottom-left point of the page item
  var bottomLeftPoint = pageItem.geometricBounds[3];

  // Check if the page item should be added to a new group
  if (currentGroup == null || bottomLeftPoint - currentGroup.geometricBounds[3] > threshold) {
    // Create a new group
    currentGroup = doc.groupItems.add();
  }

  // Add the page item to the current group
  pageItem.move(currentGroup, ElementPlacement.PLACEATEND);
}

 This doesn't solve your issue but may lead to a way that can integrate your previous script into this one. I could see this being done by applying your script to each group(line) in your selection, but I can not figure out how to get that loop to work. This is similar to @femkeblanco' script that @m1b pointed out, but I would like to see their take on this!

2 replies

Kernzy
KernzyCorrect answer
Inspiring
December 22, 2022

Hey Bryan,

 

The script is used to group page items on a line. You can adjust the threshold however you may need. This gets the selected page items in the document and sorts them by their vertical position on the page. It then loops through all the selected page items, and for each page item, it checks if it should be added to a new group or not. If the page item is the first in a new group or if it is more than 18 points away from the previous page item in the group, then it creates a new group. Otherwise, it adds the page item to the current group. At the end of the loop, all the selected page items should be organized into groups based on their vertical position on the page.

// Set the Y coordinate threshold for grouping page items
var threshold = 18;

// Get the active document
var doc = app.activeDocument;

// Get the selected page items
var selectedPageItems = doc.selection;

// Sort the selected page items by their Y coordinate
selectedPageItems.sort(function(a, b) {
  var bottomLeftPointA = a.geometricBounds[3];
  var bottomLeftPointB = b.geometricBounds[3];
  return bottomLeftPointA - bottomLeftPointB;
});

// Create a variable to store the current group
var currentGroup = null;

// Loop through all selected page items
for (var i = 0; i < selectedPageItems.length; i++) {
  var pageItem = selectedPageItems[i];

  // Get the bottom-left point of the page item
  var bottomLeftPoint = pageItem.geometricBounds[3];

  // Check if the page item should be added to a new group
  if (currentGroup == null || bottomLeftPoint - currentGroup.geometricBounds[3] > threshold) {
    // Create a new group
    currentGroup = doc.groupItems.add();
  }

  // Add the page item to the current group
  pageItem.move(currentGroup, ElementPlacement.PLACEATEND);
}

 This doesn't solve your issue but may lead to a way that can integrate your previous script into this one. I could see this being done by applying your script to each group(line) in your selection, but I can not figure out how to get that loop to work. This is similar to @femkeblanco' script that @m1b pointed out, but I would like to see their take on this!

m1b
Community Expert
Community Expert
December 22, 2022

Hi @BryanPagenkopf, since you haven't posted any specific code, I'll give you general suggestions.

1. make a single function that takes one line of items as (one) argument. So an array of page items.

2. make a function that groups all selected items into lines ( @femkeblanco's code here would be a great starting point).

3. iterate over those groups derived in step 2, calling the function from step 1 on each set of page items.

 

So, in semi-pseudo-code:

var doc = app.activeDocument,
    items = doc.selection,
    lines = sortIntoLines(items, 4); // number of lines

for (var i = 0; i < lines.length; i++)
    processLine(lines[i]);

// done

- Mark