スクロールするとフワッとアニメーションさせる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>
コメント