読者です 読者をやめる 読者になる 読者になる

MANA-DOT

PIXEL ART, PROGRAMING, ETC.

ドット絵でパララックス効果

ScreenClip

トップページ でトップ絵に採用してみましたが、ドット絵で パララックス効果 をやってみました。

パララックス効果とはなんぞや

パララックス(parallax)とは日本語では視差のことで、大雑把に言うと視点が変わることによる物の見え方の違いのことです。

パララックス効果というと、近年おしゃれなWebデザインとして多方面で利用されている、スクロールやマウスの移動などで画像をずらし、その時にずらし方を画像ごとに変えてやることで遠距離感を出す手法を指すようです。 Google検索すると、おしゃれなサイトが沢山出てきます。

今回は、このサイトのトップ絵としてパララックス効果を利用した画像を採用してみました。

デモ

こんな感じで、マウスを動かすと視点を変えたかのような動きをします。

レシピ

画像の用意

今回は以下の様な画像を用意しました。 女の子ははじめからトップページ用ということで、僕の嗜好を詰め込んだ結果こんな子になりました。 また、パララックス効果を使うことも決めていたので、このようにものがぶちまけられてるような構図にしました。

20120418

html

<div id="parallaxImage">
    <div class="bg"       data-z="-600"></div>
    <div class="picture1" data-z="-570"></div>
    <div class="picture2" data-z="-530"></div>
...
</div>

htmlはこんな感じで、パララックスする画像を一つのdivで覆ってあげて、あとはパーツの個数だけ子要素を用意します。また、data-zという属性を指定していますが、これを利用してマウスが動いた時に動き方がそれぞれのパーツで変わるようになっています。詳しくはJavaScriptの説明時にします。

全体は割愛しているので、興味が有る方はこのページのソースを見てください。

css

div#parallaxImage { position: relative; width: 200px; height: 150px; }
div#parallaxImage div { position: absolute; background-image: url("http://manaten.net/wp-content/uploads/2013/05/20120418.gif"); display: block; overflow: hidden; }

div#parallaxImage div.bg { left: 10px; top: 0px; width: 180px; height: 150px; background-position: 0px 0px; z-index: 1; }
div#parallaxImage div.picture1 { left: 20px; top: 10px; width: 40px; height: 40px; background-position: -180px 0px; z-index: 2; }
div#parallaxImage div.picture2 { left: 130px; top: 10px; width: 40px; height: 30px; background-position: -180px -40px; z-index: 3; }
...

cssは、全体の枠に対してposition:relativeと大きさを指定してあげ、 各パーツのdivはcssスプライトで対応する画像を表示しつつ、position:absoluteで正しい位置に配置してあげます。 今回大変だったのが、22個のパーツに対してcssスプライトと絶対座標を指定してやることでした。 sass使ってなければ死んでいたと思います。 cssスプライトを使わなければかなり楽にはなると思いますので、手軽にやってみたい場合はオススメです。

JavaScript

最後にJavaScriptです。 巷ではパララックス効果用のライブラリもあるようですが、今回はjQueryのみ使用しました。

$(function() {
    var baseX = $('#parallaxImage').offset().left + 100;
    var baseY = $('#parallaxImage').offset().top  + 75;
    var layers = $('#parallaxImage').children().map(function(_, layer) {
        return {
            $: $(layer),
            factor:$(layer).data("z")/10000,
            baseX: $(layer).position().left,
            baseY: $(layer).position().top
        };
    });
    $(document.body).mousemove(function(ev) {
        $.each(layers, function(_, layer) {
            var dx = ev.pageX - baseX;
            var dy = ev.pageY - baseY;
            layer.$.css({
                left: layer.baseX + (dx*layer.factor) +"px",
                top:  layer.baseY + (dy*layer.factor) +"px" });
        });
    });
});

最初に全体の枠のオフセットに枠の幅・高さの半分を足したものをbaseX, baseYとして定義しています。 この値はページの端の座標を(0,0)としたときの、画像の中心の座標となります。 この座標から現在のマウス位置がどれだけずれているかを計算し、そのズレを元にパーツを動かしてあげます。

次のlayersの定義では、各パーツの情報の配列を作ってあげています。 上から、パーツのjQueryオブジェクト、パーツを動かすときの係数(htmlで設定した、data-zの値を使っています。)、 パーツの枠を起点とした相対座用x, yです。

最後に、bodyへのmousemoveイベントを指定してあげています。 その中でlayersをループで回し、それぞれのパーツに対して先に計算しておいたパーツの元々の座標に、マウスの座標と枠の中心の座標にdata-zから計算した係数をかけたものを足してあげています。

別の言い方をすると、画像の中心からマウスがどれだけずれているか、ずれているほどパーツもずらしてあげる。ただし、ずらすときにdata-zの値だけずらし方を変える(data-zが大きいものほど大きくずらす、負のものは逆方向にずらす)ということです。

おわり

あんまりわかりやすい説明ではなかったですが、やっていることはそんなに複雑ではありません。工夫次第でまだまだいろんなことができそうなので、興味が有る方はぜひやってみて、面白い表現をしてみてください。ちなみに僕はエロ方面での応用を既に思いついています。