Skip to main content
Inspiring
September 28, 2022
Answered

align different object on different artbaords in different positions (XY or key object)

  • September 28, 2022
  • 1 reply
  • 1866 views

Hello community, I would like to ask for your help one more time. I have nothing to show to be honest but I would like to be able to make this happen.

Is it possible to have three objects positioned in the artboards just by giving the artboard index [0,1,2] or name and also place them in wherever position I need? Whether XY position or using a key object, somethign like this. Maybe I need to name the objects in the layer but if is necesary to have them well known I will name them.

 

Thank you all. ish you a great day.

This topic has been closed for replies.
Correct answer m1b

Some other good info to take in consideration sorry for bothering. Just for you to have better ideas.

1) Distance between the three artboards will never change, that makes the position of (X,Y) a constant value to set the position of the objects, it will be a template that will not change or move artboards. Distance will be the same.

2) Objects will have a name, like "Car Front, Car Back, Car Board" so they need to position in a specific place in the board, the only thing it will change is what I am going to insert in those squares (yes, the squares are kind of a reference to insert images and using illustrator variables + a excel database to change the contents).

3) If possible, though the code is AMAZING and I already saved it with it's proper copyrights, I would like to those three squares (named for example Car Front, Car Back, Car Board) to always get the fixed location in the artboard, does not matter if I need to find the correct off set value to move.

 

Can you help me up please? Thank you SO MUCH!


Hi @AntonioPacheco, actually this way is simpler to code than the last script. Here you go. I've made an array that you can edit to include name, artboard number, position, and alignment points. See what you think.

- Mark

 

 

 

var itemsToPosition = [
    {
        name: 'Car Front',
        artboard: 1,
        artboardAlignmentPoint: topLeftPoint,
        itemAlignmentPoint: topLeftPoint,
        position: [10, 20]
    },
    {
        name: 'Car Back',
        artboard: 2,
        artboardAlignmentPoint: topLeftPoint,
        itemAlignmentPoint: topLeftPoint,
        position: [50, 20],
    },
    {
        name: 'Car Board',
        artboard: 3,
        artboardAlignmentPoint: topLeftPoint,
        itemAlignmentPoint: topLeftPoint,
        position: [70, 70],
    },
];


/*
   Alignment points:
     topLeftPoint
     topPoint
     topRightPoint
     leftPoint
     centerPoint
     rightPoint
     bottomLeftPoint
     bottomPoint
     bottomRightPoint
*/


var items = positionNamedItems(
    {
        doc: app.activeDocument,
        findWhat: itemsToPosition
    }
);

// you can now do other things
// with the positioned items
// here, for example ...

app.selection = [];
items['Car Back'].selected = true;




/**
 * Finds a page item and positions it
 * in relation to the specified artboard.
 * @author m1b
 * @version 2022-09-30
 * Example findWhat:
 *   [
 *     {
 *       name: 'Car Front',
 *       artboard: 1,
 *       artboardAlignmentPoint: topLeftPoint,
 *       itemAlignmentPoint: topLeftPoint,
 *       position: [10, 20]
 *     }
 *   ]
 * Note: the alignmentPoints are functions that,
 * given an item or artboard, return a point.
 * @param {Object} options
 * @param {Document} options.doc - an Illustrator Document.
 * @param {Array<Object>} [options.findWhat] - search for this in item name (default: match all items).
 * @returns {Array<PageItem>} the positioned items.
 */
function positionNamedItems(options) {

    var doc = options.doc,
        findWhat = options.findWhat,
        results = {};

    if (
        doc == undefined
        || findWhat == undefined
    )
        return [];

    // find named items

    for (var i = 0; i < doc.pageItems.length; i++)

        for (var j = 0, count = findWhat.length; j < findWhat.length; j++)

            if (doc.pageItems[i].name.search(findWhat[j].name) != -1)

                // found one!
                findWhat[j].item = doc.pageItems[i];

    // collect artboards
    var abs = doc.artboards;

    // position each item
    for (var i = 0; i < findWhat.length; i++) {

        if (findWhat[i].item == undefined) {
            alert('No page item found for "' + findWhat[i].name + '".');
            continue;
        }

        var item = findWhat[i].item,
            ab = abs[findWhat[i].artboard - 1],
            itemAlignmentPoint = findWhat[i].itemAlignmentPoint || topLeftPoint,
            artboardAlignmentPoint = findWhat[i].artboardAlignmentPoint || topLeftPoint,
            offset = findWhat[i].position;

        // get the alignmentPoints align
        var itemPoint = itemAlignmentPoint(item),
            artboardPoint = artboardAlignmentPoint(ab);

        // translation needed to align itemPoint with artboardPoint
        var delta = [artboardPoint[0] - itemPoint[0], artboardPoint[1] - itemPoint[1]];

        // move the item, including offset
        item.translate(delta[0] + offset[0], delta[1] - offset[1]);

        // add to results
        results[findWhat[i].name] = item;

    }

    return results;

};


/**
 * Returns bounds of item.
 * @author m1b
 * @version 2022-09-29
 * @param {PageItem|Artboard} obj - a page item or artboard.
 * @returns {Array<Number>} - [left, top, right, bottom]
 */
function getBounds(obj) {
    var bounds;
    if (obj.hasOwnProperty('visibleBounds'))
        bounds = obj.visibleBounds;
    else if (obj.hasOwnProperty('artboardRect'))
        bounds = obj.artboardRect;
    return bounds;
};


/**
 * Returns the item's top left point.
 * @author m1b
 * @version 2022-09-29
 * @param {PageItem|Artboard} obj - a page item or artboard.
 * @returns {Array<Number>} - [x, y]
 */
function topLeftPoint(obj) {
    var bounds = getBounds(obj);
    if (bounds != undefined)
        return [bounds[0], bounds[1]];
};


/**
 * Returns the item's top point.
 * @author m1b
 * @version 2022-09-29
 * @param {PageItem|Artboard} obj - a page item or artboard.
 * @returns {Array<Number>} - [x, y]
 */
function topPoint(obj) {
    var bounds = getBounds(obj);
    if (bounds != undefined)
        return [bounds[0] + (bounds[2] - bounds[0]) / 2, bounds[1]];
};


/**
 * Returns the item's top right point.
 * @author m1b
 * @version 2022-09-29
 * @param {PageItem|Artboard} obj - a page item or artboard.
 * @returns {Array<Number>} - [x, y]
 */
function topRightPoint(obj) {
    var bounds = getBounds(obj);
    if (bounds != undefined)
        return [bounds[2], bounds[1]];
};


/**
 * Returns the item's left point.
 * @author m1b
 * @version 2022-09-29
 * @param {PageItem|Artboard} obj - a page item or artboard.
 * @returns {Array<Number>} - [x, y]
 */
function leftPoint(obj) {
    var bounds = getBounds(obj);
    if (bounds != undefined)
        return [bounds[0], bounds[1] + (bounds[3] - bounds[1]) / 2];
};


/**
 * Returns the item's center point.
 * @author m1b
 * @version 2022-09-29
 * @param {PageItem|Artboard} obj - a page item or artboard.
 * @returns {Array<Number>} - [x, y]
 */
function centerPoint(obj) {
    var bounds = getBounds(obj);
    if (bounds != undefined)
        return [
            bounds[0] + (bounds[2] - bounds[0]) / 2,
            bounds[1] + (bounds[3] - bounds[1]) / 2,
        ];
};


/**
 * Returns the item's right point.
 * @author m1b
 * @version 2022-09-29
 * @param {PageItem|Artboard} obj - a page item or artboard.
 * @returns {Array<Number>} - [x, y]
 */
function rightPoint(obj) {
    var bounds = getBounds(obj);
    if (bounds != undefined)
        return [bounds[2], bounds[1] + (bounds[3] - bounds[1]) / 2];
};


/**
 * Returns the item's bottom left point.
 * @author m1b
 * @version 2022-09-29
 * @param {PageItem|Artboard} obj - a page item or artboard.
 * @returns {Array<Number>} - [x, y]
 */
function bottomLeftPoint(obj) {
    var bounds = getBounds(obj);
    if (bounds != undefined)
        return [bounds[0], bounds[3]];
};


/**
 * Returns the item's bottom point.
 * @author m1b
 * @version 2022-09-29
 * @param {PageItem|Artboard} obj - a page item or artboard.
 * @returns {Array<Number>} - [x, y]
 */
function bottomPoint(obj) {
    var bounds = getBounds(obj);
    if (bounds != undefined)
        return [bounds[0] + (bounds[2] - bounds[0]) / 2, bounds[3]];
};


/**
 * Returns the item's bottom right point.
 * @author m1b
 * @version 2022-09-29
 * @param {PageItem|Artboard} obj - a page item or artboard.
 * @returns {Array<Number>} - [x, y]
 */
function bottomRightPoint(obj) {
    var bounds = getBounds(obj);
    if (bounds != undefined)
        return [bounds[2], bounds[3]];
};

 

 

Edit: added check for missing items and improved results output.

1 reply

m1b
Community Expert
September 28, 2022

Yes it's possible via script, but we'd need more information. Firstly, what are the objects? Are they already on the artboard(s)? Are they the top-most page item on each artboard? Are they new objects to be created? We need to know how the script refers to them.

 

After that, it seems that you want the items positioned some point centred above their artboard, which isn't hard in most cases.

- Mark

Inspiring
September 28, 2022

Of course! Here some more info.

Objects will be most of the time out of any of the artboards, the objects are squares and I will need them to center some vector draws inside after they get positioned. Yes they will be already in the artboard. About if they will be the top-most page item... Not really sure that's why I was wondering if I can refer them by their name in the layer, otherwise let me also change that before I have the objects in the artboards so the script work well. I really hope I cleared a little bit the idea. Thank you!

m1b
Community Expert
September 28, 2022

EDIT: this script has been superceded by the last script I posted in this thread, but I'm leaving this here for OP to compare, for learning purposes.

 

Hi @AntonioPacheco, I've written a script that does (I think!) what you are wanting. To use it, first give the items you wish to position a name (they can all have the same name), eg. in my script I used "positionMe", then run the script. You can change the "gap" value (script uses 20 pts). See attached screen shots.

Please experiment by making changes to the script so you can learn more.

- Mark

 

 

 

var items = positionNamedItems(app.activeDocument, 'positionMe', 20);


/**
 * Finds a page item for each artboard
 * and positions it above artboard.
 * @author m1b
 * @version 2022-09-28
 * @param {Document} doc - an Illustrator Document.
 * @param {String|RegExp} [findWhat] - search for this in item name (default: match all items).
 * @param {Number} [gap] - the gap between top of artboard and bottom of item (default: 0).
 * @returns {Array<PageItem>} the positioned items.
 */
function positionNamedItems(doc, findWhat, gap) {

    if (doc == undefined)
        return [];

    var items = [],
        itemCenters = [];

    // find named items
    for (var i = 0, a = doc.artboards.length; i < doc.pageItems.length; i++) {

        if (
            findWhat == undefined
            || doc.pageItems[i].name.search(findWhat) != -1
        ) {

            // found one!
            items.push(doc.pageItems[i]);

            //also store its center
            itemCenters.push(centerOfItem(doc.pageItems[i]));

            // stop looking when found one item for each artboard
            if (!--a) break;

        }

    }

    // make a copy of items for later
    var positionedItems = items.slice();

    // position each item

    for (var a = 0; a < doc.artboards.length; a++) {

        var ab = doc.artboards[a],
            abCenter = centerOfArtboard(ab);

        // find closest item to artboard center
        var smallest = -1,
            closest,
            itemCenter;

        for (var i = items.length - 1; i >= 0; i--) {

            var distance = distanceBetweenPoints(abCenter, itemCenters[i]);

            if (
                smallest == -1
                || distance < smallest
            ) {
                smallest = distance;
                closest = i;
            }

        }

        itemCenter = itemCenters[closest];

        // positions to align
        var itemBottom = [itemCenter[0], items[closest].visibleBounds[3]],
            abTop = [abCenter[0], ab.artboardRect[1]],
            offset = [0, gap];

        // relative position
        var topToBottom = [abCenter[0] - itemCenter[0], abTop[1] - itemBottom[1]];

        // position item closest to artboard's center
        items[closest].translate(topToBottom[0] + offset[0], topToBottom[1] + offset[1]);

        // remove the positioned item from array
        items.splice(closest, 1);

    }

    return positionedItems;

};


/**
 * Returns distance between two points.
 * @author m1b
 * @version 2022-07-25
 *
 * @param {Array} p1 - a point array [x, y].
 * @param {Array} p2 - a point array [x, y].
 * @returns {Number} - distance in points.
 */
function distanceBetweenPoints(p1, p2) {

    var a = p1[0] - p2[0];
    var b = p1[1] - p2[1];

    return Math.sqrt(a * a + b * b);

};


/**
 * Returns point at center of artboard.
 * @author m1b
 * @version 2022-09-28
 * @param {Artboard} ab - an Illustrator Artboard.
 * @returns {Array} - point array [x, y].
 */
function centerOfArtboard(ab) {

    return [
        ab.artboardRect[0] + (ab.artboardRect[2] - ab.artboardRect[0]) / 2,
        ab.artboardRect[1] - (ab.artboardRect[1] - ab.artboardRect[3]) / 2
    ];

};


/**
 * Returns point at center of item's bounds.
 * @author m1b
 * @version 2022-07-24
 * @param {PageItem} items - an Illustrator PageItem.
 * @returns {Array} - point array [x, y].
 */
function centerOfItem(item) {

    return [
        item.geometricBounds[0] + (item.width / 2),
        item.geometricBounds[1] - (item.height / 2)
    ];

};