Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG Rotation in 3D

Tags:

svg

transform

3d

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>
like image 318
flndr Avatar asked Jan 08 '14 14:01

flndr


2 Answers

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.

like image 119
flndr Avatar answered Jan 10 '23 07:01

flndr


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.

like image 25
shadycrzy Avatar answered Jan 10 '23 07:01

shadycrzy