Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-transforms-2][svg11] Effect of perspective and 3D transform on SVG bounding box #907

Open
smfr opened this issue Jan 13, 2017 · 3 comments

Comments

@smfr
Copy link
Contributor

smfr commented Jan 13, 2017

https://www.w3.org/mid/B7126E1C-EB7C-4D9F-9238-F9CDD72BDB21@adobe.com

SVG defines the bounding box of an object as follows [1]:

""
getBBox(): Returns the tight bounding box in current user space (i.e., after application of the ‘transform’attribute, if any) on the geometry of all contained graphics elements
""

The question is what is the effect of 3D transforms on the bounding box? I assume that there wouldn't be a big difference. It would still be the tight bounding box of the contained elements after transformations.

More interesting, what is with a perspective projection matrix? Would it affect the bounding box as well? After all, the perspective projection matrix is not very different from a CSS transform which can have perspective values as well. Therefore, I would assume that all the properties: transform, transform-origin, perspective and perspective-origin have an effect on the object bounding box.

@smfr
Copy link
Contributor Author

smfr commented Jan 13, 2017

Possible resolution here: https://lists.w3.org/Archives/Public/public-fx/2013OctDec/0057.html

On Oct 15, 2013, at 8:34 AM, Robert O'Callahan robert@ocallahan.org wrote:

I guess we can go with "don't include perspective in the object bounding box" if other people think that's OK.

I added a note and put this topic on the agenda for the next SVG meeting if we want to keep it or find another solution.

I don't know if this was discussed at any SVG meeting.

@AmeliaBR AmeliaBR added the SVG label Mar 19, 2018
@xfq
Copy link
Member

xfq commented Apr 16, 2019

It was discussed in: https://www.w3.org/2013/10/17-svg-minutes.html#item02

@AmeliaBR
Copy link
Contributor

To clarify, this is about the bounding box of a parent element to the one that has a transform. (The bounding box of the transformed element itself is always returned relative to its own coordinate system, so the transform doesn't change the numbers.)

First issue: The algorithm in SVG 2 doesn't mention child transforms at all!

SVG 1.1 didn't have an explicit algorithm or instructions for how to handle child transforms, it just says to contain all the child graphics:

  • in the definition of getBBox

    Returns the tight bounding box in current user space (i.e., after application of the ‘transform’ attribute, if any) on the geometry of all contained graphics elements, exclusive of stroking, clipping, masking and filter effects.

  • in the definition of object bounding box units

    The bounding box is the tightest fitting rectangle aligned with the axes of the applicable element's user coordinate system that entirely encloses the applicable element and its descendants.

So, this is really undefined behavior on the SVG spec. Let's look at what browsers are doing…

I put together a test case: https://codepen.io/AmeliaBR/pen/bJawWW?editors=1011

Five groups, each containing a rectangle. The rectangles are identical prior to the following transforms being added:

  1. no transform at all (visually, this is the top left)
  2. 2D transform using an SVG attribute. (top right)
  3. 2D transform using a CSS property. (bottom left)
  4. 3D transform with perspective effect. (bottom right)
  5. 3D transform, without perspective effect. (center)

The script prints to the console the transform, the rectangle's bounding box, and then the groups bounding box.

Results:

  • All browsers correctly return the untransformed bounding box for the <rect> itself. No issues there.

  • Firefox ignores all child transforms specified with the CSS property when calculating the group BBox. It accounts for the child transform if specified with an attribute.

  • EdgeHTML includes both 2D and flattened 3D transforms on the child element when calculating the parent element bounding box, but does not include perspective effects — the width and height of the group bounding box are the same for both 3D transformed elements, despite taking up different space on screen.

  • Chromium and WebKit both account for the child transform for both 2D and 3D flattened effects. But neither browser currently applies perspective effects when drawing SVG graphics (known issue for Chromium), so we can't say whether or not they'd include perspective effects in the flattened bounding box.

My conclusions:

  • All browsers factor in SVG 1-compatible transforms on child elements when computing the parent bounding box. That's consistent with the prose in SVG 1, and should be integrated in the algorithm for SVG 2.

  • I strongly believe that the results should be the same whether the transform is specified using the SVG 1 syntax or the CSS syntax. So I'd treat Firefox as having a bug for ignoring CSS transforms.

  • Looking at the remaining browsers, the consensus is that 3D transforms should be flattened when determining the parent bounding box. Which makes as much sense as anything, so let's go with that.

  • I personally think it's confusing to flatten the 3D rotation but not factor in the perspective effect. So I'd want to include perspective effects in the flattening calculation unless there is a strong implementation reason not to.

Another thought:

SVG 2 adds a bunch of options to getBBox (which no one has implemented yet, but maybe one day). In some future module, we could add an extra option to request a 3D box instead of a flattened 2D box — but the default would still be to flatten.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants