超軽量スクロールアニメーションライブラリSal.jsを試す

スクロールするとフワッとアニメーションさせるJSライブラリで軽量の物を探していたら、Sal.jsというものを見つけました。
今回試したバージョンは0.8.5です。

jsファイルは約3kbと超軽量で、cssファイルを含めると約20kbになります。

仕組みとしてはIntersectionObserverを利用していて、要素が画面内に入ると指定されたclassを付け加えるようになっていました。

使ってみた感想をざっくり伝えると、超軽量なので細かな制御はできませんが、サイト内のアニメーション表示方法がルール化されている場合に使用できる感じです。

目次

使い方

HTML

要素にdata-sal を書いて動作を制御します。

<div
  data-sal="slide-up"
  data-sal-duration="200"
  data-sal-delay="300"
  data-sal-easing="ease-out-back"
></div>
data-sal

以下のアニメーションが設定できます。

  • fade
  • slide-up
  • slide-down
  • slide-left
  • slide-right
  • zoom-in
  • zoom-out
  • flip-up
  • flip-down
  • flip-left
  • flip-right
data-sal-duration

アニメーション時間を 200ms から 2000ms までの間で設定します。
220msのような設定はできなく、250msのように50ずつ加算した値が設定できます。
これはcssファイルを見ると分かる部分で、transition-durationが50ずつ加算された値で作成されているためです。
大本であるscssを編集して出力を好きなようにできますが、後述のカスタムスタイルを書く方法もあります。

data-sal-delay

アニメーションディレイを 5ms から 1000ms で設定できます。
こちらもdata-sal-duration同様50msごとに加算します。

sal-easing

イージングを設定します。 詳しくは easings.net 参照。

data-sal-once

アニメーションを1回だけ再生します。デフォルトです。

data-sal-repeat

要素が画面に入るたびにアニメーションさせるようにします。

style (カスタムスタイル)

カスタムスタイルを設定する場合は、style属性に--sal-durationのような記述を追加します。--sal-durationの他に --sal-delay--sal-easingが設定できます。

<div
  data-sal="slide-up"
  style="--sal-duration: 3s; --sal-delay: 2s; --sal-easing: cubic-bezier(0.68, -0.6, 0.32, 1.6)"
></div>

設定できる属性はこれだけでシンプルな作りです。

ある要素だけアニメーション開始位置をコントロールしたい場合などあると思いますが、Sal.jsにはそのような設定が無いので割り切りが必要です。

JS

オプション無しだと以下を実行するだけです。

sal();

代表的なオプションは以下です。

threshold

要素が画面内に何%入ったらアニメーションを開始するか。
デフォルトは0.5なので、要素が画面内に50%入ったらアニメーションが開始されます。詳しくはこちら(英語)。

once

アニメーションを1度再生させる場合はtrue(デフォルト)、要素が画面内に入るたびに再生させるリピートモードにする場合はfalseにします。

その他のオプションはこちらです。

使ってみた感想

要素ごとにアニメーション開始位置の設定ができないので、ざっくり作る場合に使える印象です。

細かいところを気にしなければ初期状態で使えると思いますが、どうしてもアニメーションcss設定が気になるので、少しだけファイル調整が必要だと思います。

特に気になるアニメーションはスライドアップ(スライドダウン含む)です。スライドアップは要素が下から上に表示される動きで、Sal.jsの初期cssの設定が、transform:translateY(50%)になっているため、縦長要素の場合は変な位置からアニメーションが開始されます。
ついでにリピートモードにするとスクロール停止位置によっては、表示/非表示を繰り返してしまいます。

もう1つは、アニメーション開始の判定になるthresholdの初期設定も0.5(50%)のため、縦長要素を使うとアニメーションがなかなか開始されないのでこちらも調整が必要かと思います。

以下のサンプルで何となく伝わると思います。

See the Pen Sal.js Test by hakoirioyaji (@hakoirioyaji) on CodePen.

もっと細かい制御が必要であれば有名どころのAOSが良いのではないかと思います。

コピペで試せるソースコード

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sal.js@0.8.5/dist/sal.css">
</head>
<body>
  <style>
    html, body{
      margin: 0;
    }

    section {
      min-height: 1000px;
      background-color: #F5F5F5;
      padding: 1em;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    section:nth-child(odd) {
      background-color: #EAEAEA;
    }

    section.repeat .box {
      width: 500px;
      height: 500px;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: rgb(157, 175, 154);
      padding: 0.5em;
      margin: 2em 0;
    }

    .box.-large {
      height: 1000px;
    }

    .box:nth-child(odd) {
      background-color: chocolate;
    }

    /* [data-sal=slide-up] のデフォルトが transform:translateY(50%) のため、
      要素の高さが広いと初期位置が大幅にずれる。そのため場合によってはpxに変更する。 */
    [data-sal=slide-up]{transform:translateY(30px)} 
  </style>

  <section><h1>SCROLL DOWN</h1></section>
  <section>
    <h1>ONCE</h1>
    <div class="box" 
      data-sal="fade" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >fade</div>

      <div class="box" 
      data-sal="slide-up" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >slide-up</div>

      <div class="box" 
      data-sal="slide-down" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >slide-down</div>

      <div class="box" 
      data-sal="slide-left" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >slide-left</div>

      <div class="box" 
      data-sal="slide-right" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >slide-right</div>

      <div class="box" 
      data-sal="zoom-in" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >zoom-in</div>

      <div class="box" 
      data-sal="zoom-out" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >zoom-out</div>

      <div class="box" 
      data-sal="flip-up" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >flip-up</div>

      <div class="box" 
      data-sal="flip-down" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >flip-down</div>

      <div class="box" 
      data-sal="flip-left" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >flip-left</div>

      <div class="box" 
      data-sal="flip-right" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      >flip-right</div>
  </section>

  <section class="repeat">
    <h1>REPEAT</h1>
    <div class="box" 
      data-sal="fade" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      >fade</div>

      <div class="box" 
      data-sal="slide-up" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      style="display:flex; flex-direction: column; justify-content: space-between;"
      ><div>slide-up</div><div>この辺りを画面上ギリギリに表示させると永久ループ</div></div>

      <div class="box" 
      data-sal="slide-down" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      >slide-down<br>ここの辺りを画面下ギリギリに表示させると永久ループ</div>

      <div class="box" 
      data-sal="slide-left" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      >slide-left</div>

      <div class="box" 
      data-sal="slide-right" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      >slide-right</div>

      <div class="box" 
      data-sal="zoom-in" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      >zoom-in</div>

      <div class="box" 
      data-sal="zoom-out" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      >zoom-out</div>

      <div class="box" 
      data-sal="flip-up" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      >flip-up</div>

      <div class="box" 
      data-sal="flip-down" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      >flip-down</div>

      <div class="box" 
      data-sal="flip-left" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      >flip-left</div>

      <div class="box" 
      data-sal="flip-right" 
      data-sal-duration="1000" 
      data-sal-delay="100"
      data-sal-easing="ease-out"
      data-sal-repeat
      >flip-right</div>
  </section>
  
  <section>END</section>
  
  <script src="https://cdn.jsdelivr.net/npm/sal.js@0.8.5/dist/sal.min.js"></script>
  <script>
    sal({
      threshold: 0.05
    });
  </script>
</body>
</html>
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次