2017/05/17

ロード中に表示するシマー効果付きスケルトンスクリーンを実装する

ロード中にユーザの離脱を防ぐためには、プログレスバーやスピナーを表示する手法が定番だ。フリーズしているわけではなくて、ちゃんと処理してますよと示すことにより、ユーザのストレスを軽減できる。

4秒未満ならスピナー、それ以上ならプログレスバー。
所要時間がわかるならプログレスバー、わからないならスピナー。

など使い分けもされている。


しかし、ここ1〜2年くらいでプログレスバーやスピナーのかわりに、スケルトンスクリーンを使っているアプリやサービスが増えた。有名どころでは、FacebookやSlack、Mediumなどだ。

今回は、スケルトンスクリーンの実装方法を紹介する。

スケルトンスクリーンとは


スケルトンスクリーンは、画像やCSS、JavaScriptを読み込んでいる間にワイヤーフレームのようなボックスを表示し、UXを向上させるために使われる。ユーザにとってはプログレスバーやスピナーと違いどんなページが表示されるか予想できるため、ロード時間が長くても心理的に短く感じられる。

ただ、スケルトンスクリーンだけだと動きがないため、ちゃんと処理されているか不安になる。そこでシマー効果(キラキラさせるエフェクト)をつけることで、スピナーとしての役割も果たすことができる。

完成予想図は下図のとおり。

スケルトンスクリーンを実装する


<!-- index.html -->
<section class="card-item">
  <figure class="card-image -loading"></figure>
  <div class="card-detail">
    <h3 class="title -loading"></h3>
    <p class="description -loading"></p>
  </div>
</section>
/* style.sass */
body {
  background-color: white;
  color: #666666;
  padding: 10px;
}

.card-item {
  width: 320px;
  box-shadow: 0 4px 8px rgba(0,0,0,.2);
  transition: .3s;
  
  &:hover {
    box-shadow: 0 8px 16px rgba(0,0,0,.2);
  }
  
  > .card-image {
    margin: 0;
    width: 100%;
    height: 180px;
    
    > .image {
      width: 100%;
      height: 100%;
    }
  }
}

.card-detail {
  padding: 2px 16px;

  > .title {
    letter-spacing: 3px;
  }
  > .description {
    letter-spacing: 1px;
  }
}

.-loading {
  position: relative;
  background-color: #E2E2E2;
  border-radius: 15px;
  
  &.card-image {
    border-radius: 0;
  }
}
.title.-loading {
  height: 2rem;
}
.description.-loading {
  height: 80px;
}
// script.js
window.onload = () => {
  const cardImage = document.getElementsByClassName('card-image')[0];
  const title = document.getElementsByClassName('title')[0];
  const description = document.getElementsByClassName('description')[0];
  
  const render = () => {
    title.innerText = 'ポルトの街並み'
    description.innerText = 'ポルトはポルトガル北部の港湾都市。人口約263,000人。リスボンに次ぐポルトガル第二の都市。同国屈指の世界都市であり、ポルト都市圏では、人口は約160万人を数える。';
    title.classList.remove('-loading');
    description.classList.remove('-loading');
    cardImage.classList.remove('-loading');
  };
  
  const img = new Image(); 
  img.onload = () => {
    render();
    img.classList.add('image');
    cardImage.appendChild(img);
  };
  
  img.onerror = () => {
    render();
  };
  
  // 重い画像ファイル
  setTimeout(() => {
    img.src = 'https://www.pakutaso.com/shared/img/thumb/hiroto_htmachi.jpg';
  }, 5000);
};

画像の読み込みが完了するとimg.onloadイベントが発火され、実際の文章を表示、-loadingクラスを削除してカードの見た目を変更している。
※ 重い画像を読み込んだ想定で、setTimeoutに5000msを指定している。

これでスケルトンスクリーン→画像のように表示されるようになる。
次に今実装したスケルトンスクリーンに、シマー効果のアニメーションを付与する。



シマー効果を追加する


ロード中に反応がないとユーザはイライラしてしまうので、シマー効果(キラキラするエフェクト)を付与する。
/* style.sass */
/* 略 */
.-loading {
  position: relative;
  background-color: #E2E2E2;
  border-radius: 15px;
  
  &.card-image {
    /* 略 */
  }
  
  &::after {
    display: block;
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .2), transparent);
    animation: loading 1.5s infinite;
  }
}
/* 略 */
@keyframes loading {
  100% {
    transform: translateX(100%);
  }
}
/* 略 */

疑似要素(::after)に色をつけて、左から右に移動するようなアニメーションを指定している。これでグレーの部分がキラキラして見えるようになる。



参考サイト




以上

written by @bc_rikko

0 件のコメント :

コメントを投稿