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

How to move and align objects with scripts?

Contributor ,
Aug 17, 2022 Aug 17, 2022

Copy link to clipboard

Copied

How to automatically move and align objects with scripts as below shown? Any help would be greatly appreciated, Thanks in advance!

 

1X.png

 

Final effect:

2X.png

TOPICS
Scripting

Views

3.1K

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

correct answers 3 Correct answers

Valorous Hero , Aug 18, 2022 Aug 18, 2022

Given simple line-art you can simply loop the items to correct their .top and .left properties. As these objects are the same dimensions with the example they will by definition already be aligned centrally to the targets.

Assuming that your layers are just as you have them:
var targetObjects = doc.layers.getByName("Target Position").pathItems;
var objectsToMove = [
  doc.layers.getByName("To move aligned objects").layers[0].pathItems[0],

  doc.layers.getByName("To move aligned objects").layers[1].

...

Votes

Translate

Translate
Community Expert , Aug 18, 2022 Aug 18, 2022

As @Silly-V noted, if the objects are simple it's the script can be simple. When I tackled this a while back, I found the objects I needed to align are rarely simple so I wrote MatchObjects.jsx. Basically, you pick a source object (either the top or bottom object of your selection) and choose how to "match" all of the other objects in your selection to it. It does more than just aligning, but it may get you headed in the right direction. @Disposition_Dev helped with some edge cases for the `getV

...

Votes

Translate

Translate
Community Expert , Aug 18, 2022 Aug 18, 2022

I actually created some alignment utilities for public use a while back. Given a "key object" and an array of objects you want to align, it handles all the positioning quirks (including the visible bounds thing that @jduncan mentioned).

 

The initial implementation was pretty clunky and awfully repetitive. So I just took some time and simpilified it. It used to be discreet functions for each different alignment option... silly. So i condensed it all down to one function called align() which take

...

Votes

Translate

Translate
Adobe
Valorous Hero ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied

Given simple line-art you can simply loop the items to correct their .top and .left properties. As these objects are the same dimensions with the example they will by definition already be aligned centrally to the targets.

Assuming that your layers are just as you have them:
var targetObjects = doc.layers.getByName("Target Position").pathItems;
var objectsToMove = [
  doc.layers.getByName("To move aligned objects").layers[0].pathItems[0],

  doc.layers.getByName("To move aligned objects").layers[1].pathItems[0],

  doc.layers.getByName("To move aligned objects").layers[2].pathItems[0]
];

for (var i = 0; i < objectsToMove.length; i++) {

  objectsToMove[i].top = targetObjects[i].top;

  objectsToMove[i].left = targetObjects[i].left;

}

 

This is a very rudimentary example and it can work with your specific situation because of the object dimensions and the order of target and source items is the same. The order actually does not have to be the same in the layers, as long as you ensure to put them into the same order within your code so when the loop runs, it will be directed to match the proper target and source items.

 

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 ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied

As @Silly-V noted, if the objects are simple it's the script can be simple. When I tackled this a while back, I found the objects I needed to align are rarely simple so I wrote MatchObjects.jsx. Basically, you pick a source object (either the top or bottom object of your selection) and choose how to "match" all of the other objects in your selection to it. It does more than just aligning, but it may get you headed in the right direction. @Disposition_Dev helped with some edge cases for the `getVisibleBounds()` that help with matching complex objects.

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
Contributor ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied

Thank you @jduncan very much for your explanation! I also found many useful scripts on your GitHub project, especially the rename layers JSX, it may solve a problem that has troubled me for a long time, in the following post. I need some time to learn how to use your script. Thank you again for sharing this.👍👍

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
Contributor ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied

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
Contributor ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied

Unfortunately, after my simple test, for rename layers JSX,its search range is only the parent layer and cannot include all the sublayers. Is it like this? Or do I not set it correctly? Do you perhaps have an idea what I may be overlooking? Thanks @jduncan .

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 ,
Aug 19, 2022 Aug 19, 2022

Copy link to clipboard

Copied

So, I tried to piece together what you are looking to accomplish from the few different posts you have going right now. If you can get the layer duplication method (using actions) working that @Silly-V explained here, then with a slight tweak to my rename script will work for you.

 

After following @Silly-V's advice, you should have a bunch of duplicate layers in your layers palette (like left side in pic). The script below renames all of your base layers from 1 to however many layers you have. Then it recursively goes through every sublayer within each base layer and removes the "copy" text that gets added when you duplicate a layer.

 

Hope this helps!

 

layer-rename.png

 

// Do all of the layer duplications first as explained by Silly-V

// grab the current document and its layers
var doc = app.activeDocument;
var layers = doc.layers;

// iterate through all layers from bottom to top
for (var i = doc.layers.length - 1; i > -1; i--) {
  doc.layers[i].name = Math.abs(i - doc.layers.length);
  // recursively remove "copy" every sublayer
  recursiveRename(doc.layers[i]);
}

function recursiveRename(parent) {
  for (var i = 0; i < parent.layers.length; i++) {
    parent.layers[i].name = parent.layers[i].name.replace(/\scopy.*$/, "");
    recursiveRename(parent.layers[i]);
  }
}

 

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
Contributor ,
Aug 20, 2022 Aug 20, 2022

Copy link to clipboard

Copied

This works perfectly!!! Thank you very much for solving the problem that has troubled me for a long time! You are really excellent and admirable, not only "Ai Command Palette"  @jduncan 👍👍

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
Contributor ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied

Thank you @Silly-V  for pointing me in the right direction!

 

I have just started to learn JavaScript, and I have been using VBA before (thanks to the advice and help of @Disposition_Dev  and @CarlosCanto , let me enter the world of JS). This forum is a good place to start!
I want to ask you a question about the following method of declaring variables:

var objectsToMove = [
  doc.layers.getByName("To move aligned objects").layers[0].pathItems[0],

  doc.layers.getByName("To move aligned objects").layers[1].pathItems[0],

  doc.layers.getByName("To move aligned objects").layers[2].pathItems[0]
];

 

I'm curious about this declaration method. It seems that this variable is defined with a constant value pathitems [0] ? When it is objectsToMove[i], what value is the objectsToMove ? Is it below?

 

 doc.layers.getByName("To move aligned objects").layers[0].pathItems[i],

 doc.layers.getByName("To move aligned objects").layers[1].pathItems[i],

 doc.layers.getByName("To move aligned objects").layers[2].pathItems[i]

 

I really don't understand why it can be like this?

 

And what value is the objectsToMove.length ?Is it layers [0]. pathitems length? or layers[1].pathItems. length? or layers[2].pathItems. length? Or the sum of them? If the number of pathitems in each layer is different, can it be executed correctly?

 

Many thanks in advance for your time and advice!

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
Contributor ,
Aug 19, 2022 Aug 19, 2022

Copy link to clipboard

Copied

Hey, @Silly-V 

 

Can you help me answer this question?  Many thanks in advance for your time and advice! 

 

quote

Thank you @Silly-V  for pointing me in the right direction!

 

I have just started to learn JavaScript, and I have been using VBA before (thanks to the advice and help of @Disposition_Dev  and @CarlosCanto , let me enter the world of JS). This forum is a good place to start!
I want to ask you a question about the following method of declaring variables:

 

var objectsToMove = [
  doc.layers.getByName("To move aligned objects").layers[0].pathItems[0],

  doc.layers.getByName("To move aligned objects").layers[1].pathItems[0],

  doc.layers.getByName("To move aligned objects").layers[2].pathItems[0]
];

 

 

I'm curious about this declaration method. It seems that this variable is defined with a constant value pathitems [0] ? When it is objectsToMove[i], what value is the objectsToMove ? Is it below?

 

 doc.layers.getByName("To move aligned objects").layers[0].pathItems[i],

 doc.layers.getByName("To move aligned objects").layers[1].pathItems[i],

 doc.layers.getByName("To move aligned objects").layers[2].pathItems[i]

 

I really don't understand why it can be like this?

 

And what value is the objectsToMove.length ?Is it layers [0]. pathitems length? or layers[1].pathItems. length? or layers[2].pathItems. length? Or the sum of them? If the number of pathitems in each layer is different, can it be executed correctly?

 

Many thanks in advance for your time and advice!


By @Raymond ZJH

 

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 ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied

I actually created some alignment utilities for public use a while back. Given a "key object" and an array of objects you want to align, it handles all the positioning quirks (including the visible bounds thing that @jduncan mentioned).

 

The initial implementation was pretty clunky and awfully repetitive. So I just took some time and simpilified it. It used to be discreet functions for each different alignment option... silly. So i condensed it all down to one function called align() which takes 3 required arguments: align(key:any pageItem or artboard, otherObjects: array of pageItems you want to align, alignType: string representing the alignment option(s).

 

Key objects can be an artboard, pageItem, pathItem, groupItem, compoundPathItem, placedItem, linkedItem, etc. any item that falls under the umbrella of Document.pageItems.

 

The array of otherObjects can contain one or more pageItems. (no support for artboards yet.. i don't know if it's necessary?).

 

The alignType string can be one of the following: "center", "vcenter", "vtop", "vbottom", "hcenter", "hleft", "hright", "botleft", "botright", "topleft", "topright", "leftcenter", "rightcenter", "topcenter", "botcenter"

 

source code located here:

https://github.com/wdjsdev/public_illustrator_scripts/blob/master/alignment_functions.js

 

and the dependency code here:

https://github.com/wdjsdev/public_illustrator_scripts/blob/master/object_bounds_data.js

This is the code that handles the visible bounds quirks that vasily and josh mentioned. 

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
Contributor ,
Aug 18, 2022 Aug 18, 2022

Copy link to clipboard

Copied

Thank you @Disposition_Dev  very much for your explanation! You are my idol! 😊

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 ,
Jan 09, 2023 Jan 09, 2023

Copy link to clipboard

Copied

I don't know anything about Java and scripting. Does this work on below sample? 

Screenshot 1401-10-19 at 15.10.52.png

Your help would be greratly appreciated.

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 ,
Jan 09, 2023 Jan 09, 2023

Copy link to clipboard

Copied

LATEST

Can we introduce more than one key object with this code? something like below example :

 

Screenshot 1401-10-19 at 15.10.52.png

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