Copy link to clipboard
Copied
My puzzle is somewhat simple:
Suppose you have a rectangle and you ask for its geometric bounds. Then you compute a new size, with the same values for the upper left corner, and use those values to resize. What happens is that the rectangle moves quite a distance and I expect its upper left corner to remain in place.
Here's a skeleton script fragment - starting with the variable myRect pointing to a rectangle which is on a page in a spread:
myBounds = myRect.geometricBounds
myY1 = myBounds[0]
myX1 = myBounds[1]
myY2 = myBounds[2]
myX2 = myBounds[3]
newY2 = myY2 + 20
newX2 = myX2 +30
myRect.reframe(CoordinateSpaces.SPREAD_COORDINATES,[[myY1,myX1],[newY2,newX2]])
I also tried this with the PAGE_COORDINATES option, but then the frame just disappeared from view, so it made an enormous move!
I'd really appreciate any help in preventing the corner's motion. Thanks in advance.
Hi,
You can use a "new" geometricBounds to resize object directly.
I mean:
myRect.geometricBounds = [myY1, myX1, newY2, newX2];
However - to go deeper into coordinate system details see this link:
Jarek
Copy link to clipboard
Copied
Hi,
You can use a "new" geometricBounds to resize object directly.
I mean:
myRect.geometricBounds = [myY1, myX1, newY2, newX2];
However - to go deeper into coordinate system details see this link:
Jarek
Copy link to clipboard
Copied
Thanks everyone,
Just rewriting the geometricBounds property value did the trick, without all the extra messing around that some of you suggested. It's amazing how simple a problem's solution can be if you think in a good direction!!
Copy link to clipboard
Copied
I should have given big credit, along with my thanks, to Jarek, for thinking in the best direction!!
Dick
Copy link to clipboard
Copied
Hi Dick,
then rotate your selected object a bit and try to work with geometricBounds.
Alternatively use reframe() with CoordinateSpaces.INNER_COORDINATES and see the differences:
// Example:
// Values here meant as millimeters
// Converted to points:
var s = app.selection[0];
var xPlus = UnitValue( 30 , MeasurementUnits.MILLIMETERS).as(MeasurementUnits.POINTS);
var yPlus = UnitValue( 20 , MeasurementUnits.MILLIMETERS).as(MeasurementUnits.POINTS);
var topLeft = s.resolve(AnchorPoint.TOP_LEFT_ANCHOR, CoordinateSpaces.INNER_COORDINATES)[0];
var bottomRight = s.resolve(AnchorPoint.BOTTOM_RIGHT_ANCHOR, CoordinateSpaces.INNER_COORDINATES)[0];
// reframe() and other transform methods always use points as unit:
s.reframe(CoordinateSpaces.INNER_COORDINATES, [topLeft, [bottomRight[0] + xPlus, bottomRight[1] + yPlus]] );
Regards,
Uwe
Copy link to clipboard
Copied
For what it's worth (not too much on an InDesign forum) I spend most of my scripting time on Illustrator a land where there are no mm or inches only points. It actually makes life pretty simple.
To convert mm or whatevers to points one can use
String.prototype.pt = function() {
var x, m, value, unit;
if (!this.pt.table) {
this.pt.table = {
'in': 72,
'"': 72,
'inches': 72,
'inch': 72,
'mm': 72 / 24.1,
'feet': 72 * 12,
"'": 72 * 12,
'yard': 72 * 12 * 3,
'cm': 72 / 2.41,
'm': 7200 / 2.41,
'km': 7200000 / 2.41,
'pt': 1,
'pts': 1,
'point': 1,
'points': 1
}
}
x = (this.toLowerCase()).replace(/[^-.\da-z"']+/g, '');
value = +x.replace(/[^\d.]+/g, '');
unit = x.replace(/[^a-z'"]+/g, '');
if (unit === '') { unit = 'pt'; }
if (!(unit in this.pt.table)) {
return 'Ehr I don\'t know this unit';
}
if (value === '') {
return 'Funny number';
}
return value * this.pt.table[unit];
}
function inches(x) {
return 72 * x;
}
function mm(x) {
return 72 * x / 25.1
}
alert("23.6'".pt() + inches(2) + mm(6));
The inches and mm functions are quite handy and
var xPlus = '30mm'.pt();
or
xPlus = mm(30);
are both somewhat less cumbersome than
var xPlus = UnitValue( 30 , MeasurementUnits.MILLIMETERS).as(MeasurementUnits.POINTS);
var xPlus = UnitValue( '30mm').as('pt');
FWIW
Trevor
Copy link to clipboard
Copied
What Jarek said...
So, if you want to keep it simple, just stick to reading and writing geometricBounds of the object. Just remember that when you're writing the geometricBounds, you have to supply a full array. You can't write myObject.geometricBounds[1] = 30. You'd have to write: myObject.geometricBounds = [1,2,3,4];
However, really it is more correct and better to use reframe(). But in that case, to stay consistent, don't get the bounds of the object with geometricBounds, but with the resolve() method. Something like this:
s = app.selection[0];
topLeft = s.resolve(AnchorPoint.TOP_LEFT_ANCHOR, CoordinateSpaces.SPREAD_COORDINATES)[0];
bottomRight = s.resolve(AnchorPoint.BOTTOM_RIGHT_ANCHOR, CoordinateSpaces.SPREAD_COORDINATES)[0];
s.reframe(CoordinateSpaces.SPREAD_COORDINATES, [topLeft, [bottomRight[0] + 20, bottomRight[1] + 20]]);
Ariel
Copy link to clipboard
Copied
Hi Dick,
just one thing to add:
reframe() is always working with Points as unit.
+ 20 in Ariel's example will actually add 20 points.
Even if your ruler guides are showing e.g. millimeters.
You cannot use strings with reframe() like one can do with geometric bounds.
E.g. if you want to work with millimeters:
var myNewGeometricBounds = [0,0,"100 mm","70mm"];
app.selection[0].geometricBounds = myNewGeometricBounds;
Instead you first have to convert your intended measurements to points:
// Example:
// Values here meant as millimeters
// Converted to points:
var s = app.selection[0];
var xPlus = UnitValue( 30 , MeasurementUnits.MILLIMETERS).as(MeasurementUnits.POINTS);
var yPlus = UnitValue( 20 , MeasurementUnits.MILLIMETERS).as(MeasurementUnits.POINTS);
var topLeft = s.resolve(AnchorPoint.TOP_LEFT_ANCHOR, CoordinateSpaces.SPREAD_COORDINATES)[0];
var bottomRight = s.resolve(AnchorPoint.BOTTOM_RIGHT_ANCHOR, CoordinateSpaces.SPREAD_COORDINATES)[0];
// reframe() and other transform methods always use points as unit when in comes to coordinates:
s.reframe(CoordinateSpaces.SPREAD_COORDINATES, [topLeft, [bottomRight[0] + xPlus, bottomRight[1] + yPlus]] );
Regards,
Uwe
Copy link to clipboard
Copied
> Instead you first have to convert your intended measurements to points:
It's easier to set the script engine's default to points:
app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
Peter
Copy link to clipboard
Copied
Hi Peter,
but that wouldn't do the conversion, wouldn't it?
Example:
I like to expand my selected rectangle by 40 millimeters in x-direction.
Setting the measurementUnit with scriptPreferences will not help with that.
I still would have to feed my desired value 40 converted to points to the reframe() method.
Hm, or do I see something wrong here?
Regards,
Uwe
Copy link to clipboard
Copied
> but that wouldn't do the conversion, wouldn't it?
True. I'm just a bit points-biased. I always set the script engine to points and add measure in bare numbers, so that's always points. But if you want to add 40mm you'll have to use UnitValue() to convert that to points.
P.