Mach3.laBlog

JavaScriptのスライダーにブラー効果をつけてみる実験

この記事は賞味期限切れです。(更新から1年が経過しています)

先日リニューアルのご報告をした Matsukaze.で使用している ブラー効果をつけたスライダーで、実験的に採用した手法を記録しておきます。

JavaScriptのスライダーにブラー効果をつけてみる実験

  1. 基本的な仕組み
  2. ぼかし画像の透明度について
  3. 簡単なデモ
  4. まとめ

基本的な仕組み

まずスライダーに使用する絵を連結して一枚の画像にしたものを作成。 そして、その画像を横にブレさせた画像を別途用意します。

連結画像とぼかし画像

ぼかし画像は、例えばFireworksなら「移動(ぼかし)」を水平方向にかけ、 さらにその上に反対方向の「移動(ぼかし)」をかけたものを透明度50%ぐらいで重ねています。 ぼかしの強さはコンテンツの内容・大きさとご相談で、いい按排を探ります。

HTML上ではその2つの画像を、ぼかし画像を上にして重ね合わせて配置し、 スライダーが動く時にぼかし画像の透明度を変更してスピード感を出します。

基本的な仕組み

基本的な仕組みはこんな感じです。

ぼかし画像の透明度について

さて、課題はぼかし画像の透明度をどのように調整するか。 前提として、こんなHTMLとスタイルシートを用意しました。

<div id="my-slider" class="blur-slider">
    <div class="slider-images">
        <img src="./photo-blur.png" class="image-blur" />
        <img src="./photo.png" />
    </div>
</div>

<style>
    .blur-slider {
        position: relative;
        width: 500px;
        height: 331px;
        border: 2px solid #fff;
        margin: 0 auto;
        overflow: hidden;
    }
    .blur-slider .slider-images {
        position: absolute;
        left: 0;
        top: 0;
    }
    .blur-slider .slider-images .image-blur {
        position: absolute;
        opacity: 0;
        filter: alpha(opactiy=0);
    }
</style>

普通に値を変更した時のコレジャナイ感

まずはじめに、単純にスライダーと同時にぼかし画像を表示させ、アニメーション終了にあわせて透明度を下げていってみました。 ざっと書くとこんな感じです。

var $container, $slider, $blurImage, show;

$container = $("#my-slider");
$slider = $container.find(".slider-images");
$blurImage = $slider.find(".image-blur");

show = function(index){
    $slider
        .stop()
        .animate(
                { left: $container.width() * index * -1 }
        );
    $blurImage
        .stop()
        .css("opacity", 1)
        .animate(
                { opacity: 0 }
        );
};

show(1); // とりあえず2番目の画像を表示してみる

動かしてみましたが、かなり動きに違和感があります。 他にも、変化を山なりにしてみたりしましたが、どうもコレジャナイ。 イージング関数によってはまともに見えるかもしれませんが、 実際の速度とブレが同期してないので気持ち悪くて当然ですね。

はやければはやいほどブレるように

やはりブレは動きの速さに比例するもの。 そこで、動きがはやければはやいほどブレるように調整した show 関数を書いてみます。

show = function(index){
    $slider.stop().animate(
        { 
            left : $container.width() * index * -1 
        },
        {
            duration : 500,
            easing : "swing",
            step : function(now){ /* A */
                if(this.prevLeft !== undefined){
                    $blurImage.css(
                        "opacity", 
                        Math.abs(this.prevLeft - now) / 25 /* B */
                    );
                }
                this.prevLeft = now;
            },
            complete : function(){ /* C */
                $blurImage.css("opacity", 0);
            }
        }
    );
};

(A) jQuery.animate のオプションの “step” では、アニメーションのステップ毎に関数を実行する事ができます。 上の例では、前ステップの値と現在の値を比較して、その差からぼかし画像の透明度を計算しています。

(B) “25”は、1ステップに何ピクセル以上動いている時に不透明度100%とするか、という数値です。 要するにどのくらいの速度ならばブラーが最大限表示されるか。 移動距離やコンテンツの大きさでうまいこと調整します。

(C) “complete” はアニメーション完了時の関数を実行できます。 完了時にはぼかし画像の不透明度をゼロにします。

ステップ毎に計算させる関係でパフォーマンスがちょっと心配になりますね。 多用はあまりしない方がよさそうですが、今回の Matsukaze. では2箇所限定なので、この方法を採用してみちゃいました。 やはり少々重たい気がしますが、ブレが少し自然になったとおもいます。

簡単なデモ

イージング関数と所要時間をいじれるデモを作ってみましたのでどうぞ。

JS Bin

まとめ

わりと泥臭い感じではありますが、パフォーマンスはともかく見た目的には結構満足しています。 もう少しスマートな方法あったら、改善してみたいです。

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*