div だけで球体を作る

今回は div だけで球体を作るのにチャレンジしてみます。

参考:CSSで球体を作る。|Qiita

Qiita でこんな記事を見つけて、もっと高密度で作れるかもと思い作ってみました。下の方に実際の球体のデモを表示してます。

ball

作り方

CSS と JavaScript を使って作ってみます。

HTML

<div id="ball"></div>

上記の div の中に球体になる div 要素を入れていきます。rotateY で 1deg ずつずらして重ねていくことで球体にしていきます。

CSS

#ball {
    animation: rolling 2s linear 0s infinite;
    height: 300px;
    margin: 50px auto;
    position: relative;
    transform-style: preserve-3d; /*要素内の子要素が3Dで描画されるように*/
    width: 300px;
}

.ball-element {
    border: 1px solid #000;
    border-radius: 50%;
    box-sizing: border-box;
    height: 300px;
    position: absolute;
    width: 300px;
}

/*アニメーション*/
@keyframes rolling {
    0% {
        transform: rotateX(0deg)
    }
    100% {
        transform: rotateX(360deg)
    }
}

ベンダープレフィクスは必要に応じて付与してください。ポイントは transform-style: preserve-3d です。これにより、子要素が3Dでの位置を維持してくれるため球体になります。

参考:transform-style|CSS3リファレンス

JavaScript

var ballWrap = document.getElementById("ball");
var ballElement = document.createElement("div");
ballElement.className = "ball-element";

for (var i = 0; i < 180; i++) {
    var ballClone = ballElement.cloneNode();
    var ballCloneStyle = ballClone.style;
    ballCloneStyle.transform = "rotateY(" + i + "deg)"; //1deg ずつずらして180度分重ねる
    ballCloneStyle.borderColor = "hsl(" + i*2 + ", 100%, 50%)"; //ボーダー色を hsl で設定
    ballWrap.appendChild(ballClone);
}

円を 1deg ずつずらしていきますが半周すれば丁度球体になるので、for で180回繰り返しました。ボーダー色は球体と直接関係はないですが、異なる色を付けていないと球体に見えなかったため虹色にしています。それをアニメーションさせることでより球体に見せています。

デモ

GoogleChrome が一番安定して球体に見えている気がします。180個の要素をアニメーションさせているので仕方ありませんが Firefox だと少し重いです。IE に至っては transform-style で 3D に対応していないため平べったくなってしまいます。

気になった方がいれば色んなブラウザで見てみてください。

まとめ

要素を180よりも増やせばもっとより球体に近づくのだとは思いますが、これでも結構重いです。また、要素の背景色を設定すればより球体に見えます。でも、これも重すぎてブラウザが落ちそうになってしまいました。なかなか厳しいです。

3Dは今は WebGL を使って書くのが主流なので、わざわざ div を使って作る必要はないのでしょうが、やってみると面白かったです。