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

Align to bottom selection?

LEGEND ,
Feb 21, 2019 Feb 21, 2019

I edited a script from this forum (I think originally written by williamadowling​) to align selection to bottom object. I want to modify it to add the "Bottom Object" to the selection by name so the user does not need to manually select it. The modification works… if I run the script twice. What am I doing wrong?

The starting selection is the "fingerprint" group. Here's a simplified AI file if it's helpful.

Thanks for your help.

var docRef = app.activeDocument; 

    var sel = docRef.selection;

    var AlignObj = docRef.pageItems.getByName("PrintAlign");

    AlignObj.selected = true;

   

    function alignToObj() 

    var keyCenter = getCenterPoint(AlignObj);

    var curItem,curCenter;

    const ALIGNMENT_PREFERENCE_VERTICAL = true; 

    const ALIGNMENT_PREFERENCE_HORIZONTAL = true; 

 

    for(var x=0, len = sel.length-1; x < len; x++) 

    { 

        curItem = sel

        if(ALIGNMENT_PREFERENCE_HORIZONTAL) 

        { 

            //align the object horizontally 

            curItem.left = keyCenter.h - curItem.width/2; 

        } 

        if(ALIGNMENT_PREFERENCE_VERTICAL) 

        { 

            //align the object vertically 

            curItem.top = keyCenter.v + curItem.height/2; 

        } 

    } 

    function getCenterPoint(item) 

    { 

        return {"h":item.left + item.width/2, "v":item.top - item.height/2}; 

    } 

alignToObj(); 

TOPICS
Scripting
1.3K
Translate
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 1 Correct answer

Mentor , Feb 21, 2019 Feb 21, 2019

Heyyyy! attribution. i love it. =D

looks like when you modified it, you reversed the for loop without updating the len variable. the way you have it written currently:

  for (var x = 0, len = sel.length - 1; x < len; x++)

means that if you only have 1 item selected, the loop never executes because len = 0.

sel.length === 1, then you're subtracting 1. and x is not < 0, so the loop never executes.

On the second go around, the UI has "redrawn" so now your selection.length = 2, which means len = 1, and

...
Translate
Adobe
Mentor ,
Feb 21, 2019 Feb 21, 2019

Heyyyy! attribution. i love it. =D

looks like when you modified it, you reversed the for loop without updating the len variable. the way you have it written currently:

  for (var x = 0, len = sel.length - 1; x < len; x++)

means that if you only have 1 item selected, the loop never executes because len = 0.

sel.length === 1, then you're subtracting 1. and x is not < 0, so the loop never executes.

On the second go around, the UI has "redrawn" so now your selection.length = 2, which means len = 1, and the loop then executes as you expect.

change your for loop from this:

for (var x = 0, len = sel.length - 1; x < len; x++)

to this:

for (var x = 0, len = sel.length; x < len; x++)

that will fix this up. Additionally, i would remove this line:

AlignObj.selected = true;

there's really no reason to select that item, at least in the snippet you posted. You don't need to select something to get it's bounds. And having it selected COULD cause problems if you try to do something else with the things you've selected.

hope this helps.

Translate
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
LEGEND ,
Feb 21, 2019 Feb 21, 2019

Thank you, Thank you! I know just enough to be dangerous. I'll keep trying though.

Translate
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
LEGEND ,
Apr 25, 2019 Apr 25, 2019

For anyone interested, this is the corrected script I'm using. The text %percent signs% are variables supplied by Keyboard Maestro.

var docRef = app.activeDocument;

    var sel = docRef.selection;

//variables from KM %variable%

var myLayer = docRef.layers['%LocalLayer%'];

var mySubLayer = myLayer.layers['%activeLayer%Align'];

var AlignObj = mySubLayer.pathItems.getByName('R1_C1');

  

    function alignToObj()

{

    var keyCenter = getCenterPoint(AlignObj);

    var curItem,curCenter;

    const ALIGNMENT_PREFERENCE_VERTICAL = true;

    const ALIGNMENT_PREFERENCE_HORIZONTAL = true;

//~    for (var x = 0, len = sel.length - 1; x < len; x++)

    for (var x = 0, len = sel.length; x < len; x++)

    {

        curItem = sel;

        if(ALIGNMENT_PREFERENCE_HORIZONTAL)

        {

            //align the object horizontally

            curItem.left = keyCenter.h - curItem.width/2;

        }

        if(ALIGNMENT_PREFERENCE_VERTICAL)

        {

            //align the object vertically

            curItem.top = keyCenter.v + curItem.height/2;

        }

    }

    function getCenterPoint(item)

    {

        return {"h":item.left + item.width/2, "v":item.top - item.height/2};

    }

}

alignToObj();

Translate
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
LEGEND ,
May 18, 2019 May 18, 2019

williamadowling

Ok, I'm back. How would I edit the above script to align to "Top" of "AlignObj" instead of center?

I'm guessing I need to change the "getCenterPoint" function but don't know how. Any help?

Thanks.

Edit:

Well, I backed up and took a different approach. This seems to do what I need: aligning 2 named items at the top:

var aDoc = app.activeDocument;

var myText = aDoc.textFrames.getByName("T_Inscription");

var alignObj = aDoc.pathItems.getByName("Front_Max");

myText.position = alignObj.position;

//correction

myText.position = AlignObj.position;  //aligns text with top/left corner of align object

myText.translate ((AlignObj.width - targetFrame.width)/2);   // Aligns text to horizontal center of align object

Translate
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
Mentor ,
May 20, 2019 May 20, 2019

you could also say:

myText.top = alignObj.top;

myText.left = (alignObj.left + (alignObj.width / 2)) - (myText.width / 2);

Translate
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
LEGEND ,
May 20, 2019 May 20, 2019
LATEST

That's more straight-forward. Thanks.

Translate
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