状況に合わせたプログレスバーで待ち時間を「見える化」する(2/2)

オープニングのローディング画面をつくる

サンプルとして、冬景色写真のギャラリーサイトを用意した。このオープニングのローディング画面を実装してみよう。進捗状況をプログレスバーのアニメーションで示し、さらにサイト内容を想起させるローディングアイコンも合わせて表示する。

06 今回作成したローディング画面。サンプルのサイトは冬景色の写真ギャラリーなので、プログレスバーの上には降雪をイメージしたローディングアイコンを置いている

進捗率を取得する仕組み

HTML上のすべての画像(もしくは指定の画像※3)を取得し、それぞれの画像の読み込みが完了するたびにイベントを発生させる。その読み込み完了数を加算していき、イベントを設定した画像の合計数から進捗率を計算する。その進捗率をプログレスバーや、数値として画面に表示するのだ。この仕組みを、jQuery、そしてライブラリ「jQuery.ImgLoader※4」と「TweenMax※5」を使用して実装していく。

ImgLoaderで進捗率を取得

HTMLとJavaScriptは01と02のような構成になる。HTMLでは、ローディングの監視対象となる範囲にclass属性「preload」を付与しておく。この範囲内の画像にのみ、ImgLoaderのイベント、つまり、進捗率を監視するよう設定していく。

class属性「preload」の画像を用意した配列imgSrcsに格納し、ライブラリに渡す。

progressイベントは、指定した範囲内の要素の読み込みが完了するたびに呼び出される。その戻り値として、読み込む要素の全体数を1とした場合の、現在の進捗率が0から1の間で返ってくる。進捗状況の表示の更新をこのタイミングで行う。

itemloadイベントは要素ごとの読み込みが完了したタイミングで呼び出される。その戻り値として、読み込んだ要素が返ってくる。

allloadイベントは、すべての要素の読み込みが完了したときに呼び出される。このタイミングで、ページコンテンツ全体をアニメーションさせながら表示する。最後にloader.load()関数を呼び出してロードを実行する。

<main class="l-main preload"> // --------A
 
  ...中略...
 
 </main>
01 HTMLの抜粋(sample/index.html)。class属性「preload」を付与した要素の範囲が、ローディングの監視対象となる
var $preload = $('.preload');
 
 var $loading = $('#js-loading');
 
 var $progressBar = $('#js-progress');
 
 var $container = $('#js-container');
 
 $container.addClass('is-loading');
 
 
 
 var imgSrcs = []; 
 
 
 
 $preload.find('img').each(function(){
 
  imgSrcs.push($(this).attr('src'));
 
 }); 
 
 
 
 var loader = new $.ImgLoader({
 
  srcs : imgSrcs, //画像などのパスを配列に格納 --------B
 
  pipesize: 2, //同時にロードできる数の上限
 
  delay: 500, //次のロードまでの遅延をミリ秒で指定
 
  timeout: 500, //タイムアウトまでの時間をミリ秒で指定
 
  useXHR2: false //XMLHttpRequestVersion2を利用するかどうか
 
 });
 
 
 
 loader.on('progress', function(progress) { // --------C
 
  var prog = progress.loadedRatio; //進捗率を取得
 
  TweenMax.to($progressBar, 0.5, {
 
  width: progress.loadedRatio*100 + '%' //進捗率を幅に反映
 
  });
 
 });
 
 
 
 loader.on('itemload', function($img) { // --------D
 
 });
 
 
 
 loader.on('allload', function($img) { // --------E
 
  $container.removeClass('is-loading');
 
  TweenMax.to($loading, 0.5, {
 
  autoAlpha: 0,
 
  onComplete: function() {
 
  TweenMax.set($loading, {display: 'none'});
 
  },
 
  delay: 1
 
  });
 
 });
 
 
 
 loader.load(); //ロードを実行 --------E
02 JavaScriptの抜粋(sample/js/app.js)。ImgLoaderのイベントごとに処理を書いていく。progressイベントでは進捗率の計算、allloadイベントではローディング画面の削除と、ページコンテンツ全体の表示、といった具合だ

 

進捗率をプログレスバーのアニメーションに反映させる

ここから、「期待感」を表現する“遊び”の部分を実装していく。プログレスバーの幅をアニメーションで変化させていき、伝えるべきところ、つまり後どれくらいで「待ち時間」が終了するのかを表現する。自前で書くのことが難しい場合でも、ライブラリを使えば比較的簡単に実装できる。

TweenMaxでアニメーションの追加

プログレスバーは、ボックス(div要素)の幅を0%から100%へと変化させることで表現する。progressイベント発生時に取得できる進捗率を使用して、TweenMaxライブラリでボックスの幅をアニメーションさせていく。

まず、HTML上でプログレスバーのボックスを作成して(03)、CSSで装飾し(04)、このときバーの幅は0%に設定しておく。

<div id="js-loading" class="loader">
 
  <div class="loader-icon"></div> 
 
  <div class="loader-wrapper">
 
  <div id="js-progress" class="loader-progress"></div>
 
  </div>
 
 </div>
 
 
03 HTMLの抜粋(sample/index.html)。プログレスバーとローディングアイコンのマークアップ
.loader .loader-progress {
 
  width: 0%; // --------A
 
  height: 3px;
 
  background-color: #c9c9c9;
 
 }
04 CSSの抜粋(sample/css/style.css)。初期状態では幅(width)を0%にしておく

そして、progressイベントが発生した時点で0~1の値を取得できるので、その値に100を掛けて新しい幅を設定する。TweenMaxの使い方は簡単だ。toメッソドのオプションとして、「変化させる要素(ここでは、プログレスバー)」「変化させるプロパティと値(ここでは幅)」「アニメーションにかける時間(秒)」を設定するだけである。

loader.on('progress', function(progress) {
 
  var prog = progress.loadedRatio; //進捗率を取得 // --------B
 
  TweenMax.to($progressBar, 0.5, { // --------C
 
  width: progress.loadedRatio*100 + '%' //進捗率を幅に反映 --------C
 
  }); // --------C
 
 });
05 JavaScriptの抜粋(sample/js/app.js)。進捗率をもとに、to メッソドでボックスの幅を変化させる

ローディングアイコンの表示

ローディングアイコンは最初に画面上に表示される必要があるので、なるべく軽いものを選択する。今回は、スプライト画像を使用し(07)、background-positionプロパティをCSSのanimationで変化させて動きをつけている(06)。パラパラ漫画のイメージだ。

.loader .loader-icon {
 
  position: absolute;
 
  top: 50%;
 
  left: 50%;
 
  width: 100px;
 
  height: 100px;
 
  transform: translate(-50%, -50%);
 
  background-image: url(../images/snow-sprite.png);
 
  background-position: 0 -3200px;
 
  background-repeat: no-repeat;
 
  animation: loadingAnimation 15s steps(100) 0.4s infinite;
 
 }
 
 @keyframes loadingAnimation {
 
  100% {
 
  background-position: 0 0;
 
  }
 
 }
06 CSSの抜粋(sample/css/style.css)。animationプロパティで動かす
07 スプライト画像(snow-sprite.png)の一部。実物は、100×3,200ピクセルある

UIを超えた発想を

「“体感”の待ち時間」を短縮するためには、遊び心が重要ではないだろうか。ストレス軽減のために遊び心を考えることは、UIというよりも、UXの領域まで踏み込んでいるかもしれない。だが、その発想で考えていくことで、「パーツとしてのUI」を超えたモノを作ることができるはずだ。

※3 ローディングを監視する際、HTML上のすべての画像を対象とする必要はない。ページのファーストビューの範囲に含まれない画像なら、見た目を損なうわけではないので、わざわざそこの画像が読み込まれるまで待つ必要はなく、イベントへの登録は不要だ。

※4 https://github.com/Takazudo/jQuery.ImgLoader

※5 https://greensock.com/tweenmax

 

野辺地美可子
ITベンチャー企業にてWebデザイン・フロントエンド・ディレクション業務に従事したのち、2013年より株式会社LIGに参画。コンセプト・ブランド設計から入り込んだデザイン業務を担当している。

 

中村大騎
独立系SIerを経て、Webデザイン会社にてバックエンドエンジニアとして従事。その後、フロントエンドエンジニアとして株式会社LIGに参画。最近は、IoTの勉強会登壇など、Webにとらわれない表現を求めている。 http://liginc.co.jp/
  • URLをコピーしました!
目次