Skip to main content
February 22, 2011
Answered

Stacking Multiple Artboards?

  • February 22, 2011
  • 1 reply
  • 3893 views

Hi everyone,

I am trying to write a script that will take all the artboards in a document and stack them on top of each other.  (All the artboards are the same size).  It will also bring all the artwork on those artborads along with it.  And then it will delete all the artboards except one.

So far I have thought of two ways to accomplish this:

1)  document.rearrangeArtboards() - This function allows you to arrange the artboards by grids or rows, but as far as I can tell, you can't make them stack on one another...?

2)  document.selectObjectOnActiveArtboard() - selects all artwork on one artboard, then...

    [some function to move all artwork to position of first artboard, and then repeat for all artboards]

Any ideas on how best to go about this?  I would really appreciate your help!

Thank you!

This topic has been closed for replies.
Correct answer CarlosCanto

Oh many good points, Carlos.  Thank you for catching that!

And yes, although it will turn out quite messy, that is kind of the end goal.  You see, I am trying to develop a script that will take an Illustrator file with many artboards and prepare it for animation with After Effects.  Currently, I receive an Illustrator file that has many artboards on it.  The artboards are the designers way to communicate how the animation should proceed.  They are bascially storyboards with each artboard slightly changing its appearance and content from one to the next.  It looks like a flipbook all layed out.

But After Effects will only import one artboard and so everything in the Illustrator "storyboards" needs to be moved to one artboard.  Then the script will turn all the groups/artwork/linked files into their own "top level" layers because After Effects will merge everything that is in one Illustrator layer, which prevents me from being able to independently animate the separate artwork pieces.  And then since I only need one instance of each piece of artwork to use in After Effects, I will have it delete any artwork that doesn't change size/position/rotation from one artboard to the other.  I will probably have to designate these "duplicates" manually by making them invisible in the Layers panel and then having the script delete all invisible layers.

If I can get this to succesully run, it will easily save me anywhere from 2-4 hours per day.  Right now I have to manually drag everything around, reorder all the layers, and pull sublayers out to their individual top level layers, and it's just tedious.

But back to step 1 in my plan for world domination automation. 

I had seen the getTranslationMatrix() function, but I never could get it to work. I'm not quite sure what you mean by LBound(j) and UBound(j) in your script.  Maybe you can explain a little more what it is doing?  Or maybe write it in Javascript instead? 

Here is my updated code:

#target Illustrator

var docRef = app.activeDocument;


stackArtboards();


//------Stack Artboards and Contents-------------//
function stackArtboards(){
  
   var activeboard = new Array();
   var stackhere = new Array();
   var getdelta = new Array();
   var numboards = docRef.artboards.length;
  
   stackhere = docRef.artboards[0].artboardRect;
  
   for(i=numboards; i>1; i--){
  
        activeboard[1] = docRef.artboards[1].artboardRect;
        getdelta = calcDelta(stackhere, activeboard[1]);
       
        var deltaX = getdelta[0];
        var deltaY = getdelta[1];
           
        docRef.artboards.setActiveArtboardIndex(1);
        docRef.selectObjectsOnActiveArtboard();
       
        var sel = docRef.selection;
        var moveMatrix = app.getTranslationMatrix (deltaX, deltaY);
       
        sel.transform(moveMatrix);
        sel.selected = false;
       
        delBoard(1);

    }
}



//------Calculate How Much to Move Artwork-------------//
function calcDelta(stckhere, movethis){
      
       var deltaX = stckhere[0] - movethis[0];
       var deltaY = stckhere[1] - movethis[1];

    return[deltaX, deltaY];
}




//-------Delete Artboard-----------//
function delBoard(boardindex){
   
    docRef.artboards.setActiveArtboardIndex(boardindex);
    docRef.artboards.remove(boardindex);
}

When I run this script, I get an error at the bolded section (sel.transform(moveMatrix);) - it says "sel.transform is not a function."  Since I'm not quite sure what your VB script is doing, I'm not exactly sure how to proceed.

I appreciate your help!


Lbound & Ubound are the VB functions to get the first and last index of the selection, there's no "length" property in VB.

loop thru all items in selection and apply matrix

for (var j=0;j<sel.length;j++)

     {

          sel.transform (moveMatrix);

          sel.selected = false;

     }

this should set you on your World Dominance way.

1 reply

CarlosCanto
Community Expert
Community Expert
February 22, 2011

go with # 2, no need to move the artboard, just move the pageItems then delete the arboard

do you want to learn how to do it? here's how, it's more fun if you do it yourself

1. loop thru the Artboards (from last artboard to second artboard)

2. activate artboard

2. select all with selectObjectsOnActiveArtboard

3. find the distance from active artboard to artboard # 1 (use artboardRect property)

4. loop thru all items in selection

5. move item to first artboard (based on distance found in #3)

6. deselect item

7. delete artboard

I'll post the actual script if you get stuck.

February 23, 2011

Thank you both for your responses!

Carlos, that was exactly the logic I had in mind for option 2.  Here is my attempt (I am unsure how to accomplish the bolded part):

#target Illustrator

var docRef = app.activeDocument;


stackArtboards();

//------Stack Artboards and Contents-------------//
function stackArtboards(){
  
   var activeboard = new Array();
   var stackhere = new Array();
   var getdelta = new Array();
   var numboards = docRef.artboards.length;
  
   stackhere = docRef.artboards[0].artboardRect;
  
   for(i=1; i<numboards; i++){
  
        activeboard = docRef.artboards.artboardRect;
        getdelta = calcDelta(stackhere, activeboard);
        var deltaX = getdelta[0];
        var deltaY = getdelta[1];
               
        docRef.artboards.setActiveArtboardIndex(i);
        docRef.selectObjectsOnActiveArtboard();
       

        <<insert "move selected items" function here>>>

       
        delBoard(i);

    }
}

//------Calculate How Much to Move Artwork-------------//
function calcDelta(stckhere, movethis){
      
       var deltaX = stckhere[0] - movethis[0];
       var deltaY = stckhere[1] - movethis[1];

    return[deltaX, deltaY];
}


//-------Delete Artboard-----------//
function delBoard(boardindex){
   
    docRef.artboards.setActiveArtboardIndex(boardindex);
    docRef.artboards.remove(boardindex);
}

As you can see, I couldn't find a good way to move artwork that has been selected.  This artwork isn't always on the same layer, and it contains text items, path items, groups, linked files, you name it, so any code examples would be appreciated!

Thanks!

And now for all those Adobe employees that I hope are lurking in this forum:

I have some Javascript experience but I've never coded scripts for Adobe programs before.  So naturally in order to learn how to start scripting, I turned to the Object Model Viewer.

After much poking around in the Object Model Viewer, I have decided it is not very helpful at all.

For starters, the "copy text" link copies all of the text in the description box, instead of copying the sample code to actually call the function or property I am looking up.  I don't need the whole paragraph with all of the descriptions in my code, just copy a line of code that would be the same as if I let ESTK autocomplete when I type.

Secondly, the OMV only displays the default arguments of a function when it would be much more helpful to include all the options for each argument (i.e. the entry for "document.rearrangeArtboards" does not list all the options for the "artboardlayout" argument so I do not know what options there are for this function until I go back to ESTK).

Thirdly, the OMV should also provide example code for how to use this function or property, even if it was very simple.  It would be great to see a short block of example code that really showcases this function's/property's purpose.

And lastly, there is some sort of bug when I have OMV and ESTK open and I try to switch back and forth between the two.  The OMV will stay on top of all the other windows even when I Alt+Tab back and forth two or three times or even clicking the ESTK on the taskbar.  It takes a couple of tries to get the ESTK as the active window.  I am using CS5 on Windows 7 64-bit.

Thank you all for taking the time to help me out!

CarlosCanto
Community Expert
Community Expert
February 23, 2011

no problem,

what you have so far kind of works, it starts with the second artboard and when it gets deleted, the third artboard becomes the second. So when it loops to the next AB the 3rd is AB # 4, does it makes sense? you need to start with the last AB so when it gets deleted the others don't get their index # messed up.

loop backwards

For i = idoc.Artboards.Count To 2 Step -1

to move items use a translation matrix

Set moveMatrix = iapp.GetTranslationMatrix(deltaX, deltaY) 

loop thru items (any kind of item) in selection, and apply matrix

sel = idoc.Selection
       
For j = LBound(sel) To UBound(sel)
    sel(j).Transform moveMatrix
    sel(j).Selected = False //deselect
Next

it's all VB code, but you get the idea.

As Mark said, it could get messy once all is in one artboard, but I guess they are all arranged to coexist into one, right?