SVGで3D座標変換

svg-3d.png

まとめ

  • SVGのtransform機能でやろうとすると正投影になってしまう
  • HTMLファイルにしてCSS3の機能を使いSVGタグをDIVで囲むと透視投影が実現可能である

+ SVGの機能だけでやろうとすると正投影になってしまう

 <svg version="1.1" xmlns="http://www.w3.org/2000/svg" height="300" width="400" viewBox="0 0 628 726">
 <polygon points="723,314 543,625.769145 183,625.769145 3,314 183,2.230855 543,2.230855 723,314" fill="#A1D3D8" stroke="white" stroke-width="4" />
</svg>
 <svg version="1.1" xmlns="http://www.w3.org/2000/svg" height="300" width="400" viewBox="0 0 628 726">
     <style>
         .trans3d{
             transform: rotate3d(1,0,0,60deg);
         }
     </style>
 <polygon points="723,314 543,625.769145 183,625.769145 3,314 183,2.230855 543,2.230855 723,314" fill="#A1D3D8" stroke="white" stroke-width="4" class="trans3d"/>
</svg>

奥行き感 透視投影にするには

いろいろやってみたけど、どうやらSVGだけでは効かず
htmlファイルとして<div>で囲まないと出来なかった

<div style="
width:200px;
height:200px;
perspective:200px;
perspective-origin:50% 50%;
"
>
<svg width="200" height="200" viewBox="0 0 200 200" style="
transform:rotateX(45deg);
transform-style:preserve-3d;
">
 
<rect width="250" height="250" fill="#A1D3D8" stroke="white" stroke-width="4" fill-opacity="0.7"/>
</svg>
</div>

あらゆるブラウザに対応する場合

各transformに対してこんな風に増殖ずればokです

-moz-transform:rotateX(45deg);
-webkit-transform:rotateX(45deg);
-o-transform:rotateX(45deg);
-ms-transform:rotateX(45deg);
transform:rotateX(45deg);

+ 重なるレイヤー表現

<head>
<style>
.layer_bottom{
    transform:rotateX(45deg);
    transform-style:preserve-3d;
    position:absolute;
    top: 0;
    left: 0;
}
.layer_middle{
    transform:rotateX(45deg) translateZ(30px);
    transform-style:preserve-3d;
    position:absolute;
    top: 0;
    left: 0;
}
.layer_top{
    transform:rotateX(45deg) translateZ(60px);
    transform-style:preserve-3d;
    position:absolute;
    top: 0;
    left: 0;
}
</style>
<head>
<div style="
width:200px;
height:200px;
perspective:200px;
perspective-origin:50% 50%;
"
>
<svg width="200" height="200" viewBox="-20 -20 400 400" class="layer_bottom">
<rect width="250" height="250" fill="#A1D3D8" stroke="white" stroke-width="4" fill-opacity="0.7"/>
</svg>
<svg width="200" height="200" viewBox="-20 -20 400 400" class="layer_middle">
<rect width="250" height="250" fill="skyblue" stroke="white" stroke-width="4" fill-opacity="0.5"/>
</svg>
<svg width="200" height="200" viewBox="-20 -20 400 400" class="layer_top">
<rect width="250" height="250" fill="magenta" stroke="white" stroke-width="4" fill-opacity="0.5"/>
</svg>
 
</div>

ポイント

絶対座標で位置を(0,0)にして、無理やり<svg>同士が重なり合うようにした

position:absolute;
    top: 0;
    left: 0;
Bibliography

サポートサイト Wikidot.com