Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

【CSS】疑似3D 前後関係

 どうも!LSSです!!

 

little-strange.hatenablog.com

で、惑星の公転運動っぽい動きを作っていました。

 

が、あくまでも「疑似」の悲しさ、

little-strange.hatenablog.com

と同じで「前後関係が表現できない」事から、例えば中央に太陽、動くのを地球とすると、重なると3Dではない事が露呈してしまうという欠点があります。

 

CSSには3D表現があるので、そちらを使えば良いのですが(そちらには球や曲面の表示が苦手という弱点もありますが)なんとか「疑似3D」のままで誤魔化せないか?試みてみました。

 

 

疑似3D 前後関係

 
 

 

地球(?)が太陽(?)の向こう側を回る時には隠れ、手前側を回る時には太陽を隠しています。

 

 

コード

<style>
@keyframes d3dzx{
0%{background-position-x:0%;}
100%{background-position-x:100%;}
}
@keyframes d3dzy{
0%{background-position-y:40%;background-size:20px 20px;}
100%{background-position-y:60%;background-size:60px 60px;}
0%,49%{z-index:1;}
50%,100%{z-index:3;}
}
.d3dz{
position:relative;
height:200px;
background-color:black;
}
.d3dz div{
position:absolute;
top:0;left:0;
width:100%;height:100%;
}
.d3dz div:nth-child(1){
background-image:radial-gradient(farthest-side,#444488 0%,#4444cc 49%,#0000ff 50%,#0000ff00 100%);
background-repeat:no-repeat;
animation:
d3dzx 5s ease-in-out 2.5s infinite alternate
,d3dzy 5s ease-in-out infinite alternate;
}
.d3dz div:nth-child(2){
background:radial-gradient(farthest-side,#ffffff 49%,#ffcc00 50%,#ffcc0000 100%) 50% 50%/80px 80px no-repeat;
z-index:2;
}
</style>
<div class="d3dz">
<div> </div>
<div> </div>
</div>

 

コードは大幅に変わりました。

 

 

HTML部分

<div class="d3dz">
<div> </div>
<div> </div>
</div>

 

クラス名を「d3dz」としたdivタグ、その中に指定も中身もないdivタグが2組、入っています。

(d3dzは全体の外枠、その中の1つめのdivタグが地球、2つめが太陽となります。)

 

 

外枠のCSS

.d3dz{
position:relative;
height:200px;
background-color:black;
}

 

「position:relative;」を指定しています。

「外枠自体は記事文脈に埋め込みつつ、その中身をゴニョゴニョする」際のお約束みたいなものです。

「height:200px;」で高さをとりあえず200pxとしていますが、こちらは好きに変更できます。

あとは「background-color:black;」で全体を黒塗りしています。

 

外枠に対する指定は以上だけなので、別途background-imageなどで星空を描いてもいいかもですね^^

 

 

他、3つのセレクタ

.d3dz div{
中略
}
.d3dz div:nth-child(1){
中略
}
.d3dz div:nth-child(2){
中略
}

 

その他のセレクタとして、上記3種類書いています。

 

まず最初の「.d3dz div」は「クラス名d3dzの要素の中に入っているdivタグ」という意味で、これは前述のHTMLで言うと、

<div class="d3dz">
<div> </div>
<div> </div>
</div>

この「内側のdivタグ2つ両方」に対する指定となります。

「どちらにも共通する設定」をここにまとめて書いています。

その内容は、

position:absolute;
top:0;left:0;
width:100%;height:100%;

で、「position:absolute;」は(記事文脈を無視した)絶対位置指定(これにより、重なったりします)。

場所は左上角から、サイズは幅・高さともめいっぱい(ただし、外枠の中で)という指定となります。

 

次に、「.d3dz div:nth-child(1)」は「クラス名d3dzの要素の中に入っているdivタグの1つめ」に対する指定となります。

その内容は、

background-image:radial-gradient(farthest-side,#444488 0%,#4444cc 49%,#0000ff 50%,#0000ff00 100%);
background-repeat:no-repeat;
animation:
d3dzx 5s ease-in-out 2.5s infinite alternate
,d3dzy 5s ease-in-out infinite alternate;

ですが、これは【CSS】疑似3D【実験】と同じ内容ですね。

 

最後に、「.d3dz div:nth-child(2)」は「クラス名d3dzの要素の中に入っているdivタグの2つめ」に対する指定となります。

その内容は、

background:radial-gradient(farthest-side,#ffffff 49%,#ffcc00 50%,#ffcc0000 100%) 50% 50%/80px 80px no-repeat;
z-index:2;

となっており、単に「太陽(?)」を描いているだけですね。

太陽を動かさないのでanimationも指定していません。

が、「z-index:2;」を指定しています。

z-indexは「奥行き」を順番づけたい時に指定するプロパティで、それに「2」を指定しています。

 

 

keyframes内にz-indexの指定を追加

ここでようやく、「疑似3Dにどのように前後関係を与えているか」って話になります。

「地球(?)」の動きに、animationプロパティから以下の2つのkeyframesを呼び出しているのは前回通りですが、

 

@keyframes d3dzx{
0%{background-position-x:0%;}
100%{background-position-x:100%;}
}
@keyframes d3dzy{
0%{background-position-y:40%;background-size:20px 20px;}
100%{background-position-y:60%;background-size:60px 60px;}
0%,49%{z-index:1;}
50%,100%{z-index:3;}
}

 

縦の動きに合わせて、

0%,49%{z-index:1;}
50%,100%{z-index:3;}

と、地球の入ったdivタグに対して、z-indexを

  • 「表示位置が上半分でサイズも小~中の時」には「1」
  • 「表示位置が下半分でサイズも中~大の時」には「3」

となるように変化させる指示を書いています。

 

太陽のdivタグのz-indexを「2」としているので、奥行きがそれより小さくなったり大きくなったりするんですね。

 

 

という感じで「疑似3Dのまま、なんとか前後関係を表現」してみました。

divタグを3つも使っているので、もうbackgroundにこだわる必要もなく、他にもっとまともな表現方法もあるかとは思いますが^^;;;

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^