Copy link to clipboard
Copied
Is there a script or a way to paste the same image on every page but each page a slight different position?
I'm doing a fore-edge print and need the same image on every other page but each time it has to move 0.246mm left
Thank You!
Copy link to clipboard
Copied
Hi @Joaquin35467744k2vs here's a script that should be useful in your situation. There are instructions in the script documentation below.
- Mark
Notes:
/**
* @file Interpolate Item Across Pages.js
*
* Places a duplicate item on each intervening page
* between start and end items. Interpolates the
* positions between start and end items.
*
* Instructions:
* 1. create a page item (can be a Group)
* 2. position the item on the starting page,
* in the starting position
* 3. in the layers panel, name the item "start_"
* + an identifier of your choice, eg. "start_line"
* 4. copy the item and paste it on the ending page,
* and move to the ending position
* 5. name the pasted item "end_" with the same
* identifier, eg. "end_line"
* 6. select the start or end item and run script;
* will create duplicates called eg. "middle_line"
*
* Tips:
* - you can adjust the start and/or end items and
* run script again and it will update the interpolated
* duplicates (actually it will first remove them all
* and re-do the duplicating).
* - the interpolationed items will be placed on the same
* layer as the start item.
*
* @author m1b
* @version 2025-12-13
* @discussion https://community.adobe.com/t5/indesign-discussions/script-to-paste-images-with-slight-offset/m-p/15624584
*/
function main() {
const PREFIX_START = 'start_';
const PREFIX_MIDDLE = 'middle_';
const PREFIX_END = 'end_';
var doc = app.activeDocument;
var item = doc.selection[0];
if (
!item
|| 'function' !== typeof item.duplicate
|| 'string' !== typeof item.name
)
return alert('Please select an item and try again.')
var matchAnyPrefix = new RegExp('^(' + [PREFIX_START, PREFIX_MIDDLE, PREFIX_END].join('|') + ')');
if (!matchAnyPrefix.test(item.name))
return alert('The name of the selected item does not have an expected prefix, eg. "' + PREFIX_START + '". Please set up correctly and try again.');
var id = item.name.replace(matchAnyPrefix, '');
var startItemName = PREFIX_START + id;
var middleItemName = PREFIX_MIDDLE + id;
var endItemName = PREFIX_END + id;
var middleItems = getThings(doc.allPageItems, 'name', middleItemName);
// remove all middle items
for (var i = middleItems.length - 1; i >= 0; i--)
middleItems[i].remove();
var startItem = getThing(doc.allPageItems, 'name', startItemName);
var endItem = getThing(doc.allPageItems, 'name', endItemName);
if (!startItem)
return alert('Could not find the start item named "' + startItemName + '".');
if (!endItem)
return alert('Could not find the end item named "' + endItemName + '".');
if (endItem.itemLayer !== startItem.itemLayer)
endItem.move(startItem.itemLayer);
var startPage = getNearestPage(startItem);
var endPage = getNearestPage(endItem);
var startSpread = startPage.parent;
var endSpread = endPage.parent;
if (startSpread === endSpread)
return alert('Your start and end items must be on different spreads.');
// collect the spreads we want
var spreads = [];
var count = Math.abs(endSpread.index - startSpread.index) - 1;
var indices = interpolateRange(startSpread.index, endSpread.index, count);
for (var i = 1; i <= count; i++)
spreads.push(doc.spreads.item(indices[i]));
// collect the pages we want
var pages = [startPage];
for (var i = 0, page, item; i < count; i++)
pages.push(getPage(spreads[i]));
pages.push(endPage);
var startX = startItem.geometricBounds[1] - startPage.bounds[1];
var startY = startItem.geometricBounds[0] - startPage.bounds[0];
var endX = endItem.geometricBounds[1] - endPage.bounds[1];
var endY = endItem.geometricBounds[0] - endPage.bounds[0];
var xPositions = interpolateRange(startX, endX, count);
var yPositions = interpolateRange(startY, endY, count);
// duplicate the item to each page
for (var i = 1, page, item; i < pages.length - 1; i++) {
page = pages[i];
item = startItem.duplicate(page);
item.name = 'middle_' + id;
positionItemRelativeToPage(item, xPositions[i], yPositions[i], page);
}
/**
* Given a Spread, returns the page we want to interpolate onto.
* @param {Spread} spread
* @returns {Page}
*/
function getPage(spread) {
for (var i = 0, pg; i < spread.pages.length; i++) {
pg = spread.pages[i];
if (doc.documentPreferences.facingPages) {
if (startPage.side === pg.side)
return pg;
else
continue;
}
else if (startPage.index === pg.index)
return pg;
}
};
};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Interpolate Item Across Pages');
/**
* Returns an array including `count` interpolated
* values between `start` and `end`, inclusive.
* @author m1b
* @version 2024-08-13
* @param {Number} start - the first value.
* @param {Number} end - the last value.
* @param {Number} count - the number of interpolations.
* @returns {Array<Number>}
*/
function interpolateRange(start, end, count) {
var range = [start],
step = (end - start) / (count + 1);
for (var i = 1; i <= count; i++)
range.push(start + i * step);
range.push(end);
return range;
};
/**
* Moves `item` to the top left of the nearest page, offset by [dx, dy].
* @author m1b
* @version 2025-11-08
* @param {PageItem} item - an Indesign PageItem.
* @param {Number} dx - the X offset.
* @param {Number} dy - the Y offset.
* @param {Page} [nearestPage] - an Indesign Page (default: the nearest page).
*/
function positionItemRelativeToPage(item, dx, dy, nearestPage) {
if ('function' !== typeof item.move)
throw new Error('positionItemRelativeToPage: cannot move item.');
// get the nearest page, in case the item isn't on a page
var page = nearestPage || getNearestPage(item);
// get the top left of the page
var pos = [page.bounds[0], page.bounds[1]];
// move the item
item.move([pos[1] + dx, pos[0] + dy]);
};
/**
* Returns the nearest page to `item`.
* @author m1b
* @version 2025-08-02
* @param {PageItem} item - the target item.
* @returns {Page} - the nearest page to `item`.
*/
function getNearestPage(item) {
var page = item.parentPage;
var spread;
while (!page) {
spread = item.parent;
if ('Page' === spread.constructor.name)
page = spread;
if ('Spread' === spread.constructor.name) {
var index = findClosestBounds(
item.visibleBounds,
spread.pages.everyItem().bounds
);
page = spread.pages.item(index);
}
}
return page;
};
/**
* Returns the index of the bounds in `boundsArray` that is
* closest to the target bounds. All bounds are in [T, L, B, R] format.
* @author m1b
* @version 2025-08-02
* @param {Array} targetBounds - The target bounds [T, L, B, R].
* @param {Array<bounds>} boundsArray - An array of bounds arrays.
* @returns {Number} Index of the closest bounds in the array.
*/
function findClosestBounds(targetBounds, boundsArray) {
var targetCenter = centerOfBounds(targetBounds);
var minDist = Infinity;
var closestIndex = -1;
for (var i = 0, center, dx, dy, distSq; i < boundsArray.length; i++) {
center = centerOfBounds(boundsArray[i]);
dx = targetCenter[0] - center[0];
dy = targetCenter[1] - center[1];
distSq = dx * dx + dy * dy;
if (distSq < minDist) {
minDist = distSq;
closestIndex = i;
}
}
return closestIndex;
};
/**
* Returns the center of `bounds`;
* @param {Array} bounds - The bounds [T, L, B, R].
* @returns {Array<Number>} - [cx, cy].
*/
function centerOfBounds(bounds) {
return [(bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2];
};
/**
* Returns a thing with matching property.
* If `key` is undefined, evaluate the object itself.
* @author m1b
* @version 2024-04-21
* @param {Array|Collection} things - the things to look through.
* @param {String} [key] - the property name (default: undefined).
* @param {*} value - the value to match.
* @returns {*?} - the thing, if found.
*/
function getThing(things, key, value) {
for (var i = 0; i < things.length; i++)
if ((undefined == key ? things[i] : things[i][key]) == value)
return things[i];
};
/**
* Returns a property of each object.
* @author m1b
* @version 2023-09-08
* @param {Array|Collection} things - the things to look through.
* @param {String} key - the property name.
* @param {*} value - the value to match.
* @returns {Array<*>}
*/
function getThings(things, key, value) {
var found = [];
for (var i = 0; i < things.length; i++)
if (things[i][key] == value)
found.push(things[i]);
return found;
};
Edit 2025-12-13: added better handling of spreads and facing pages.
Copy link to clipboard
Copied
@Joaquin35467744k2vs sorry I just realized that the script didn't consider spreads and facing pages. I have updated the code above. You mention "every other page"—I am assuming that is due to using two-page spreads? If so, I hope that revised script will suit your case.
- Mark
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more