Skip to main content
Disposition_Dev
Legend
May 15, 2015
Answered

Sort groupItems in array using left coordinate of visible bounds?

  • May 15, 2015
  • 1 reply
  • 1183 views

Hey all! It's been a while, but I'm back with some more brain busters for you guys.

I'm in the process of re-working a script that Silly-V‌ wrote up for me. The goal is to create an artboard around each group item of a document in order from top left to bottom right (as though you were reading a book). (ultimately i would also like to add a provision that precludes the possibility of having one artboard being contained by another artboard, but that's just a luxury that I can try to work out later).

Silly's script works great and does exactly what i need it to.. about 60% of the time. The problem comes in when I have a group item that contains a clipping mask. Since the artboards are being created by way of groupItem.visibleBounds, illustrator assumes that the invisible artwork that extends beyond the clipping mask is visible and thus, creates an artboard that is much too large.

His version pushes the visible bounds of every groupItem to an array, then sorts the visible bounds by left coordinate, then pushes that subarray to another array and at the end, sorts the arrays vertically by top coordinate.. However, I'm looking to push the actual groupItems into the array instead of just the visible bounds. Then I'd like to sort the array of groupItems by their visible bounds and then I have the option of either creating the artboards in order based on their visible bounds or (the contingency) running a loop to make each groupItem selected=true and using the fitArtboardToSelectedart() command.

I'm stuck on how to sort the array of groupItems based on the visible bounds.. Here's what I have so far:

my inclination is to set a variable for the visibleBounds of each groupItem of temp (which seems like it would need a loop) but it doesn't make sense to me to loop the sort function...? there's something really big i'm missing here but i can't wrap my head around it.

Thanks for any help!

function organize(){

  var docRef = app.activeDocument;

  var layer = docRef.layers[0];

  var groups = layer.groupItems;

  var currentRowMarker;

  var groupList = []; //array of all groupItems

  var sortedGroupList = []; //array of subarrays sorted by visible bounds

  var temp = []; //temporary array for the current row of groupItems. sort this array from left to right first, then push the entire array into "sortedGroupList"

  //populate groupList

  for (g=0; g<groups.length; g++){

       groupList.push(groups);

  }

  //set currentRowMarker and compare rest of groupList to top coordinate of visible bounds. push true results to temp array.

  for (t=0; t<groupList.length; t++){

  temp = [];

  currentRowMarker = groupList.visibleBounds[1];

  temp.push(groupList);

  groupList.splice(t,1);

       for (c=0; c<groupList.length; c++){

            var currentGroup = groupList;

            var vB = groupList.visibleBounds[1];

                 if (vB + 20 > currentRowMarker && vB - 20 < currentRowMarker){

                      temp.push(currentGroup);

                      groupList.splice(c,1);

                 }

       }

  //this is where i'd like to sort the temp array

  sortedGroupList.push(temp);

  }

}

organize();

This topic has been closed for replies.
Correct answer Disposition_Dev

Well, I can't really say how it works on the inside, but here's an example that you can use:

function test(){

    var arr = [1, 2, 5, 4, 3, 11, 7, 8, 9, 10, 3];

  

    var msg = arr.sort(function(a, b){ return a < b});

    $.writeln(msg); //  11,10,9,8,7,6,5,4,3,2,1

  

    var msg2 = arr.sort(function(a, b){ return a > b});

    $.writeln(msg2); //  1,2,3,4,5,6,7,8,9,10,11

  

    // more complex example

    var arr2 = [

        {name: "object 1", visibleBounds: [10, 10, 100, 200]},

        {name: "object 3", visibleBounds: [30, 10, 100, 200]},

        {name: "object 2", visibleBounds: [20, 10, 100, 200]},

    ];

  

    var msg3 = arr2.sort(

        function(a, b){

            return a.visibleBounds[0] < b.visibleBounds[0];

        }

    );

    $.writeln(msg3.toSource());

    //[({name:"object 3", visibleBounds:[30, 10, 100, 200]}), ({name:"object 2", visibleBounds:[20, 10, 100, 200]}), ({name:"object 1", visibleBounds:[10, 10, 100, 200]})]

  

    var msg4 = arr2.sort(

        function(a, b){

            return a.visibleBounds[0] > b.visibleBounds[0];

        }

    );

    $.writeln(msg4.toSource());

    //[({name:"object 1", visibleBounds:[10, 10, 100, 200]}), ({name:"object 2", visibleBounds:[20, 10, 100, 200]}), ({name:"object 3", visibleBounds:[30, 10, 100, 200]})]

}

test();


Thanks for your help Vasily.

I was unable to get your suggestion to work, not to say that it was an incorrect suggestion. So i decided to go the more complicated route. Hopefully I can learn about why your suggestion wasn't working for me in a future attempt.

I'm positive this isn't the most elegant way to perform this task, but it was the only way that made sense to me. Here's what i ended up with:

for (s=temp.length; s>0; s--){

  var placeholder = 0;

  var farthestLeft;

  var deleteIndex;

       for (a=0; a<temp.length; a++){ // this loop finds farthest left groupItem.

       if(placeholder == 0){

            placeholder = temp.visibleBounds[0];

            farthestLeft = temp;

            deleteIndex = a;

       }

       else if(temp.visibleBounds[0] < placeholder){

            placeholder = temp.visibleBounds[0];

            farthestLeft = temp;

            deleteIndex = a;

       }

  }

  tempSorted.push(farthestLeft);

  temp.splice(deleteIndex,1);

}

Disposition_Dev
Legend
May 15, 2015

so, a little more research seems to point to a custom function to use for the sort command. But I sitll don't quite know how to implement the function. this is what stack overflow says:

function compare(a,b) {
 
if (a.last_nom < b.last_nom)
  
return -1;
 
if (a.last_nom > b.last_nom)
  
return 1;
 
return 0;
}

objs
.sort(compare);


but i don't really know where to start....


something like:


function compare(a,b) {

    

     if (a.temp[i don't know how to index this].visibleBounds[0] < b.temp[index].visibleBounds[0])

          return -1;

     etc...

}


temp.sort(compare);

Silly-V
Legend
May 15, 2015

Hey long time no see!
the sort function goes like this:

temp.sort(function( a, b){

     if (a.visibleBounds[0] < b.visibleBounds[0])

          return -1;

     etc...

});

Disposition_Dev
Legend
May 15, 2015

so returning -1 will move the current groupItem to the left one place? or all the way to the left?

how did the rest of what i had look? i haven't run any part of that script even once, so i have no idea whether i made a huge mistake somewhere..