10

I need to rotate the paths in my SVG document around an arbitrary point in 3D. It appears that there are multiple ways to do this by either using a 4x4 transformation matrix or the rotateX or rotateY transforms. I've tried both of these methods, and neither seem to work. Are these supported anywhere?

For my application, a bitmap is going to be the final output, so I'm not worried about browser support. I am open to any tool--I can run a specific browser through selenium, or use a standalone SVG rasterizer.

This is what I've tried so far (using Google Chrome 31):

I would expect this to be a black rectangle, rotated about the X axis, and appearing like a trapezoid.

<svg version="1.1" 
     xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink" width="640px" height="480px">

    <rect x="100" y="100" width="440" height="280" fill="#000000" 
          transform="rotateX(30 580 100)"></rect>
</svg>

(omitting cy and cz from rotateX gives the same result).

I've also tried with a 4x4 matrix. I don't see any difference from above. I also doubt my math is correct in finding the right matrix elements.

<svg version="1.1" 
     xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink" width="640px" height="480px">

    <rect x="100" y="100" width="440" height="280" fill="#000000" 
          transform="matrix(102400 0 0 0 0 88681.00134752653 -159.99999999999997 1387899.8652473476 0 159.99999999999997 88681.00134752653 -15986.602540378442)"></rect>
</svg>
flndr
  • 455
  • 1
  • 6
  • 16

3 Answers3

5

I found that there really isn't a way in SVG to do a 3D rotation that is supported in any modern browser (to the best of my knowledge). However, CSS3 does have a similar "transform" property.

The following works for me:

<svg version="1.1" 
     xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink" width="640px" height="480px">

    <rect x="100" y="100" width="440" height="280" fill="#000000" style="-webkit-transform: rotateX(30); -webkit-transform-origin-y: 580px; -webkit-transform-origin-z: 100"></rect>
</svg>

This, obviously, isn't a good cross-browser solution (as it uses prefixed properties), but that isn't something I need in my application.

flndr
  • 455
  • 1
  • 6
  • 16
  • 1
    Copied into Codepen, this code doesn't seem to work. Perhaps more code is needed. – matanster May 25 '14 at 13:15
  • 1
    FWIW, the transform that worked for me in Firefox v44 is rotateX(30deg); – Emo Mosley Jun 09 '16 at 16:28
  • Note that the "deg" is necessary for it to work. You can also use "transform-origin: 580px 100px;" (not sure of the values needed) to determine where the element pivots. – Emo Mosley Jun 09 '16 at 16:49
2

3d rotations are tricky and i've only just started using them. transform: rotateX() and rotateY() will apply the transformations for you, but to get that perspective of a trapezoid, you'll need to use perspective in the css of the parent element.

Here's a codepen.

The relevant bits are

#parent {
  perspective: 4rem;
}

#child {
  transform: rotateX(45deg);
}

Think of perspective as the distance the object is from the back of your screen. The lower the value, the more intense the distortion of the perspective will be.

shadycrzy
  • 21
  • 1
-2

See https://www.w3schools.com/css/css3_3dtransforms.asp : indeed the CSS code { transform: rotateX(##deg) } and similar for -Y and -Z should work now without prefix in most browsers. But it appears these cannot be combined. So you may want to use the more general method: { transform: rotate3d(x,y,z,angle) } , where you can give an arbitrary rotation axis. Hope that helps...

Max
  • 415
  • 5
  • 12