很早是从github搜索到,用来批量替换logo时比较好用,最近在拼版工作中比较好用,所以复制一份改名 A 拼版替换对齐
。
脚本在处理很多物件的时候会报错BUG,哪天有空 精简一下,看看能否提高效率。
Adobe Illustrator 拼版替换对齐.jsx
/////////////////////////////////////////////////////////////////
//Copy to Object(s) v7 -- CS,CS2,CS3
// Hacked again by Nathaniel Vaughn KELSO
// Last modified: 2008.March.30
// Created: 2007.July.7
// at Hyattsville, MD
// Version 2
// (c) [email protected] (but remove the 2008 bit)
// "Multiple-object-replacement" hack by Iain Henderson
// [email protected]
//
//>=--------------------------------------
// User selects two (or more) objects:
// This script copies the top most object to the position and size of
// all other selected objects.
//
//Version 2 update: now adjusts stroke based on difference in area.
//Version 3 update: now accepts multiple targets (Thanks Iain)
//Version 4 update: Deselects everything but source object
// --this makes it easy to delete the source object if you wish,
// -- also this makes the older "Replace-Object" script obsolete.
//Version 5 update: option to NOT transform to fit original shape
// -- with additional option flag to register the replacing shape to
// the being-replaced shape's center instead of upper-left corner
//TODO: add flag to delete "master" replacing symbol on completion
//>=--------------------------------------
// JS code (c) copyright: John Wundes ( [email protected] ) www.wundes.com
//copyright full text here: http://www.wundes.com/js4ai/copyright.txt
//////////////////////////////////////////////////////////////////
//initialize vars
//
//*******************************************************
// Toggles for scaling object, fitting to original, offset to center
//toggle for scaling stroke: set to true to scale stroke.
var scaledStroke = false; // when fitting original dimensions, scale the stroke
var scaledObject = false; // fit to original dimensions
var scaleMethod = "scaleToFit"; // if true, do NOT scale to fit original bounds but favor the smallest percentage of X or Y scaling for both X and Y
var scalingCentered = true; // register with center of being-replaced object
var groupFindAndReplaceResults = false; // often not desired
var keepReplacedSelected = true; // the result
var keepReplaceWithObjSelected = true; // the model object that everything is replaced with
var deleteReplaceWithObj = true; // the model object that everything is replaced with
var selObjs = "Please select at least two objects on the page.";
var docRef = activeDocument;
if (documents.length>0) {
if (docRef.selection.length > 1) {
mySelection = docRef.selection;
var sourceObj = docRef.selection[0];
//if object is a (collection of) object(s) not a text field.
if (mySelection instanceof Array) {
//*******************************************************
//create stroke Array
var strokeArray = new Array();
//create bounding objects
//********************************************************
var origBounds = mySelection[0].geometricBounds;
//define paramaters of top object
var oul_x = origBounds[0];
var oul_y = origBounds[1];
var olr_x = origBounds[2];
var olr_y = origBounds[3];
var oSelWidth = (olr_x-oul_x);
var oSelHeight = (oul_y-olr_y);
var oSelPos = [oul_x, oul_y];
// *********************************************************
var initBounds;
var ul_x;
var ul_y;
var lr_x;
var lr_y;
var mySelWidth;
var mySelHeight;
var mySelPos;
var alterObjectArray = new Array();
for (var i=0; i < mySelection.length; i++) {
eval('subArray' + i + '=' + 'new Array()');
eval('subArray' + i + '["object"]' + '=' + mySelection[i]);
initBounds = mySelection[i].geometricBounds;
ul_x = initBounds[0];
ul_y = initBounds[1];
lr_x = initBounds[2];
lr_y = initBounds[3];
mySelWidth = (lr_x-ul_x);
mySelHeight = (ul_y-lr_y);
mySelPos = [ul_x, ul_y];
mySelOffsetXpos = (ul_x + mySelWidth / 2 - oSelWidth / 2);
mySelOffsetYpos = (ul_y - mySelHeight / 2 + oSelHeight / 2);
eval('subArray' + i + '["width"]=' + mySelWidth);
eval('subArray' + i + '["xpos"]=' + ul_x);
eval('subArray' + i + '["ypos"]=' + ul_y);
eval('subArray' + i + '["height"]=' + mySelHeight);
eval('subArray' + i + '["offsetXpos"]=' + mySelOffsetXpos);
eval('subArray' + i + '["offsetYpos"]=' + mySelOffsetYpos);
eval('alterObjectArray.push(subArray' + i + ')');
}
for (var i=1; i < alterObjectArray.length; i++) {
//find proportional Difference
//average height and width to find new stroke
if (scaledStroke == true ) {
var wdiff = mySelWidth/oSelWidth;
var whght = mySelHeight/oSelHeight;
var propDiff = (wdiff+whght)/2;
} else {
var propDiff = 1;
}
//mark stroked Items
//apply transforms
var newGroup = mySelection[i].parent.groupItems.add();
//modify move behavior for changes in JS for CS...
if (version == "10.0") {
newGroup.moveToEnd(mySelection[i].parent);
tempItem = mySelection[0].duplicate( mySelection[i], ElementPlacement.PLACEBEFORE);
tempItem.moveToEnd(newGroup);
} else {
newGroup.move(mySelection[i], ElementPlacement.PLACEBEFORE);
mySelection[0].duplicate(newGroup, ElementPlacement.PLACEATEND);
}
markStroked(newGroup);
// Check to see if the replacing object should be scaled down/up to fit the dimensions of the being-replaced object
if ( scaledObject == true) {
eval('newGroup.position = [alterObjectArray['+i+']["xpos"], alterObjectArray['+i+']["ypos"]]');
//eval('newGroup.position = [alterObjectArray['+i+']["offsetXpos"], alterObjectArray['+i+']["offsetYpos"]]');
newGroupWidth = newGroup.width;
newGroupHeight = newGroup.height;
tempObjCenterX = newGroup.position[0] + newGroup.width / 2;
tempObjCenterY = newGroup.position[1] - newGroup.height /2;
replacingWidth = eval('newGroup.width = alterObjectArray[' + i +']["width"]');
replacingHeight = eval('newGroup.height = alterObjectArray['+ i +']["height"]');
switch( scaleMethod) {
case "proportionalX":
if( newGroupWidth >= newGroupHeight ) {
eval('newGroup.height = alterObjectArray['+ i +']["width"]');
eval('newGroup.width = alterObjectArray['+ i +']["width"]');
// now offset X as needed
if( newGroup.height >= mySelection[0].height ) {
newGroup.top = newGroup.top + replacingHeight / 2;
} else {
newGroup.top = newGroup.top - replacingHeight / 2;
}
} else {
eval('newGroup.height = alterObjectArray['+ i +']["height"]');
eval('newGroup.width = alterObjectArray['+ i +']["height"]');
// now offset X as needed
newGroup.left = newGroup.left + replacingWidth / 2;
}
break;
case "proportionalY":
if( newGroupWidth >= newGroupHeight ) {
eval('newGroup.height = alterObjectArray['+ i +']["height"]');
eval('newGroup.width = alterObjectArray['+ i +']["height"]');
// now offset X as needed
if( newGroup.width >= mySelection[0].width ) {
newGroup.left = newGroup.left - replacingWidth / 2;
} else {
newGroup.left = newGroup.left + replacingWidth / 2;
}
} else {
eval('newGroup.height = alterObjectArray['+ i +']["width"]');
eval('newGroup.width = alterObjectArray['+ i +']["width"]');
// now offset X as needed
newGroup.top = newGroup.top + replacingHeight / 2;
}
break;
case "proportionalXY":
xy_Average = ( eval('alterObjectArray['+ i +']["height"]') + eval('alterObjectArray[' + i +']["width"]') ) /2;
newGroup.height = xy_Average;
newGroup.width = xy_Average;
if( newGroup.width >= mySelection[0].width ) {
newGroup.left = (newGroup.left + newGroup.width / 2 - replacingWidth / 2);
} else {
newGroup.left = (newGroup.left + newGroup.height / 2 - replacingHeight / 2);
}
if( newGroup.height >= mySelection[0].height ) {
newGroup.top = (newGroup.top + newGroup.height / 2 - replacingHeight / 2);
} else {
newGroup.top = (newGroup.top + newGroup.height / 2 + replacingHeight / 2);
}
break;
case "scaleToFit":
default:
eval('newGroup.height = alterObjectArray['+ i +']["height"]');
eval('newGroup.width = alterObjectArray[' + i +']["width"]');
break;
}
tempGroupWidth = newGroup.width;
tempGroupHeight = newGroup.height;
// now offset Y as needed
//newGroup.top = newGroup.top + newGroupHeight / 2 - tempGroupHeight / 2;
} else {
// Check to see if the replacing object should be registered to the upper left corer of
// the being-replaced objects or if it should be centered on the being-replaced object
if( scalingCentered == true ) {
eval('newGroup.position = [alterObjectArray['+i+']["offsetXpos"], alterObjectArray['+i+']["offsetYpos"]]');
} else {
eval('newGroup.position = [alterObjectArray['+i+']["xpos"], alterObjectArray['+i+']["ypos"]]');
}
}
mySelection[i].remove();
//restroke with new proportions
scaleStroke(strokeArray, propDiff);
howManyGroupItems = newGroup.pageItems.length - 1;
if( groupFindAndReplaceResults ) {
// they are already grouped
if( keepReplacedSelected ) {
theMovedObject.selected = true;
} else {
theMovedObject.selected = false;
}
} else {
// but was the original a group?
if( mySelection[0].typename == "GroupItem" ) {
// do nothing
if( keepReplacedSelected ) {
newGroup.selected = true;
} else {
newGroup.selected = false;
}
} else {
for( g=0; g<=howManyGroupItems; g++ ) {
theMovedObject = newGroup.pageItems[g].duplicate( newGroup, ElementPlacement.PLACEBEFORE );
if( keepReplacedSelected ) {
theMovedObject.selected = true;
} else {
theMovedObject.selected = false;
}
}
// now that the group is empty of items, delete the group
newGroup.remove();
}
}
}
// Do we want to have the "replacing" object SELECTED after the result is processed and displayed (and may be selected)?
if( keepReplaceWithObjSelected ) {
sourceObj.selected = true;
} else {
sourceObj.selected = false;
}
// Do we want to have the "replacing" object DELETED after the result is processed and displayed (and may be selected)?
if( deleteReplaceWithObj ) {
sourceObj.remove();
}
} else {
alert(selObjs);
}
} else {
alert(selObjs);
}
}
//Create the stroke Object that goes into the stroke Array.
// contains the items colorObject, and it's initial stroke weight.
function strokeObj(pName, strokeWt) {
this.pName = pName;
this.strokeWt = strokeWt;
}
function markStroked(Sel) {
var slen = Sel.length;
// if selected is a single object...
if (Sel.typename == "GroupItem") {
markStroked(Sel.pageItems);
} else if (Sel.typename == "CompoundPathItem") {
//add object and stroke weight to the array...
myColor = Sel.pathItems[0];
myWt = myColor.strokeWidth;
bob = new strokeObj(myColor, myWt);
strokeArray.push(bob);
} else if (Sel.typename == "TextFrame") {
if (Sel.textRange.characterAttributes.strokeColor.typename != "NoColor") {
var clMax = Sel.textRange.characters.length;
for (var cl=0; cl<clMax; cl++) {
myColor = Sel.textRange.characters[0].characterAttributes;
myWt = myColor.strokeWeight;
bob = new strokeObj(myColor, myWt);
strokeArray.push(bob);
}
}
}
// if selected contains more than one object...
for (var a=0; a<slen; a++) {
if (Sel[a].typename == "GroupItem") {
//alert("a group in markStroke");
markStroked(Sel[a].pageItems);
} else if (Sel[a].typename == "CompoundPathItem") {
myColor = Sel[a].pathItems[0];
myWt = myColor.strokeWidth;
bob = new strokeObj(myColor, myWt);
strokeArray.push(bob);
} else if (Sel[a].typename == "PathItem") {
if (Sel[a].stroked == true) {
myColor = Sel[a];
myWt = myColor.strokeWidth;
bob = new strokeObj(myColor, myWt);
strokeArray.push(bob);
}
} else if (Sel[a].typename == "TextFrame") {
if (Sel[a].textRange.characterAttributes.strokeColor.typename != "NoColor") {
var clMax = Sel[a].textRange.characters.length;
for (var cl=0; cl<clMax; cl++) {
myColor = Sel[a].textRange.characters[cl].characterAttributes;
myWt = myColor.strokeWeight;
bob = new strokeObj(myColor, myWt);
strokeArray.push(bob);
}
}
}
}
}
function scaleStroke(mySlx, strokeScale) {
var slen = mySlx.length;
for (var a=0; a<slen; a++) {
//set it's strokeweight or strokewidth, whatever... :)
mySlx[a].pName.strokeWidth = mySlx[a].strokeWt*strokeScale;
mySlx[a].pName.strokeWeight = mySlx[a].strokeWt*strokeScale;
}
}