///////////////////////////////////////////////////////////////// //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) nvkelso2008@gmail.com (but remove the 2008 bit) // "Multiple-object-replacement" hack by Iain Henderson // iain@addition.com.au // //>=-------------------------------------- // 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 ( john@wundes.com ) 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