3D Transforms on Svg Element

3d transforms on SVG element


Update Nov 2018:

Testing the snipet from the question in latest chrome and Firefox works. Although support for 3d transforms on svg elements isn't very wide, browsers are implementing it more and more.


Origin answer :

3D transforms aren't supported on SVG elements. There are a few workarounds though :

If the svg doesn't contain elements that shouldn't be transformed, you can use CSS 3d transforms on the SVG element itself :

svg {  width: 70%;  margin: 0 auto;  display: block;  -webkit-transform: perspective(300px) rotateX(30deg);  transform: perspective(300px) rotateX(30deg);}
<svg viewbox="0 0 100 20">  <text x="0" y="20">TEXTEXTEX</text></svg>

3d transform perspective in svg

SVG has no support for 3D transforms. You can transform the whole SVG (the browser renders it to an image first) but not the individual elements.

  <div id="outer">
<svg id="inner" width="500" height="500">
<image x="20" y="90" width="200" height="200" xlink:href='http://www.w3schools.com/html/smiley.gif' />
</svg>
</div>

Demo here

SVG Rotation in 3D

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.

How to make a perspective in SVG?

SVG doesn't support 3D transforms, so what you want to do is not possible.

What you can do instead is do the 3D image transform in CSS/HTML and then create a new clip-path that is a de-projection of the original clip path in SVG. It takes quite a bit of matrix math to manually calculate the new clip-path coordinates, so it's not a quick answer. I just threw a scale transform onto the clip path so you can get the idea.

WebGL would really be a better toolbox for 3D textures - if you've considered that.

* {
margin: 0;
padding: 0;
transform-style: preserve-3d;
perspective: 1000px;
}

img {
display: block;
width: 800px;
height: 450px;
position: fixed;
top: 0;
left: 0;
z-index: -1;
}

#brick-overlay {
position: absolute;
z-index: 5;
transform: rotateY(-38deg);
transform-origin: 9% 0%;
clip-path: url(#clip-me);
}
 <img src="https://i.ibb.co/bQdMN47/image.png" alt="Sample Image">

<img id="brick-overlay" src="https://i.ibb.co/YkvS1LC/brick-004.jpg"/>

<svg viewBox="0 0 800 450" id="svg">
<defs>
<clipPath id="clip-me" transform="scale(1.6 1)"><path d="M95,329 238,374 238,183 207,183 140,120 95,228 M137,294 137,224 157,219 158,294z"/></clipPath>
</defs>
</svg>

How to rotate in 3D many rect in SVG with a different angle of rotation?

Unfortunately 3D transforms aren't supported on SVG elements.

There are a few workarounds that allow you to rotate three-dimensionally by CSS the element inside: look here

So you could...

  • create 3 SVG and rotate the element inside, following the link above

OR anyway without to use SVG...

  • create 3 different DIVS following for each one this
    method

SVG Transform: Scale Y depending on X

You could use CSS 3D transforms to get that "tapered" effect (play around with this example), but since 3D transforms aren't supported on SVG elements, you would have to apply the transform to the entire <svg> element:

.tapered {  transform-origin: 0px 0px 0px;  transform: matrix3d(0.52, -0.033, 0, -0.00096, 0.012, 0.52, 0, 0, 0, 0, 1, 0, -1, 17, 0, 1);}
<svg class="tapered" xmlns="http://www.w3.org/2000/svg" width="500" height="60">  <g stroke-width="1" stroke="black">    <line x1="10" y1="10" x2="490" y2="10"/>    <line x1="10" y1="25" x2="490" y2="25"/>    <line x1="10" y1="40" x2="490" y2="40"/>    <line x1="10" y1="55" x2="490" y2="55"/>  </g></svg>

CSS3 3D flip card effect with SVG elements

The fact that you're using d3.js does not at all affect the ability to create 3D transforms. The fact that you are using SVG, however, does make it complicated.

SVG has its own transform system—and coordinate system—that doesn't directly correspond to the way that CSS transforms are applied to HTML elements. Although the CSS transforms spec is supposed to apply to SVG, browser implementations are still very inconsistent.

As Lars said in the comments, if you wanted to flip your entire SVG, it would be simply a matter of applying the CSS transformations (as described in the answer linked by @Harry) to a parent <div>. However, in order to get an individual SVG element or group to "flip" to reveal different content, you need two different SVG elements, which super-impose one on top of the other when one of them is flipped using CSS transforms.

You can apply CSS transformations to individual SVG elements, but beware:

  • IE will ignore them completely
  • Firefox (v32 and earlier) and Chrome (v37 and earlier) will calculate the transform-origin differently, so you'll want to position your elements such that the SVG coordinate system origin (used by Chrome) is the same as the bounding box origin (used by Firefox).
  • Chrome won't flip individual text elements.
  • SVG doesn't currently have a z-index, so you can't use it to make sure the correct element is "on top". Instead, you would have to hide the flipped element using the backface-visibility property.

The below example is extracted from a longer discussion about CSS transforms and SVG that I wrote on CodePen. Test it in a couple different browsers to get an idea of the problems you're up against:

svg.graphic {  padding:2em 1.2%;  margin:0;  float:left;  overflow:visible;  shape-rendering:geometricPrecision;  stroke-width:3;}.graphic.CSS {  -webkit-perspective:500px;  perspective:500px;}.graphic.CSS.spin *{  -webkit-transition:3s linear;  transition:3s linear;  -webkit-transform-origin:50% 50%;  transform-origin:50% 50%;}.graphic.CSS.spin:hover *{  -webkit-transform:rotateY(360deg);  transform:rotateY(360deg);}
<svg class="graphic CSS spin">  <g id="svg-shapes">    <rect width="100%" height="100%" rx="2em"           fill="lightblue" stroke="green" />    <circle r="1.5em" cy="2.5em" cx="70%"             fill="lightyellow" stroke="goldenrod" />    <rect width="5em" height="2em" x="20%" y="2.5em"           fill="lavender" stroke="indigo" />  </g>  <text x="20%" dx="2.5em" text-anchor="middle"         y="2.5em" dy="1em">3D???</text></svg>


Related Topics



Leave a reply



Submit