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.
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;
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
I just do not know how to add them to the script.(((
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; }
}
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?
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");
}
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
r-bin,
"It's a kind of Magic"!
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.
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. )