Skip to main content
Inspiring
May 15, 2023
Answered

How to find overlap object?

  • May 15, 2023
  • 2 replies
  • 757 views

Hi All, 

 

I'm trying to find the overlapping object on the selected frame.
can anyone help me in finding this with the script?

thank you 

This topic has been closed for replies.
Correct answer m1b

Hi @@AG, here is an example script to show you one approach. - Mark

 

/**
 * @fileOverview Example usage of `itemsIntersectingItem` function.
 * Select an item, then script will change selection to any items intersecting.
 * Note: uses geometricBounds to determine intersections.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-find-overlap-object/m-p/13793143
 */
function main() {

    var doc = app.activeDocument,
        item = doc.selection[0],
        page = getItemPage(item);

    if (
        item == undefined
        || page == undefined
    ) {
        alert('Please select an item on a page and try again.');
        return;
    }

    var intersectingItems = itemsIntersectingItem(item, page.allPageItems);

    doc.selection = intersectingItems;

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Select intersecting items');


/**
 * Returns an item's page or spread, if any.
 * @param {PageItem} item - an Indesign or Illustrator PageItem.
 * @returns {Page}
 */
function getItemPage(item) {

    if (item == undefined)
        return;

    var page = item.parent;

    while (
        page.parent != undefined
        && page.constructor.name != ('Page')
        && page.constructor.name != ('Spread')
        && page.constructor.name != ('Document')
    )
        page = page.parent;

    if (
        page.constructor.name == 'Page'
        || page.constructor.name == 'Spread'
    )
        return page;

};


/**
 * Returns items whose bounds intersect
 * with the item's bounds.
 * @author m1b
 * @version 2022-10-04
 * @param {PageItem} item - an Indesign PageItem.
 * @param {Array<PageItem>|PageItems} items - an array or collection of Indesign PageItems.
 * @returns {Array<PageItem>}
 */
function itemsIntersectingItem(item, items) {

    var intersectingItems = [];

    for (var i = 0; i < items.length; i++) {

        if (
            item !== items[i]
            && boundsDoIntersect(items[i].geometricBounds, item.geometricBounds)
        )
            intersectingItems.push(items[i]);

    }

    return intersectingItems;

};


/**
 * Returns true if the two bounds intersect.
 * @author m1b
 * @version 2022-10-04
 * @param {Array} bounds1 - bounds array [t, l, b, r].
 * @param {Array} bounds2 - bounds array [t, l, b, r].
 * @returns {Boolean}
 */
function boundsDoIntersect(bounds1, bounds2) {

    // TLBR
    return !(
        bounds2[0] > bounds1[2]
        || bounds2[1] > bounds1[3]
        || bounds2[2] < bounds1[0]
        || bounds2[3] < bounds1[1]
    );

};

2 replies

m1b
Community Expert
m1bCommunity ExpertCorrect answer
Community Expert
May 18, 2023

Hi @@AG, here is an example script to show you one approach. - Mark

 

/**
 * @fileOverview Example usage of `itemsIntersectingItem` function.
 * Select an item, then script will change selection to any items intersecting.
 * Note: uses geometricBounds to determine intersections.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-find-overlap-object/m-p/13793143
 */
function main() {

    var doc = app.activeDocument,
        item = doc.selection[0],
        page = getItemPage(item);

    if (
        item == undefined
        || page == undefined
    ) {
        alert('Please select an item on a page and try again.');
        return;
    }

    var intersectingItems = itemsIntersectingItem(item, page.allPageItems);

    doc.selection = intersectingItems;

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Select intersecting items');


/**
 * Returns an item's page or spread, if any.
 * @param {PageItem} item - an Indesign or Illustrator PageItem.
 * @returns {Page}
 */
function getItemPage(item) {

    if (item == undefined)
        return;

    var page = item.parent;

    while (
        page.parent != undefined
        && page.constructor.name != ('Page')
        && page.constructor.name != ('Spread')
        && page.constructor.name != ('Document')
    )
        page = page.parent;

    if (
        page.constructor.name == 'Page'
        || page.constructor.name == 'Spread'
    )
        return page;

};


/**
 * Returns items whose bounds intersect
 * with the item's bounds.
 * @author m1b
 * @version 2022-10-04
 * @param {PageItem} item - an Indesign PageItem.
 * @param {Array<PageItem>|PageItems} items - an array or collection of Indesign PageItems.
 * @returns {Array<PageItem>}
 */
function itemsIntersectingItem(item, items) {

    var intersectingItems = [];

    for (var i = 0; i < items.length; i++) {

        if (
            item !== items[i]
            && boundsDoIntersect(items[i].geometricBounds, item.geometricBounds)
        )
            intersectingItems.push(items[i]);

    }

    return intersectingItems;

};


/**
 * Returns true if the two bounds intersect.
 * @author m1b
 * @version 2022-10-04
 * @param {Array} bounds1 - bounds array [t, l, b, r].
 * @param {Array} bounds2 - bounds array [t, l, b, r].
 * @returns {Boolean}
 */
function boundsDoIntersect(bounds1, bounds2) {

    // TLBR
    return !(
        bounds2[0] > bounds1[2]
        || bounds2[1] > bounds1[3]
        || bounds2[2] < bounds1[0]
        || bounds2[3] < bounds1[1]
    );

};
Robert at ID-Tasker
Legend
May 15, 2023

I'm not JS guy but you would have to iterate through the collection of allPageItems for the parent page / Spread of your selected object and compare geometricBounds - for rectangles... it's more complicated if objects are irregular - ovals or polygons...

Then there is a case of rotation and deformation...