Inspiring
May 15, 2023
Question
Grouping only specific paths using a Script.
- May 15, 2023
- 1 reply
- 435 views
I have a script that looks at the active selection. Always an outlined letter with dots inside. It then checks to see if there are two paths that are on the exact same Y axis. If it finds any paths it creates groups of two path items. I'm having two issues I could use help with.
1. I'm getting an error - Error 1302: No Such Element
2. I'd love to just select the whole layout and have it loop through each outlined character.
The dots are always black, but to illustrate which dots would get grouped I colored them in the example file.
Thank you!
if (app.documents.length > 0) {
if (app.activeDocument.selection.length > 0) {
// group items by vertical separation (line)
var groups = groupObjectsByLine(app.activeDocument.selection);
if (groups) {
var paths;
// iterate over each group of objects
for (var i = 0; i < groups.length; i++) {
paths = [];
// capture all pageItems within the group
// so that a standard array can be passed to adjustOffset
for (var j = 0; j < groups[i].pageItems.length; j++) {
paths.push(groups[i].pageItems[j]);
}
// if a group has 2 items already, create a new group
if (groups[i].pageItems.length === 2) {
var matchingSize = groups[i].pageItems.every(function(p) {
return p.width === groups[i].pageItems[0].width && p.height === groups[i].pageItems[0].height;
});
if (matchingSize) {
var g = app.activeDocument.groupItems.add();
groups.push(g);
g.pageItems.add(paths[0]);
g.pageItems.add(paths[1]);
groups[i].remove();
i--;
}
}
}
}
}
}
/**
* Take an array of Adobe Illustrator pageItems and group them by vertical separation.
* @9397041 {Array} sel Adobe Illustrator pageItems
* @Returns {Array} Array of Adobe Illustrator groupItems
*/
function groupObjectsByLine(sel) {
var groups = [];
// sort the selected page items by their position (left to right, top to bottom)
sel.sort(function (a, b) {
if (a.top === b.top) {
return a.left - b.left;
} else {
return a.top - b.top;
}
});
// check if each page item shares bounds with others
var item, placed;
while (sel.length > 0) {
item = sel.pop();
placed = false;
for (var i = 0; i < groups.length; i++) {
var group = groups[i];
if (overlappingBounds(item, group)) {
item.move(group, ElementPlacement.PLACEATEND);
placed = true;
group.pageItems.add(item);
break;
}
}
// if an item didn't fit into any current groups make a new group
if (!placed) {
var g = app.activeDocument.groupItems.add();
groups.push(g);
item.move(g, ElementPlacement.PLACEATEND);
}
}
return groups;
}
/**
* Check if a pageItems bounds overlaps with a groupItem.
* @9397041 {pageItem} item Adobe Illustrator pageItem
* @9397041 {groupItem} group Adobe Illustrator groupItem
* @Returns {Boolean}
*/
function overlappingBounds(item, group) {
var top = item.geometricBounds[1];
var bottom = item.geometricBounds[3];
var gTop = group.geometricBounds[1];
var gBottom = group.geometricBounds[3];
if (gTop !== top) {
return false;
}
return true;
}
