Thursday, June 02, 2011

Distribute Stacked Objects to a grid (sort of...)

Hey All,

New script goodness!!!



Distribute Stacked Objects is a script I cooked up to take any number of selected objects, and spread them out a bit.  The script doesn't create an exact grid, but it does prevent objects from overlapping, which is handy if you've just imported 50 .eps icons. Take it for a spin and see if it improves your quality of life. I've tested it on CS5 for Windows.  Good luck, and happy illustrating.

right click here to acquire.

cheers,
-J

15 comments:

Geno said...

Any way you can help guide me on how to set up an Illustrator Script that would tell variable Spot Colors in file to export as png/gif/jpg?

John said...

The issue is a bit complex to describe in the blog comments. Pop me an email (found at top of all my scripts) and let's discuss.

cheers,
-J

bob said...

Hey John great script! What changes do you think can I make if the stacked objects belong to layers, and I want them to be distributed into the grid while staying in their individual layers?
Thanks for any help!

John said...

Good idea Bob. I'll see what I can do.

bob said...

That'll be awesome.

btw, great blog you've got here. Its proving to be a great resource for AI scripting

John said...

Hey Bob,
I missed the part where you said you were learning how to script. Cool, I'm glad to be a resource. I remember how hard it was getting started, and am glad to help make the transition easier for you.
I wrote this script quickly and so I used the 'group' idea to quickly collect the objects into an object so I could get the collection to center easily. You should pretty easily be able to remove the centering code, and the 'object' code, and it shouldn't affect the positioning code at all. I think I started to implement this, since I set 'objectsCentered' as a variable, but never fully implemented it. Try modifying the script by extracting the group, and if you get stuck, I'll help you out. Cheers!

bob said...

Thank you so much! It worked. At first, some of the objects would randomly end up far outside of the grid (like at the very edge of the document), but I tried it a few more times, and it hasn't messed up since. I'm assuming the stacked objects weren't centered when it was messing up (not sure how much that matters).

Thanks Again!

var doc = activeDocument;
var selx = doc.selection;
if(selx.length ==0){alert("You must select objects to distribute.");}
else{makeGrid(selx);}


function makeGrid(sel)
{
var objectsCentered = true;
if(objectsCentered){
var newGroup = app.activeDocument.groupItems.add();
}

var maxW = maxH = currentX = currentY = maxRowH = 0;
var padding = Number(prompt("How much padding between objects?","10"));
var gridCols = Math.round(Math.sqrt(sel.length)) ;
for(var e=0, slen=sel.length;e<slen;e++)
{

if(objectsCentered){
// ::Add to group
sel[e].moveToBeginning( newGroup );
}

// :::SET POSITIONS:::
sel[e].top = currentY;
sel[e].left = currentX;

// :::DEFINE X POSITION:::
currentX += (sel[e].width + padding);

var itembottom = (sel[e].top-sel[e].height);
maxRowH = itembottom < maxRowH ? itembottom : maxRowH;

if((e % gridCols) == (gridCols - 1))
{
currentX = 0;
maxH = (maxRowH);

// :::DEFINE Y POSITION:::
currentY = maxH-padding;
maxRowH=0;
}
}



if(objectsCentered){
newGroup.top = -( doc.height/2) + newGroup.height/2;
newGroup.left = (doc.width/2)-newGroup.width/2;

// :::UNGROUP:::
var sLen=sel.length;
while(sLen--)
{
sel[sLen].moveToBeginning( doc.activeLayer );
}
}
}

John said...

Hey Bob,
The code you posted is exactly the code in my script, minus the header. Did you mean to do that??

thanks,
-J

bob said...

Oops, Sorry about that. copied the wrong code.


var doc = activeDocument;
var selx = doc.selection;
if(selx.length ==0){alert("You must select objects to distribute.");}
else{makeGrid(selx);}


function makeGrid(sel)
{
var objectsCentered = true;


var maxW = maxH = currentX = currentY = maxRowH = 0;
var padding = Number(prompt("How much padding between objects?","10"));
var gridCols = Math.round(Math.sqrt(sel.length)) ;
for(var e=0, slen=sel.length;e<slen;e++)
{

// :::SET POSITIONS:::
sel[e].top = currentY;
sel[e].left = currentX;

// :::DEFINE X POSITION:::
currentX += (sel[e].width + padding);

var itembottom = (sel[e].top-sel[e].height);
maxRowH = itembottom < maxRowH ? itembottom : maxRowH;

if((e % gridCols) == (gridCols - 1))
{
currentX = 0;
maxH = (maxRowH);

// :::DEFINE Y POSITION:::
currentY = maxH-padding;
maxRowH=0;
}
}

}

yesjorn said...

Hey John,

your Distribute Stacked Objects Script is awesome but is there a way to tell it to to make a horizontal or vertical stack and define a padding value?

That would be perfect!

thanks!

Jorn

John said...

Brilliant idea Jorn, I'll add the functionality this weekend!

John said...

Fixed. Now it defaults to group, but you can set to horizontal or vertical too. Cheers,
-J

Unknown said...

Any way to set a fixed width? Trying to distribute 35 stacked objects onto a 48" x 96" artboard. The current script places the objects just too wide. Thanks!

John said...

Hey Andrew,
There is no easy way to modify this script to work with a max width, but it is possible. Email me a demo file of what you are trying to do and I'll see if I can make something work for you. (My email is at the top of all my scripts...)

Unknown said...

Hi John,

This looks great. I wondered if you ever managed to make this work within a set artboard size as Andrew message above.

It's something I am trying to work on at the moment where you can nest objects onto an artboard but keeping the order, where most nesting software changes the order to create a better nest, but I am more after the order more than anything.

Cheers,

Sam