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

A script for measuring the distance between two elements?

Community Beginner ,
Dec 24, 2017 Dec 24, 2017

Copy link to clipboard

Copied

Anyone can help me with the script for measuring the distance between two elements (layers) in Photoshop.

I know that there are smart guides . I need this funcionality as a script to apply correct margins/paddings in CSS

Layers should be selected by shift. It's works very similar in Adobe Dreamweaver Extract and Assets Extract.

2017-12-23_174748.jpg

TOPICS
Actions and scripting

Views

4.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

correct answers 1 Correct answer

People's Champ , Jan 15, 2018 Jan 15, 2018

OK.

The following script gives you this result. But it seems to me this is complete nonsense. ))

// version no CS6 or no effects

var old_units = app.preferences.rulerUnits;   

app.preferences.rulerUnits = Units.PIXELS;   

 

try { app.activeDocument.suspendHistory("Get Text Bounds", "var bounds = get_selected_layers_bounds()") } catch(e) { alert(e); } 

 

try { executeAction( charIDToTypeID( "undo" ), undefined, DialogModes.NO ); } catch(e) { alert(e); } 

 

app.preferences.rulerUnits = old_units;   

...

Votes

Translate

Translate
Adobe
Community Beginner ,
Jan 15, 2018 Jan 15, 2018

Copy link to clipboard

Copied

So, to correct this difference, I need to make calculations for this 2 layers.

distance_in_css = distance - (line-height_1 - 1.2 * font-size_1) / 2
                          
- (line-height_2 - 1.2 * font-size_2) / 2

or in Photoshop Script syntax it should look something like this:

distance_in_css = distance - (Layer1.textItem.leading - 1.2 * Layer1.textItem.size) / 2
                           - (Layer2.textItem.leading - 1.2 * Layer2.textItem.size) / 2;

For above example it will be:

distance_in_css = 50px - (120px - 1.2 * 100px) / 2 - (200px - 1.2 * 100px) / 2 = 50px - 0 - 40px = 10px;

And now if we apply this 10px for CSS margin, the visual distance between text layers will be the same as in Photoshop - 50px

2018-01-15_115013.png

I just do not know how to add them to the script.(((

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 ,
Jan 15, 2018 Jan 15, 2018

Copy link to clipboard

Copied

OK.

The following script gives you this result. But it seems to me this is complete nonsense. ))

// version no CS6 or no effects

var old_units = app.preferences.rulerUnits;   

app.preferences.rulerUnits = Units.PIXELS;   

 

try { app.activeDocument.suspendHistory("Get Text Bounds", "var bounds = get_selected_layers_bounds()") } catch(e) { alert(e); } 

 

try { executeAction( charIDToTypeID( "undo" ), undefined, DialogModes.NO ); } catch(e) { alert(e); } 

 

app.preferences.rulerUnits = old_units;   

   

if (bounds)   

    {   

    if (bounds.length == 2)   

        {   

        var distance = 0;

       

        if (bounds[0].bottom <= bounds[1].top) distance = bounds[1].top - bounds[0].bottom;   

        else if (bounds[1].bottom <= bounds[0].top) distance = bounds[0].top - bounds[1].bottom;   

        else  alert("Intersecting layers")   

        var distance_in_css = distance - (bounds[0].leading - 1.2*bounds[0].size)/2 - (bounds[1].leading - 1.2*bounds[1].size)/2;

        alert("distance = " + distance + "\ndistance_in_css = " + distance_in_css);

        }   

    else   

        alert("More then 2 selected layers")    

       

    }   

else    

    alert("There is no selected layers")    

   

/////////////////////////////////////////////////////////////////////////////////////////////////   

function get_selected_layers_bounds()   

    {   

    try {   

        var ref = new ActionReference();   

   

        ref.putProperty( charIDToTypeID( "Prpr" ), stringIDToTypeID( "targetLayers" ) );   

        ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );   

        var desc = executeActionGet(ref);   

       

        if (!desc.hasKey( stringIDToTypeID("targetLayers") ) ) return null;   

       

        var n = 0;   

        try { activeDocument.backgroundLayer } catch (e) { n = 1; }   

       

        desc = desc.getList( stringIDToTypeID("targetLayers"));   

       

        var len = desc.count;   

       

        var selected_bounds = new Array();   

       

        for (var i = 0; i < len; i++)   

            {   

            try    

                {   

                var r = new ActionReference();   

                r.putIndex( charIDToTypeID( "Lyr " ), desc.getReference(i).getIndex() + n);   

 

                var ret = executeActionGet(r);   

                var size    = 0;

                var leading = 0;

 

                if (ret.hasKey(stringIDToTypeID("textKey"))) 

                    { 

                    var textStyleRangeList = ret.getObjectValue(stringIDToTypeID("textKey")).getList(charIDToTypeID("Txtt" ));

                    if (textStyleRangeList.count > 1) { alert("More than one textStyleRange in layer", "Oops!!"); }

                    var textStyle = textStyleRangeList.getObjectValue(0).getObjectValue(charIDToTypeID("TxtS" ));

                    var auto_leading = textStyle.getBoolean(stringIDToTypeID("autoLeading"));

                    size = textStyle.getUnitDoubleValue(stringIDToTypeID("size"));

                    leading = auto_leading?size*1.2:textStyle.getUnitDoubleValue(stringIDToTypeID("leading"));

                    var s = ret.getObjectValue(stringIDToTypeID("textKey")).getString(charIDToTypeID("Txt " )); 

                    s = s.replace(/^./gm, String.fromCharCode(0x2588)); 

 

                    var d1 = new ActionDescriptor(); 

                    d1.putReference( charIDToTypeID( "null" ), r ); 

             

                    var d2 = new ActionDescriptor(); 

                    d2.putString( charIDToTypeID( "Txt " ), s); 

 

                    d1.putObject( charIDToTypeID( "T   " ), charIDToTypeID( "TxLr" ), d2 ); 

 

                    executeAction( charIDToTypeID( "setd" ), d1, DialogModes.NO ); 

 

                    ret = executeActionGet(r);   

                    } 

                     

                var bounds = ret.getObjectValue(stringIDToTypeID("bounds"));  // use this in CS6 or when you want to take into account the effects   

                //var bounds = ret.getObjectValue(stringIDToTypeID("boundsNoEffects")); // in CS6 does not work   

   

                var obj = {

                          left   : bounds.getUnitDoubleValue(stringIDToTypeID("left")),   

                          top    : bounds.getUnitDoubleValue(stringIDToTypeID("top")),   

                          right  : bounds.getUnitDoubleValue(stringIDToTypeID("right")),   

                          bottom : bounds.getUnitDoubleValue(stringIDToTypeID("bottom")),

                          size   : size,

                          leading: leading,

                          };   

       

                selected_bounds.push(obj);   

                }   

            catch (e)   

                {   

                alert(e);   

       

                return null;   

                }   

            }   

       

        return selected_bounds;   

        }   

   

    catch (e) { alert(e); return null; }   

    }   

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 15, 2018 Jan 15, 2018

Copy link to clipboard

Copied

I'm sorry that this looks completely nonsense to you, but it works great! ;)) Thank you!

The only thing I used was the previous version of bounds:

var bounds = ret.getObjectValue(stringIDToTypeID("boundsNoEffects")); // in CS6 does not work

Cause I don't want to take into account the effects - shadows, glows etc. I want to take into account stroke, but I do not think it's possible to do this separately.

So, we can consider the issue resolved . Thanks again!

Hmm.. Could I put the numeric value of distance_in_css right in clipboard?

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 ,
Jan 15, 2018 Jan 15, 2018

Copy link to clipboard

Copied

yeah.not  написал(а)

Hmm.. Could I put the numeric value of distance_in_css right in clipboard?

You can try like this )

text_to_clip("1234567890");

function text_to_clip(txt)

    {

    app.system("echo " + txt + "|clip");

    }

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 ,
Jan 15, 2018 Jan 15, 2018

Copy link to clipboard

Copied

LATEST

Hmmh?

You want to get the line height?

Why not simply use text property?

var aLay= app.activeDocument.activeLayer;

if(aLay.textItem) {

    if (!aLay.textItem.useAutoLeading) { alert("leading: "+aLay.textItem.leading) }

    else { alert("AutoLeading with: "+Math.round (aLay.textItem.autoLeadingAmount)+"%" ); }

};

Have fun

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 ,
Dec 25, 2017 Dec 25, 2017

Copy link to clipboard

Copied

r-bin​,

"It's a kind of Magic"!

Thanks a lot!

One thing... Could I put output numeric value right in clipboard too?

Other thing)... The ultimate goal was to get CSS margin/padding. You can see the discussion, but I do not recommend - too many words . The point is that distance in CSS is NOT equal to the distance in Photoshop for text layers. There is a very approximate formula:

border-line <> border-line (two shapes, e.g.)

distance_CSS = distance_PS

text <> border-line

distance_CSS = distance_PS - (line-height - 0.7 * font-size) / 2

text 1 <> text 2

distance_CSS = distance_PS - (line-height_1 - 0.7 * font-size_1) / 2 - (line-height_2 - 0.7 * font-size_2) / 2

How to put this formula in the script? Help here or there​, if U pls.

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 ,
Dec 25, 2017 Dec 25, 2017

Copy link to clipboard

Copied

It's not entirely clear how to apply your formula. You mean by the height of the text, what you get with Ctrl-T text, ie. bounding box during the transformation?

You can get its FontSize for each layer. But there can be several for one layer. We can take the maximum. But still it is not clear how to know the height of the text, especially if there are several lines.

The simplest option. Temporarily replace all the symbols with the █ (SolidBlock symbol).
It has the maximum height for a given font.
After measuring the distance between the texts and return (undo) all in place.

The task is not very difficult but now there is no time for it. Later I'll try. )

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