Skip to main content
Known Participant
September 16, 2024
Answered

Need a script that can copy the width of one object and paste that width onto another object

  • September 16, 2024
  • 2 replies
  • 1303 views

Hello, my job requires a lot of scaling one object to match another object.

It would be super convenient to have my workflow look like this:

1. Select first object, run script to copy width.

2. Select second object, run script to paste width. Now they are the same width.

 

I imagine they would be two separate scripts. Could I possibly have help with this? 

I'm aware that scripts like MatchObject exists but it's not what I'm looking for. I don't want to have to constantly select settings in a dialogue box. Assigning scripts to F1 and F2 would make it just a couple button presses.

 

Thanks in advance.

Correct answer jduncan

So below are two scripts...

 

The first script gets the "visible" bounds of the first selected object and saves them as an environment variable. 

// scale_get.jsx

// get the "visibleBounds" of the first item of the app selection
var sourceItem = app.activeDocument.selection[0];

// get the "visible" bounds of the sourceItem
// https://ai-scripting.docsforadobe.dev/scripting/positioning.html#art-item-bounds
// to use a different type of bounds update the line below
var sourceBounds = sourceItem.visibleBounds;

// save sourceBounds to an environment variable so it can be retrieved by second script
$.setenv("scaleTargetBounds", sourceBounds.toSource());

 

After running the first script, make sure to select the objects you want to scale (multiple objects are allowed), then run this second script.

// scale_apply.jsx

// get source bounds from first script
var sourceBounds = eval($.getenv("scaleTargetBounds"));

// iterate over each selected object and scale to match source object width
var target, targetBounds, scaleFactor, scaleMatrix;
for (var i = 0; i < app.activeDocument.selection.length; i++) {
  target = app.activeDocument.selection[i];
  // if you change the type of bounds in the first script, you need to change her as well
  targetBounds = target.visibleBounds;
  // calculate the scale factor between the source and current target widths
  scaleFactor =
    ((sourceBounds[2] - sourceBounds[0]) / (targetBounds[2] - targetBounds[0])) * 100;
  // generate a scale matrix
  scaleMatrix = app.getScaleMatrix(scaleFactor, scaleFactor);

  // apply the matrix using the transform method
  // https://ai-scripting.docsforadobe.dev/jsobjref/PageItem.html#pageitem-transform
  target.transform(
    scaleMatrix,
    true, // change positions
    true, // change fill patterns
    true, // change fill gradients
    true, // change stroke patterns
    true, // change stroke width
    Transformation.CENTER // anchor point https://ai-scripting.docsforadobe.dev/jsobjref/scripting-constants.html#transformation
  );
}

 

Please note, you may want to use a different type of bounds other than "visible". There are comments in the scripts of where you need to make the change as well as links to the documentation. There are also options to scale the properties of the target objects (patterns, gradients, strokes) that you may want to read the docs on. You can also choose an anchor point for the scaling transformation.

 

Try these out and let me know if you have any questions? Cheers!

2 replies

jduncan
Community Expert
jduncanCommunity ExpertCorrect answer
Community Expert
September 17, 2024

So below are two scripts...

 

The first script gets the "visible" bounds of the first selected object and saves them as an environment variable. 

// scale_get.jsx

// get the "visibleBounds" of the first item of the app selection
var sourceItem = app.activeDocument.selection[0];

// get the "visible" bounds of the sourceItem
// https://ai-scripting.docsforadobe.dev/scripting/positioning.html#art-item-bounds
// to use a different type of bounds update the line below
var sourceBounds = sourceItem.visibleBounds;

// save sourceBounds to an environment variable so it can be retrieved by second script
$.setenv("scaleTargetBounds", sourceBounds.toSource());

 

After running the first script, make sure to select the objects you want to scale (multiple objects are allowed), then run this second script.

// scale_apply.jsx

// get source bounds from first script
var sourceBounds = eval($.getenv("scaleTargetBounds"));

// iterate over each selected object and scale to match source object width
var target, targetBounds, scaleFactor, scaleMatrix;
for (var i = 0; i < app.activeDocument.selection.length; i++) {
  target = app.activeDocument.selection[i];
  // if you change the type of bounds in the first script, you need to change her as well
  targetBounds = target.visibleBounds;
  // calculate the scale factor between the source and current target widths
  scaleFactor =
    ((sourceBounds[2] - sourceBounds[0]) / (targetBounds[2] - targetBounds[0])) * 100;
  // generate a scale matrix
  scaleMatrix = app.getScaleMatrix(scaleFactor, scaleFactor);

  // apply the matrix using the transform method
  // https://ai-scripting.docsforadobe.dev/jsobjref/PageItem.html#pageitem-transform
  target.transform(
    scaleMatrix,
    true, // change positions
    true, // change fill patterns
    true, // change fill gradients
    true, // change stroke patterns
    true, // change stroke width
    Transformation.CENTER // anchor point https://ai-scripting.docsforadobe.dev/jsobjref/scripting-constants.html#transformation
  );
}

 

Please note, you may want to use a different type of bounds other than "visible". There are comments in the scripts of where you need to make the change as well as links to the documentation. There are also options to scale the properties of the target objects (patterns, gradients, strokes) that you may want to read the docs on. You can also choose an anchor point for the scaling transformation.

 

Try these out and let me know if you have any questions? Cheers!

paloma95Author
Known Participant
September 17, 2024

Firstly I just want to say thank you for the scripts! I tried them out and noticed something a little strange. When I use the script to copy the width of a box and then use the next script to paste it onto some artwork, the width is a little off.

Width of box copied: 3.5in

Width of artwork after I paste width: 3.5139in

Any idea why this may be? Thanks!

paloma95Author
Known Participant
September 17, 2024

I also want to add that it's important that the height stays porportional to the width. Any help appreciated!