STEP 3:クリックによる回転
画像を全面に表示した直方体が完成したので、ナビゲーションがクリックされたら回転するアニメーションを作る。直方体をrotateXで90度回転させると底面が正面に変わり、正面は上面へ移動する。同様に、今度はrotateXを180度回転させると、初期状態で正面だった面は上面から背面になり、正面は初期状態の背面になる。
回転する角度は、ナビゲーションとなるa要素にカスタムデータ属性「data-deg」を設定して格納する。a要素がクリックされるとjQueryでdata-degの値を読み出し、transformプロパティの引数に指定する。これで、ナビゲーションごとに指定された角度にページ全体が回転するようになる。
■ソースコード(HTML)
<div class="nav">
<ul>
<li><a data-deg="0" class="active" href="#">0deg</a></li>
<li><a data-deg="90" href="#">90deg</a></li>
<li><a data-deg="180" href="#">180deg</a></li>
<li><a data-deg="270" href="#">270deg</a></li>
<li><a data-deg="315" href="#">315deg</a></li>
</ul>
</div>
■ソースコード(CSS)
/* ナビゲーション部分、他はSTEP2のCSSを引き継ぎ */
.nav {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
}
.nav li {
float: left;
width: 20%;
}
.nav li a{
display: block;
width: 100%;
line-height: 40px;
text-align: center;
text-decoration: none;
color: #fff;
height: 40px;
background:rgba(0,0,0,0.6);
font-size: 13px;
letter-spacing: 3px;
transition:all 0.5s ease-in-out;
}
■ソースコード(JavaScript)
$(function(){
function setCube(){
wW = $(window).width();
wH = $(window).height();
$('.cube').css({'transform':'translateZ(-'+wH/2+'px)'});
$('.cube,.cube div').css({width :wW,height:wH});
$('.cube_top').css({top:-wH/2});
$('.cube_bottom').css({bottom:-wH/2});
$('.cube_front').css({'transform':'translateZ('+wH/2+'px)'});
//背面が回転で上下逆になるのを回避
$('.cube_back').css({'transform':'translateZ(-'+wH/2+'px) rotateX(180deg)'});
}
setCube();
$(document).on('click', '.nav a', function(event) {
event.preventDefault();
var deg = $(this).data('deg');
$('.cube').css({'transform':'translateZ(-'+wH/2+'px) rotateX('+deg+'deg)'});
});
$(window).on('resize',function(){
//画面をリサイズした際に各面もリサイズさせる
setCube();
});
});
STEP 4:2段階のアニメーション
HUMAANの例では、直方体をいったん奥へ移動させ、その後で回転させている。
そこで、ナビゲーションがクリックされたら、$('.scale').css({'transform':'translateZ(-200px)'});で直方体を奥へ移動させ、その後でSTEP 3の回転を実行し、最後に $('.scale').css({'transform':'translateZ(0px)’});で手前に位置を戻す。それぞれのアニメーションは、setTimeout()で実行間隔を空けている。
■ソースコード(JavaScript)
$(function(){
function setCube(){
wW = $(window).width();
wH = $(window).height();
$('.cube').css({'transform':'translateZ(-'+wH/2+'px)'});
$('.cube,.cube div').css({width :wW,height:wH});
$('.cube_top').css({top:-wH/2});
$('.cube_bottom').css({bottom:-wH/2});
$('.cube_front').css({'transform':'translateZ('+wH/2+'px)'});
$('.cube_back').css({'transform':'translateZ(-'+wH/2+'px) rotateX(180deg)'});
}
setCube();
$(document).on('click', '.nav a', function(event) {
event.preventDefault();
var deg = $(this).data('deg');
//アニメーション重複を回避
if(!$(this).is('.active')){
$('.scale').css({'transform':'translateZ(-200px)'});
setTimeout(function(){
$('.cube').css({'transform':'translateZ(-'+wH/2+'px) rotateX('+deg+'deg)'});
setTimeout(function(){
$('.scale').css({'transform':'translateZ(0px)'});
},500);
},500);
}
//アニメーション重複を回避
$(this).parents('ul').find('a').removeClass('active');
$(this).addClass('active');
});
$(window).on('resize',function(){
setCube();
});
});
さまざまなブラウザーに向けたアニメーションの分岐
今回作成したアニメーションは、Internet Explorerなどの一部のブラウザーでは動作しないが、top,bottomといったプロパティは有効なため、表示が崩れてしまう。
そこで、3Dアニメーションを再生できるブラウザーとそれ以外(IEと、transform-styleが利用できないブラウザー)でアニメーションを振り分けるのが現実的だ。詳しくはデモページのソースコードを参照してほしい。
DEMO > http://zxcvbnmnbvcxz.com/demonstration/as/007/preserve-3d.html
著者:利倉健太(としくら・けんた)
1985年生まれ。株式会社レターズのデザイナー。2010年からWebデザイナーとして働き始める。Webに関する活動拠点「Stronghold」というサイトでブログを書いたり、デザインの実験をしている。