• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
4

Another day, another free simple tool to help your development. Object Bounds Data

Community Expert ,
Aug 19, 2022 Aug 19, 2022

Copy link to clipboard

Copied

There's a simple, but prevalent addage in software... DRY.. Don't Repeat Yourself. Good advice.. Sometimes easier said than done. There's also another addage (or perhaps it's just more of a meme...) in programming... "Why spend 5 minutes doing a task when you could spend 2 hours automating it?" I believe this facetious sentiment hits the nail on the head in terms of identifying exactly what the problem is with the difficulty of finding the balance between trying to never repeat a task or command and not wasting unnecessary time trying to automate or generalize or abstract every single thing on the off chance you may need to use it in the future. Each time you do a task, you kind of have to think "how often am i going to do this, and is it worth automating?" And the answers to those questions may vary heavily on how you're feeling at the moment. So we often find ourselves fluctuating between repeating ourselves too much because we didn't think it was worth the time to streamline it... and overengineering everything just in case a task becomes more frequent in the future.

 

Anyway. I'm not sure where I was going with that. Except to say that I did a bit of introspection and retrospection to identify areas of repetition in my workflow. What kinds of things do i find myself doing all the time, and how can I put my focus onto generalizing/abstracting THOSE things, instead of worrying about things i hardly ever do.

 

One large area of repetitition i identified is working with object bounds. Illustrator has a nice handy "left" and "top" property for pageItems... But no "right" or "bottom" property. Obviously not a huge deal, because there are indeed "width" and "height" properties, so the "right" and "bottom" coordinates can be easily calculated.  But since i access these kinds of properties on a regular basis, that means that i'm always writing this:

//move myShape so it's right edge is aligned with artboard horizontal center point
//and it's top edge is 25% of the artboard height above the bottom of the page

var myShape = app.activeDocument.pageItems[0];
var artboard = app.activeDocument.artboards[0];
//there's no "left", "right", or "width" property of artboard,
//so all of that needs to be extracted and calculated from artboardRect
//trivial, to be sure.. but repetitive.. the math is always the same
var abRect = artboard.artboardRect;
var abWidth = abRect[2]-abRect[0];
var abHeight = abRect[1] - abRect[3]; //if you ever work with any other coordinate systems, this one might trip you up constantly because illustrator's y scale is reversed from most other systems which have 0,0 at the top left, and y increases as you move down on the screen
var abHCenter = abRect[0] + abWidth/2;

myShape.left = abRect[2] - abWidth/2 - myShape.width/2;
myShape.top = abRect[3] + abHeight * .25;

 

Not mensa math, by any stretch. But it looks ugly in the code and may take some time to decipher by someone who doesn't look at this daily. And again... repetitive. Wouldn't it be better if we could just access all of the commonly calculated values by name instead of inserting the arithmetic every time we need the right side of something?

 

What if i could write this instead?

 

//move myShape so it's right edge is aligned with artboard horizontal center point
//and it's top edge is 25% of the artboard height above the bottom of the page

var myShape = app.activeDocument.pageItems[0];
var artboard = app.activeDocument.artboards[0];
var shapeBounds = getBoundsData(myShape);
var abBounds = getBoundsData(artboard);

myShape.left = abBounds.vcenter - shapeBounds.halfwidth;
myShape.top = abBounds.bottom + abBounds.quarterHeight;

 

No need to calculate the bottom or center of the artboard using the artboard bounds. Descriptive property names so that it's very easy to tell where you're putting something. (personally, i've always had to think hard about artboardRect, visibleBounds/geometricBounds, and the argument passed to pathItems.rectangle. is the first element x? or is it y? are the 3rd and 4th arguments/elements representing right and bottom edges? Or are they representing width and height? I'd rather just not have to deal with teh indices directly, because it takes more brain power to remember which ones to use, it takes more brain power to read old code and see what was intended, and it just takes more typing... and more typing is the worst. But not as bad as mouse clicks... don't get me started on mouse clicks.

 

Additionally, the math above gets significantly messier (but again.. not more difficult. just messier) if your artwork contains clipped artwork. Setting the "left" property of a clip group doesn't change the left edge of the clipping mask, as it should. It changes the left edge of the entire clipGroup, including any clipped artwork inside

 

Enter Object Bounds Data.

 

The calculations to obtain right, bottom, center, half width/height, amount of clipped artwork (i,e, the difference between the left edge of some clipped artwork and the left edge of the mask that's clipping it.. this can be used to ensure proper visual positioning, despite the errant placement of just simply using "left", "top", or "position" properties.) are trivial and fast. So there's very little cost to just predeclaring all of them (customizable to your process of course) into an easy to use object that allows you to treat any pageItem or artboard in the document with the exact same set of standard and non-standard properties.

 

Object Bounds Data utilizes a dependency called getVisibleBounds(pageItem) written by @jduncan 

(https://github.com/joshbduncan). Then, using the actual visible bounds of the artwork sans any clipped art, it returns an object with lots of commonly used properties pre-calculated so that they can be easily referenced without doing the math later.

 

properties are duplicated in the resulting object with different naming conventions depending on whether you want more descriptive code (using properties like "width" and "halfHeight" as opposed to more terse property names like "w" and "hh"). And of course, you can simply rename any of these to anything that makes sense for your workflow. It would be trivial to add several more calculated properties as well, including parent information, parent layer information, document information, as well as even keeping a reference to the art object so that you can get the bounds data in one document, then move to another one, duplicate the artwork into the new document and already have all the calculated properties ready to go.

 

as far as usage... super easy. just call the function and pass in the pageItem or artboard that you want data for and set the resulting object to some variable. 

 

Let me know what you think, and if you find it useful. 😃

 

code located here:

https://github.com/wdjsdev/public_illustrator_scripts/blob/master/object_bounds_data.js

TOPICS
Scripting , SDK , Tools

Views

175

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Engaged ,
Aug 19, 2022 Aug 19, 2022

Copy link to clipboard

Copied

This is great work! If anyone manipulates pageItems often you should definitely check this out. It makes things so much more intuitive.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 19, 2022 Aug 19, 2022

Copy link to clipboard

Copied

LATEST

Thanks for the kind words. I know it's helped me a ton. In fact there were some issues, even in my professional work, that I had simply written off as too complex to handle without using different logic on a case by case basis. Your match objects repo and specifically the getVisibleBounds function allowed me to retroactively fix all those issues and be the hero who solved the impossible. 😉

 

I just hope others find it useful as well. I know I personally much prefer a tool I've written to one that is provided from elsewhere. Just easier to feel like I fully understand everything it does, I guess. So I could totally understand others choosing not to use it. Oh well. It's here if anyone wants it and on github if anyone wants to fork it, improve it, and submit a pull request. Let's see if we can't all help turn it into a monster of insane levels of usefulness for manipulating page items. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines