Copy link to clipboard
Copied
Hi! I have a question:
I wonder if there's a way to select a group of objects (in the same layer) and auto-arrange them based on each object's Y value (vertical position on the page).
This would be helpful in creating basic perspectives.
Perhaps a script?
Thanks!
1 Correct answer
not the prettiest thing int he world, but it does the trick. give this a shot:
...function test()
{
if(!app.documents.length)
{
alert("You must have a document open.");
return;
}
var docRef = app.activeDocument;
var sel = docRef.selection;
if(!sel.length)
{
alert("You must make a selection.");
return;
}
function sortVertically(items)
{
var topMost,curY,delIndex,curItem,tempItems = [];
for(var x=0,len=items.length;x<len;x++)
Explore related tutorials & articles
Copy link to clipboard
Copied
not the prettiest thing int he world, but it does the trick. give this a shot:
function test()
{
if(!app.documents.length)
{
alert("You must have a document open.");
return;
}
var docRef = app.activeDocument;
var sel = docRef.selection;
if(!sel.length)
{
alert("You must make a selection.");
return;
}
function sortVertically(items)
{
var topMost,curY,delIndex,curItem,tempItems = [];
for(var x=0,len=items.length;x<len;x++)
{
tempItems.push(items
); }
while(tempItems.length)
{
topMost = tempItems[0];
curY = topMost.top;
delIndex = 0;
for(var x=1, len = tempItems.length;x<len;x++)
{
curItem = tempItems
; if(curItem.top > curY)
{
topMost = curItem;
curY = curItem.top;
delIndex = x;
}
}
topMost.zOrder(ZOrderMethod.BRINGTOFRONT);
tempItems.splice(delIndex,1);
}
}
sortVertically(sel);
}
test();
Copy link to clipboard
Copied
Thank you very, very much!
Worked like a charm!
Copy link to clipboard
Copied
Salut !
Je me permet de proposer une autre façon plus souple.
I allow myself to propose another more flexible way.
// JavaScript Document
function test() {
if (!selection.length) return;
var reverse = false;
var sel = selection;
function sortVertically(items,zd) {
var tab = [];
for(var n = 0; n < items.length; n++) {
tab
= []; tab
[0]= items .top; tab
[1]= items ; }
tab.sort();
if (zd) tab.reverse();
for (n = 0; n < sel.length; n++) {
tab
[1].zOrder(ZOrderMethod.BRINGTOFRONT); }
}
sortVertically(sel,reverse);
}
if (app.documents.length) {test();}
de LR
Copy link to clipboard
Copied
I need to reorder objects by y position and it looks like this script will do exactly what I need, but I get an error when I try to run it...
Copy link to clipboard
Copied
Can you help me? I need to order objects by the row (if possible I need to round y position of objects (to group them to row) for some value that I can enter in a script manually) from right down corner of airboard and each row sort by decreasing x position.
From top to down order in the layer should be 1,2,3,4,5,6 and etc.
thanks in advance
Copy link to clipboard
Copied
I'm not sure i follow exactly what you mean. you just want to take any items that exist at the same Y position (plus or minus some buffer) and group them together, then take the resulting groups and sort them in descending order from top to bottom?
Copy link to clipboard
Copied
For example
I want to sort this objects from bottom to top by rounded Y for simplify sorting process. Rounding will create virtual rows highest value goes first (Top in the layers list). Then each row I want to sort by X, from right to the left (so high value goes first - revers order)
This is like sorting 2 dimensional array in revers order:
X,Y array
myobjlist= [[124,2],[23,2],[60,1],[150,1],[12,2],[20,0],[50,1],[40,0],[70,0]]
sorted(myobjlist)
will create next array
[[124, 2] [23, 2] [12, 2] [150, 1] [60, 1] [50, 1] [70, 0] [40, 0] [20, 0]]
Object with [124, 2]
coordinates will be first in layers list and [20, 0] - last
Copy link to clipboard
Copied
Salut,
Une approche si cela peut aider (si j'ai bien compris ?) :
// JavaScript Document for Illustrator
var dec = 20;if (app.documents.length > 0) {
var docRef = app.activeDocument;
var selectedItems = selection;
var nbObjSelect = selectedItems.length;
if (nbObjSelect) {
var rep, iObj, newtop;
var TabTop = [];
rep = prompt("Tolérance ?", dec);
dec= rep*1;
for (var i = 0; i < nbObjSelect; i++) {
iObj = selectedItems;
TabTop.push([iObj.top,i])
}
TabTop.sort();
TabTop.reverse(); //alert(TabTop.join("\r"));
newtop = TabTop[0][0];
docRef.layers.add();
nbLayers = docRef.layers.length;
for(i = 0, k = nbLayers-1; i < nbObjSelect; i++) {
if (newtop > TabTop[0]-dec && newtop < TabTop[0]+dec) {
iObj = selectedItems[TabTop[1]];
iObj.move(docRef.layers[0],ElementPlacement.PLACEATEND);
docRef.layers[0].name = "Rang "+k;
}
else {
newtop = TabTop[0]; k++; i--;
docRef.layers.add();
}
}
var layerAct, nbObjLayer, n, nObj, j, jObj;
var TabLeft = [];
for(i = 0; i < k; i++) {
layerAct = docRef.layers;
nbObjLayer = layerAct.pageItems.length;
for(n = 0; n < nbObjLayer; n++) {
nObj = layerAct.pageItems;
TabLeft.push([nObj.left,nObj]);
}
TabLeft.sort(); //TabLeft.revers(); alert(TabLeft.join("\r"));
for(j = 0; j < nbObjLayer; j++) {
jObj = TabLeft[1];
jObj.zOrder(ZOrderMethod.SENDTOBACK);
}
TabLeft = [];
}
}
else alert("Vous n'avez rien sélectionné !","De Elleere");
}
else alert("Pour l'exécution de ce sript un document doit être ouvert !","Script Alerte de Elleere !");
//-------------------------------------------------------------
de LR elleere
Copy link to clipboard
Copied
Thank you, your script seems doing that I need. Tolerance value I think is fine. But there is some problems:
- It creates last layer (virtual row) in top of the list.
- Each object in the row should be sorted from right to left
- it creates layers with objects. In finale will be good if all sorted objects will be in one layer
see pic below
Here some test ai files.
[link removed by moderator]
You can test by your self. I will be glad if you can fix this problem for me!
Thanks in advance!
Copy link to clipboard
Copied
Bonjour Dever,
The link is infected attention !!
Me contacter par mail (exemple enregistré sous Illustrator Version CS6).
LR
Copy link to clipboard
Copied
Hello LR
Zippyshare injects some ads and it can be infected, sorry about it
here is Wetransfer link with CS6 files to test
Thanks,
Alex
Copy link to clipboard
Copied
Hello Rene,
Still did not get an Email from you. Can you post working script here?
Thanks
Copy link to clipboard
Copied
This script looks like exactly what I need but it also gives me an error... am I doing somthing wrong?
Copy link to clipboard
Copied
I cannot see why the above two scripts are not working. You could try the snippet below, but it's for all pageItems in the document, not selected items. It doesn't work for selected items and again I'm unsure why. (I would be grateful if someone could advise on why it works on the "pageItems" or "pathItems" collection but not on the "selection" collection.)
var items = app.activeDocument.pageItems;
for (var i = 0; i < items.length - 1; i++) {
for (var j = 0; j < items.length - i - 1; j++) {
if (items[j].top > items[j + 1].top) {
items[j].moveAfter(items[j+1]);
}
}
}
Copy link to clipboard
Copied
Thanks!
Unfortunately,...
topMost.zOrder is not a function
(Maybe changes in the API in the meanwhile?)
Copy link to clipboard
Copied
function test() {
if (!app.documents.length) {
alert("You must have a document open.");
return;
}
var docRef = app.activeDocument;
var sel = docRef.selection;
if (!sel.length) {
alert("You must make a selection.");
return;
}
function sortVertically(items) {
var topMost,curY,delIndex,curItem,tempItems = [];
for (var x = 0, len = items.length; x < len; x++) {
tempItems.push(items[x]);
}
while (tempItems.length) {
topMost = tempItems[0];
curY = topMost.top;
delIndex = 0;
for (var x = 1, len = tempItems.length; x < len; x++) {
curItem = tempItems[x];
if (curItem.top > curY) {
topMost = curItem;
curY = curItem.top;
delIndex = x;
}
}
topMost.zOrder(ZOrderMethod.BRINGTOFRONT);
tempItems.splice(delIndex, 1);
}
}
sortVertically(sel);
}
test();
Copy link to clipboard
Copied
Thanks, @femkeblanco (et al, of course): this works!
And thanks for posting it as pre-formatted text, that makes it a lot easier to read, copy and paste.
Comparing your script witht the original, I'm surprised the original worked at all for anybody.
I notice the same kind of change in two locations:
tempItems.push(items); →→→ tempItems.push(items[x]);
and
curItem = tempItems; →→→ curItem = tempItems[x];
Would the original have worked accidentally with grouped items?
Copy link to clipboard
Copied
Based on the work by @Disposition_Dev and @femkeblanco, I wrote a more verbosely commented script and added the possibility to sort by any property. For sake of legibility, I used the JavaScript 'sort' function. I hope this helps.
function main() {
// Check if there is an open document with a selection
if (!app.documents.length) {
alert("You must have a document open.");
return;
}
var docRef = app.activeDocument;
var sel = docRef.selection;
if (!sel.length) {
alert("You must make a selection.");
return;
}
// Prompt the user for the sorting criterion
var criterion = prompt("What property do you want to sort by? E.g. top, left, width, height, opacity, name:", "top");
// If the property has a minus sign, the user wants to sort in reverse order. (*1)
var sortOrder = 1;
if (criterion[0] === "-") {
sortOrder = -1;
criterion = criterion.substr(1);
}
// Make a copy of the array containing the selection:
var items = [];
for (var i = 0; i < sel.length; i++) {
items.push(sel[i]);
}
// Sort the array by the criterion
items = items.sort(dynamicSort(criterion));
// iterate the array in reverse order while moving every element to the top:
for (var i = items.length - 1; i >= 0; i--) {
if (sortOrder === 1) {
items[i].zOrder(ZOrderMethod.BRINGTOFRONT);
} else {
items[i].zOrder(ZOrderMethod.SENDTOBACK);
}
}
}
// Sorting function
function dynamicSort(property) {
// Adapted from: https://stackoverflow.com/a/4760279/960592 (Credit: Ege Özcan)
// (Adobe's Javascript doesn't seem to like double ternary operator)
return function (a, b) {
if (a[property] < b[property]) {
return -1;
}
if (a[property] > b[property]) {
return 1;
}
return 0;
}
}
main();
/*
Note: It *should* be possible to just reverse the array (items.reverse() ) or to change the sorting order in
the sorting function, but I couldn't get either method to work. This is a work-around.
*/
Copy link to clipboard
Copied
I should have made it clear that the above was @Disposition_Dev 's script, I just updated it. It is my understanding that migrating to the present forum in late 2019 impaired scripts, including causing loss of indices of elements. The script was evidently working up until that point.
Copy link to clipboard
Copied
Is that also the reason that there is no formatting on code in older posts?
Copy link to clipboard
Copied
That is what I presume.
Copy link to clipboard
Copied
Thanks so much for this! I've been using illustrator for a bit of CNC vector work and some of the linework I've been generating has been totally random. This can add a ton of time to the CNC operations as the tool head is sent to polar opposite ends of the material between cuts. This script allows my CAM software to order the operations based on layers. Its saving me a ton of time.

