Copy link to clipboard
Copied
Hello,
Below is a script indended to swap two selected items. Should a user have a graphic the script portionally centres the images in their new frames.
However EPS do not behave in such a away, but jpgs pdfs and psds all seems okay.
Any hints would be most welcome,
Best,
Smyth
//AutoSwap
app.doScript(function () {
if (app.selection.length !== 2) {
alert("Please select exactly two objects.");
} else {
var firstObject = app.selection[0];
var secondObject = app.selection[1];
// Check if either object is a GraphicLine
if (firstObject.constructor.name === "GraphicLine" || secondObject.constructor.name === "GraphicLine") {
alert("Cannot swap selection with a rule.");
return; // Exit the script if a GraphicLine is detected
}
// Ensure both objects are valid
if (!firstObject.isValid || !secondObject.isValid) {
alert("Invalid selection. Please select two valid objects.");
} else {
// Function to remember text frame settings
function rememberTextFrameSettings(object) {
if (object.constructor.name === "TextFrame") {
return {
verticalJustification: object.textFramePreferences.verticalJustification,
columnCount: object.textFramePreferences.textColumnCount,
isMultiColumn: object.textFramePreferences.textColumnCount > 1
};
}
return null;
}
// Function to apply text frame settings
function applyTextFrameSettings(object, settings) {
if (settings !== null) {
object.textFramePreferences.verticalJustification = settings.verticalJustification;
object.textFramePreferences.textColumnCount = settings.columnCount;
}
}
// Remember text frame settings
var firstSettings = rememberTextFrameSettings(firstObject);
var secondSettings = rememberTextFrameSettings(secondObject);
// Get the geometric bounds of both objects
var firstBounds = firstObject.geometricBounds;
var secondBounds = secondObject.geometricBounds;
// Calculate width and height from geometric bounds
var firstWidth = firstBounds[3] - firstBounds[1];
var firstHeight = firstBounds[2] - firstBounds[0];
var secondWidth = secondBounds[3] - secondBounds[1];
var secondHeight = secondBounds[2] - secondBounds[0];
// Function to compare width and height
function areDimensionsEqual(width1, height1, width2, height2) {
return Math.abs(width1 - width2) < 6 && Math.abs(height1 - height2) < 6; // Tolerance for floating-point precision
}
// Check if either object is a multi-column text frame
var isFirstMultiColumn = firstSettings && firstSettings.isMultiColumn;
var isSecondMultiColumn = secondSettings && secondSettings.isMultiColumn;
// Handle swapping based on the type of objects
if ((isFirstMultiColumn && !isSecondMultiColumn && secondObject.constructor.name === "Rectangle") ||
(!isFirstMultiColumn && isSecondMultiColumn && firstObject.constructor.name === "Rectangle")) {
// Swap geometric bounds only for multi-column text frame with picture
firstObject.geometricBounds = secondBounds;
secondObject.geometricBounds = firstBounds;
} else {
// Swap geometric bounds and apply text frame settings
firstObject.geometricBounds = secondBounds;
secondObject.geometricBounds = firstBounds;
// Apply text frame settings only if both are text frames
if (firstSettings && secondSettings) {
applyTextFrameSettings(firstObject, secondSettings);
applyTextFrameSettings(secondObject, firstSettings);
}
}
// Handle grouped objects specifically
function adjustGroupImagesPosition(group, offsetX, offsetY) {
if (group.constructor.name === "Group") {
for (var i = 0; i < group.allPageItems.length; i++) {
adjustImagePosition(group.allPageItems[i], offsetX, offsetY);
}
}
}
// Function to adjust image position within the new frame
function adjustImagePosition(object, offsetX, offsetY) {
if ((object.constructor.name === "Rectangle" ||
object.constructor.name === "Oval" ||
object.constructor.name === "Polygon") && object.images.length > 0) {
var image = object.images[0];
// Adjust geometric bounds for all shapes
image.geometricBounds = [
image.geometricBounds[0] + offsetY,
image.geometricBounds[1] + offsetX,
image.geometricBounds[2] + offsetY,
image.geometricBounds[3] + offsetX
];
}
}
// Function to fit content in images with proportional adjustment for all shapes
function fitContentInImagesProportionally(object, fitOption) {
if ((object.constructor.name === "Rectangle" ||
object.constructor.name === "Oval" ||
object.constructor.name === "Polygon") && object.images.length > 0) {
object.fit(fitOption); // Use proportional fitting
} else if (object.constructor.name === "Group") {
for (var i = 0; i < object.allPageItems.length; i++) {
fitContentInImagesProportionally(object.allPageItems[i], fitOption);
}
}
}
// Check if the dimensions (width and height) are equal
if (areDimensionsEqual(firstWidth, firstHeight, secondWidth, secondHeight)) {
// Calculate the offset between the first and second object
var offsetX = secondBounds[1] - firstBounds[1];
var offsetY = secondBounds[0] - firstBounds[0];
// Adjust the image position for both objects
adjustImagePosition(firstObject, offsetX, offsetY);
adjustImagePosition(secondObject, -offsetX, -offsetY);
// Adjust image positions within groups if necessary
adjustGroupImagesPosition(firstObject, offsetX, offsetY);
adjustGroupImagesPosition(secondObject, -offsetX, -offsetY);
} else {
// Use FILL_PROPORTIONALLY option for fitting images without stretching
var fitOptions = FitOptions.FILL_PROPORTIONALLY;
// Fit content in images in both objects using proportional fitting for all shapes
fitContentInImagesProportionally(firstObject, fitOptions);
fitContentInImagesProportionally(secondObject, fitOptions);
// Adjust image positions within groups if necessary
adjustGroupImagesPosition(firstObject, 0, 0);
adjustGroupImagesPosition(secondObject, 0, 0);
}
}
}
}, ScriptLanguage.JAVASCRIPT, null, UndoModes.ENTIRE_SCRIPT, "Swap Object Sizes and Positions");
Copy link to clipboard
Copied
Hi @SmythWharf , I’m sure I’m missing something, but is there a reason you can’t just swap the two object‘s x, y positions? Something like this:
if (app.selection.length !== 2) {
alert("Please select exactly two objects.");
} else {
var o1 = app.selection[0];
var b1 = o1.geometricBounds
var o2 = app.selection[1];
var b2 = o2.geometricBounds
o1.move([b2[1], b2[0]])
o2.move([b1[1], b1[0]])
}
Before and after:
Copy link to clipboard
Copied
At a guess, it's a bounding box issue? But the xy swap works well.
Copy link to clipboard
Copied
Not sure, but I think it's because you are using .images instead of .graphics
Copy link to clipboard
Copied
Had a little look into it thank you all for the advice below is some updated code which from what I could test seems to swap the .eps files well
Best,
Smyth
//AutoSwap
app.doScript(function () {
if (app.selection.length !== 2) {
alert("Please select exactly two objects.");
} else {
var firstObject = app.selection[0];
var secondObject = app.selection[1];
// Check if either object is a GraphicLine
if (firstObject.constructor.name === "GraphicLine" || secondObject.constructor.name === "GraphicLine") {
alert("Cannot swap selection with a rule.");
return; // Exit the script if a GraphicLine is detected
}
// Ensure both objects are valid
if (!firstObject.isValid || !secondObject.isValid) {
alert("Invalid selection. Please select two valid objects.");
} else {
// Function to remember text frame settings
function rememberTextFrameSettings(object) {
if (object.constructor.name === "TextFrame") {
return {
verticalJustification: object.textFramePreferences.verticalJustification,
columnCount: object.textFramePreferences.textColumnCount,
isMultiColumn: object.textFramePreferences.textColumnCount > 1
};
}
return null;
}
// Function to apply text frame settings
function applyTextFrameSettings(object, settings) {
if (settings !== null) {
object.textFramePreferences.verticalJustification = settings.verticalJustification;
object.textFramePreferences.textColumnCount = settings.columnCount;
}
}
// Remember text frame settings
var firstSettings = rememberTextFrameSettings(firstObject);
var secondSettings = rememberTextFrameSettings(secondObject);
// Get the geometric bounds of both objects
var firstBounds = firstObject.geometricBounds;
var secondBounds = secondObject.geometricBounds;
// Calculate width and height from geometric bounds
var firstWidth = firstBounds[3] - firstBounds[1];
var firstHeight = firstBounds[2] - firstBounds[0];
var secondWidth = secondBounds[3] - secondBounds[1];
var secondHeight = secondBounds[2] - secondBounds[0];
// Function to compare width and height
function areDimensionsEqual(width1, height1, width2, height2) {
return Math.abs(width1 - width2) < 6 && Math.abs(height1 - height2) < 6; // Tolerance for floating-point precision
}
// Check if either object is a multi-column text frame
var isFirstMultiColumn = firstSettings && firstSettings.isMultiColumn;
var isSecondMultiColumn = secondSettings && secondSettings.isMultiColumn;
// Handle swapping based on the type of objects
if ((isFirstMultiColumn && !isSecondMultiColumn && secondObject.constructor.name === "Rectangle") ||
(!isFirstMultiColumn && isSecondMultiColumn && firstObject.constructor.name === "Rectangle")) {
// Swap geometric bounds only for multi-column text frame with picture
firstObject.geometricBounds = secondBounds;
secondObject.geometricBounds = firstBounds;
} else {
// Swap geometric bounds and apply text frame settings
firstObject.geometricBounds = secondBounds;
secondObject.geometricBounds = firstBounds;
// Apply text frame settings only if both are text frames
if (firstSettings && secondSettings) {
applyTextFrameSettings(firstObject, secondSettings);
applyTextFrameSettings(secondObject, firstSettings);
}
}
// Handle grouped objects specifically
function adjustGroupImagesPosition(group, offsetX, offsetY) {
if (group.constructor.name === "Group") {
for (var i = 0; i < group.allPageItems.length; i++) {
adjustMediaPosition(group.allPageItems[i], offsetX, offsetY);
}
}
}
// Function to adjust media position (images and graphics) within the new frame
function adjustMediaPosition(object, offsetX, offsetY) {
if ((object.constructor.name === "Rectangle" ||
object.constructor.name === "Oval" ||
object.constructor.name === "Polygon") &&
(object.images.length > 0 || object.graphics.length > 0)) {
// Handle both images and graphics (including .eps)
var media = object.images.length > 0 ? object.images[0] : object.graphics[0];
// Adjust geometric bounds for all shapes
media.geometricBounds = [
media.geometricBounds[0] + offsetY,
media.geometricBounds[1] + offsetX,
media.geometricBounds[2] + offsetY,
media.geometricBounds[3] + offsetX
];
}
}
// Function to fit content in images/graphics with proportional adjustment for all shapes
function fitContentInMediaProportionally(object, fitOption) {
if ((object.constructor.name === "Rectangle" ||
object.constructor.name === "Oval" ||
object.constructor.name === "Polygon") &&
(object.images.length > 0 || object.graphics.length > 0)) {
object.fit(fitOption); // Use proportional fitting
} else if (object.constructor.name === "Group") {
for (var i = 0; i < object.allPageItems.length; i++) {
fitContentInMediaProportionally(object.allPageItems[i], fitOption);
}
}
}
// Check if the dimensions (width and height) are equal
if (areDimensionsEqual(firstWidth, firstHeight, secondWidth, secondHeight)) {
// Calculate the offset between the first and second object
var offsetX = secondBounds[1] - firstBounds[1];
var offsetY = secondBounds[0] - firstBounds[0];
// Adjust the image/graphic position for both objects
adjustMediaPosition(firstObject, offsetX, offsetY);
adjustMediaPosition(secondObject, -offsetX, -offsetY);
// Adjust media positions within groups if necessary
adjustGroupImagesPosition(firstObject, offsetX, offsetY);
adjustGroupImagesPosition(secondObject, -offsetX, -offsetY);
} else {
// Use FILL_PROPORTIONALLY option for fitting media without stretching
var fitOptions = FitOptions.FILL_PROPORTIONALLY;
// Fit content in media in both objects using proportional fitting for all shapes
fitContentInMediaProportionally(firstObject, fitOptions);
fitContentInMediaProportionally(secondObject, fitOptions);
// Adjust media positions within groups if necessary
adjustGroupImagesPosition(firstObject, 0, 0);
adjustGroupImagesPosition(secondObject, 0, 0);
}
}
}
}, ScriptLanguage.JAVASCRIPT, null, UndoModes.ENTIRE_SCRIPT, "Swap Object Sizes and Positions");