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

A script for measuring the distance between two elements?

Community Beginner ,
Dec 24, 2017 Dec 24, 2017

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
7.0K
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

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;   

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

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

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
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;   

   

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; }   

    }   

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

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?

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
People's Champ ,
Jan 15, 2018 Jan 15, 2018

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");

    }

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

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

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.

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
People's Champ ,
Dec 25, 2017 Dec 25, 2017

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

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