stylesheet

2017-11-13

CSS: transform-styleを用いた3D視差回転アニメーション

transform-styleプロパティへpreserve-3dを設定すると子要素を3D空間に配置することができる。 これを使用すると簡単なcssとスクリプトで視差回転アニメーションが実現できるので試してみた。

デモはこちら
対応ブラウザでマウスかタッチしてぐりぐりしてみて欲しい。

transform-style - CSS | MDN

k3d.css
.k3d {
  position: absolute;
  top: 50%;
  left: 50%;
  transform-style: preserve-3d;
  width: 600px;
  height: 600px;
  transform: translate(-50%, -50%) perspective(600px);
}

.k3d img {
  display: block;
  position: absolute;
}

.k3d__l0 {
  transform: translateZ(-30px);
  z-index: 1;
  opacity: 0.8;
}

.k3d__l1 {
  transform: translateZ(0px);
  z-index: 2;
}

.k3d__l2 {
  transform: translateZ(30px);
  z-index: 3;
}

.k3d__l3 {
  transform: translateZ(60px);
  z-index: 4;
}
index.html
<div class="k3d">
  <img class="k3d__l0" src="kuma0.svg" />
  <img class="k3d__l1" src="kuma1.svg" />
  <img class="k3d__l2" src="kuma2.svg" />
  <img class="k3d__l3" src="kuma3.svg" />
  ...
</div/>  

k3d要素を画面中央に配置。この要素が回転アニメーションさせる面となる。
回転時に視差効果が出るよう4枚の画像をZ方向へずらしながら重ねて配置した。

k3d.js
var flip = false;
var style = "translate(-50%, -50%) perspective(600px)";
var el = document.querySelector(".k3d");
var x = 0, y = 0;

var render = function() {
  el.style.transform = style +
    " rotateY(" + (flip ? x + 180 : x) + "deg)" + " rotateX(" + y + "deg)";
};

document.addEventListener('pointermove', throttle(20, function(e) {
  x = -(window.innerWidth / 2 - e.clientX) * 0.03;
  y = (window.innerHeight / 2 - e.clientY) * 0.02;
  render();
}), false);

document.addEventListener('click', function(e) {
  if (e.button == 0) {
    flip = !flip;
    render();
  }
}, false);

マウス移動(タッチ移動)をキャプチャして回転量を調整しながらtransformプロパティを変化させてk3d要素を回転させる。 translateでマイナス方向へ移動させ、perspectiveを指定しているので、回転の原点は画面中央且つ奥方向へ600pxとなる。
また、クリックで180度多く回転させて後ろ姿も見れるようにした。

throttleはイベントを間引く関数。

以上。かなりのお手軽さ。