• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Transform all objects by multiplier

Community Beginner ,
May 30, 2017 May 30, 2017

Copy link to clipboard

Copied

Hi there!

I'm new to scripting and I can't find an example of a javascript that mimics Transform panel behaviour.

I need to change width or height of all selected objects that are on different layers (without grouping) by certain set of multipliers (I don't wanna input them manually every time). And that objects should be transformed relative to the center reference point.

I've tried different solutions that I've found on the internet but I can't figure out how to do that.

When I do it manually I hit Ctrl+A, then type in Transform panel [*0,6512], hit Enter. So I want to automate it.

Is that possible? Could someone help me please?

TOPICS
Scripting

Views

1.6K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
People's Champ ,
May 30, 2017 May 30, 2017

Copy link to clipboard

Copied

Transfomations are both easy to apply and tough to acquire (Understanding CoordinateSpaces, reference points, bridges between points and contextual units). You may be interested in PageItem Collection's transform() method :

InDesign ExtendScript API (10.0)

And in UnitValue, always valuable to use in combination with transform:

http://www.indesignjs.de/extendscriptAPI/indesign10/#UnitValue.html

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 30, 2017 May 30, 2017

Copy link to clipboard

Copied

Loic, I don't believe Illustrator has that same functionality as the Illustrator API is severely anemic compared with InDesign's API.

eoneof, What you're looking for is definitely doable, but requires a few custom components and calculations to make sure the art is resized relative to the center of a given reference point.

Do you have any code written you'd like us to help with or are you looking for someone to write the code?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 30, 2017 May 30, 2017

Copy link to clipboard

Copied

I have a suitable piece of code from other script:

if ( documents.length > 0)

  mySelection = activeDocument.selection;

  if (mySelection instanceof Array) {

  initBounds = mySelection[0].visibleBounds;

  ul_x = initBounds[0];

  ul_y = initBounds[1];

  lr_x = initBounds[2];

  lr_y = initBounds[3];

  for (i=1; i<mySelection.length; i++) {

  groupBounds = mySelection.visibleBounds;

  if (groupBounds[0]<ul_x){ul_x=groupBounds[0]}

  if (groupBounds[1]>ul_y){ul_y=groupBounds[1]}

  if (groupBounds[2]>lr_x){lr_x=groupBounds[2]}

  if (groupBounds[3]<lr_y){lr_y=groupBounds[3]}

              var wid = lr_x-ul_x 

              alert (wid)

  }

           

  }

Here I managed to get to know current objects' width, but I have no idea what's next.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 30, 2017 May 30, 2017

Copy link to clipboard

Copied

when you say "current object" do you mean the current selection?

That snippet seems needlessly cryptic. But perhaps it's just a different style than i'm used to writing. It looks like that snippet alerts the difference between lr_x and ul_x (initBounds[2] - initBounds[0]) which is the right edge - left edge.

This is a way to give you the information about the width of multiple ungrouped objects, but it will not help you to resize anything since you cannot resize a selection of objects. You can only resize a single object at a time. So you can either loop each object and resize it individually (which would then require additional logic to reposition it so it's in the same relative position to your chosen reference point) or else you could take the existing selection, temporarily group it together, resize the entire group at once, then ungroup it.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 30, 2017 May 30, 2017

Copy link to clipboard

Copied

Yes, you are right, I meant current selection.

I added these rows to be shure I'm on the right way:

  1. var wid = lr_x-ul_x   
  2.               alert (wid)

It shows width:

scrn-20170530-002.png

Unfortunately grouping is not acceptable as I need objects to be on certain layers. It would take more manual work to sort them back, than transforming

Anyway, I'd like to know how to transform group?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
May 30, 2017 May 30, 2017

Copy link to clipboard

Copied

williamadowling​ I constantly jump from InDesign Scripting forum to here and sometimes I miss the fact I am not in the good room My apologises for those being misleaded.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
May 30, 2017 May 30, 2017

Copy link to clipboard

Copied

So to be illustratorly useful :

var sel = app.selection;

var n = sel.length;

while ( n-- ) sel.resize ( 50, 50 )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 30, 2017 May 30, 2017

Copy link to clipboard

Copied

Loic,

This will work to resize each item, but each item will be resized relative to it's own center, which means that if you resize two items, their positions (relative to one another) will change. See this screenshot as an example.

http://imgur.com/xyn8Bdh 

In order to resize each piece individually, you'll also have to include logic that repositions the art after it's resized so it's placement relative to the desired reference point, remains the same.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
May 30, 2017 May 30, 2017

Copy link to clipboard

Copied

You can perform a transform like how you wish by script only, without having to necessarily use a document selection. This can be done by temporarily changing your document's origin to a desired location and performing the transform scripting commands then. The origin would be in the center of the bounding box of the art in question, or any arbitrary point.

Re: Rotate around a custom pivot???

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
May 31, 2017 May 31, 2017

Copy link to clipboard

Copied

Ok I think I got it :

Before reduction ( reduced objects have been converted to rulers so we can have a clue of where objects have to be eventually)

Capture d’écran 2017-05-31 à 12.55.33.png

Once the script is applied, objects are nicely resized:

Capture d’écran 2017-05-31 à 12.55.42.png

HTH

Loic

Ozalto | Productivity Oriented - Loïc Aigon

//Main routine

var main = function() {

  var sel;

   

  //Exit if no documents open

    if ( !app.documents.length ) return;

   

    sel = app.selection;

   

  //Exit if no selection

    if ( !sel.length ) return;

  //Exit if selection is  range of text characters

  if ( sel.typename == "TextRange" ) {

  alert( "Please select pageItems and run again…");

  return;

  }

   

  //Apply reduction

  try {

  reduceSelection ( sel, 50, 50 );

  }

  catch ( err ) {

  alert( err.line+">>"+err.message );

  }

};

//reduction routine

var reduceSelection = function( sel,  wRatio, hRatio ) {

  //-- VARS

  var n = sel.length, gx1, gx2, gy1, gy2, items = [], item,

  ix1, ix2, iy1, iy2, mx, my, iLeft, iTop;

  // Looping through selection items

  // to compute the boundaries of the pseudo group

  // and in extenso the reference point in the center of that area

  while ( n-- ) {

  item  = sel;

  ix1 = item.left;

  ix2 = item.left+item.width;

  iy1 = item.top;

  iy2 = item.top-item.height;

  (typeof(gx1)=="undefined"||ix1<gx1) && gx1 = ix1;

  (typeof(gx2)=="undefined"||ix2>gx2) && gx2 = ix2;

  (typeof(gy1)=="undefined"||iy1>gy1) && gy1 = iy1;

  (typeof(gy2)=="undefined"||iy2<gy2) && gy2 = iy2;

  }

  //Computing central point values

  mx = gx1+(gx2-gx1)/2;

  my = gy1+(gy2-gy1)/2;

  //Looping over items so they can be resized and relocated in reference to the central point in [mx,my]

  n = sel.length;

  while ( n-- ) {

  item = sel;

  ix1 = item.left;

  iy1 = item.top;

  //Storing initial value of top/left position of the item

  iLeft = item.left;

  iTop = item.top;

  //resizing item

  item.resize ( wRatio, hRatio );

  //Moving item to its initial location in order to prevent computation corruption

  item.left = iLeft;

  item.top = iTop;

  //Moving resized item to the correct location

  if ( iLeft<mx ) {

  item.left+= (mx-iLeft)*wRatio/100;

  }

  else {

  item.left-= (iLeft-mx)*wRatio/100;

  }

  if (  iTop<mx ) {

  item.top+= (my-iTop)*hRatio/100;

  }

  else {

  item.top-= (my-iTop)*hRatio/100;

  }

  }

}

//YOLO

main();

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 02, 2017 Jun 02, 2017

Copy link to clipboard

Copied

Wow, that's quite complicated. I didn't even know that that "simple" operation would take so many computations. I apreciate your help.

The script works as expected but... Excuse me for my noob quiestion: what exactly should I change to transform W & H separately with custom values ?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 02, 2017 Jun 02, 2017

Copy link to clipboard

Copied

Line 21. The second and third arguments. the second argument is "wRatio" and the third is "hRatio".

So let's say you wanted to scale the width to 20% and the height to 65%. Change line 21 to this:

reduceSelection ( sel, 20, 65 );

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jun 03, 2017 Jun 03, 2017

Copy link to clipboard

Copied

Hi Loic, there has a problem with your above code: if the document's rulerOrigin is lower than the selection's bottom, objects will be wrongly positioned after scaled.

It's more easy to use

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jun 07, 2017 Jun 07, 2017

Copy link to clipboard

Copied

LATEST

moluapple

Indeed.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 31, 2017 May 31, 2017

Copy link to clipboard

Copied

This is exactly what I had in mind, Loic. Good work.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
May 31, 2017 May 31, 2017

Copy link to clipboard

Copied

Thanks williamadowling

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jun 02, 2017 Jun 02, 2017

Copy link to clipboard

Copied

Exactly.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines