Get the untransformed bounds of an object


#1

Is there a method to get the untransformed bounds of an object?

For example, if I have a rectangle and it is at 10 x 10 and size is 50 x 100 I can get the bounds with:

var bounds = sceneNode.globalBounds; // {x:10, y:10, width: 50, height: 100}

Then when I change the rotation by 45’ the bounds are :-18.03 x 6.97

var bounds = sceneNode.globalBounds; // {x:10, y:10, width: 50, height: 100}
sceneNode.rotateAround(45, sceneNode.localCenterPoint);
// Update to original post: the next line has a typo in the size, corrected line after 
// var bounds = sceneNode.globalBounds; // {x:-18.03, y:6.97, width: 50, height: 100}
var bounds = sceneNode.globalBounds; // {x:-18.03, y:6.97, width: 106.1, height: 106.1}
sceneNode.rotateAround(-sceneNode.rotation, sceneNode.localCenterPoint);

Is it possible to get the original unrotated bounds? When I manually rotate the scene node back it works but if it is outside of the edit context I get an error:

Plugin Error: Plugin abc is not permitted to make changes from the background. Return a Promise to continue execution asynchronously.
    at convertPluginErrorToString (plugins/PluginErrorUtil.js:1:198)
    at internalFormatPluginError (plugins/PluginErrorUtil.js:1:503)
    at internalReportPluginError (plugins/PluginErrorUtil.js:1:610)
    at Object.reportPluginError (plugins/PluginErrorUtil.js:1:1015)
    at Object.checkAllowedToEdit (plugins/ScenegraphGuard.js:1:1097)
    at Line.<anonymous> (plugins/ScenegraphWrappers.js:1:2399)
    at exportLine (/Users/bob/Library/Application Support/Adobe/Adobe XD CC/develop/myplugin/main.js:100:8)

Is there a way to get the untransformed bounds:

var untransformedBounds = sceneNode.getUntransformedBounds();

#2

@Velara There is no direct API to get the untransformed bounds at the moment. As a workaround, could you save the original bounds to a variable before transforming the objects?


#3

Unfortunately, the objects are already transformed.


#4

Is there enough information currently in the API to get the untransformed bounds?


#5

Wouldn’t the untransformed bounds always be (0,0) - (sceneNode.width, sceneNode.height)? The offset (x, y) is a transformation itself (from 0,0).

That said, I don’t think every sceneNode has a width and height property. Ellipse, for example, just has X and Y radius properties.

Also, what’s the usecase here? Maybe that would help shed some light on what you’re trying to accomplish.


#6

I’m not sure what you mean. Could you elaborate?

I did just noticed a typo in the bounds size:

In the original example the reported global bounds after rotation is 106 x 106

var bounds = sceneNode.globalBounds; // {x:10, y:10, width: 50, height: 100}
sceneNode.rotateAround(45, sceneNode.localCenterPoint);
var bounds = sceneNode.globalBounds; // {x:-18.03, y:6.97, width: 106.1, height: 106.1}
sceneNode.rotateAround(-sceneNode.rotation, sceneNode.localCenterPoint);

You can repeat the steps here:

  1. Add rectangle to stage at 10x10 with dimensions of 50x100
  2. Rotate 45
  3. Select rectange and group

The bounds are -18.03 x 6.97 and size is 106.1 x106.1.

I know that Lines do not have a height or width sometimes as reported by sceneNode.globalBounds but they do have a height or width with sceneNode.globalDrawBounds.


#7

I’ve noticed an minor inconsistency in the UI slightly based around this post.

In the UI you have the width, height, x, y and rotation.

If you change the rotation the x and y are changed but the width and height do not.

If you check the global bounds of the object it contains the transformed width and height and the transformed x and y.

So the UI reflects the transformed x and y values but not the transformed width and height.

The code for the above information:

var localX = selectedItem.parent ? selectedItem.globalBounds.x - selectedItem.parent.globalBounds.x : 0;
var localY = selectedItem.parent ? selectedItem.globalBounds.y - selectedItem.parent.globalBounds.y : 0;
addRow("Position in Group", "(sceneNode.globalBounds.x - sceneNode.parent.globalBounds.x)", {x: localX, y: localY});
addRow("Bounds in Parent", "(sceneNode.boundsInParent)", selectedItem.boundsInParent);
addRow("Top Left in Parent", "(sceneNode.topLeftInParent)", selectedItem.topLeftInParent);
addRow("Global Bounds", "(sceneNode.globalBounds)", selectedItem.globalBounds);
addRow("Global Draw Bounds", "(sceneNode.globalDrawBounds)", selectedItem.globalDrawBounds);

#8

@peterflynn Thoughts here? You’re probably most familiar with how the coordinate spaces work with the API, so any thoughts are most appreciated. :slight_smile:


#9

I think what you’re looking for is localBounds, no?