[jQuery]スクロール量に応じて(連動して)、アニメーションさせる方法
アニメーションというか、jQueryでスクロールを監視して数値化し、それをリアルタイムに反映させることで滑らかに動かす方法。スクロール量に連動させているので、スクロールするたびにアニメーションのような滑らかな動きをします。
色々な使い方があると思うけど、ここではwidth
の値をリアルタイムに更新し、スクロール量に応じて幅を広げたり狭めたりする方法をのせています。
デモとHTMLとCSS
言葉だけだと説明が難しいので、デモを見てもらうと何をやりたいのか分かるかと思います。とてもシンプルです。※古いIEでは見れません。
デモでは5種類ありますが、基本的にはスタート位置(CSS)が違うだけで、内容はほとんど同じ。
HTML
HTMLは何でも良くて、便宜上、空divの要素を更新するような形にしています。
<div class="contents">
<div class="line"></div>
</div>
子要素の div.line
の width
の値をリアルタイムに更新します。
CSS
CSSも基本は何でも良くて、とりあえず位置を決めるためだけに指定しています。
.contents {
position: relative;
width: 100%;
height: 100vh;
}
.line {
position: absolute;
top: 0;
left: 0;
bottom: 0;
margin: auto;
width: 0;
height: 5px;
background: #EC4E20;
}
位置は position
で指定していますが、何でもいいはず。ここでは、左の真ん中からスタートするようになっています。
※上記のままだとスクロールしないので、bodyのheightを大きくとって.contentsにmargin-topを与えるなど、スクロールさせる環境を用意する必要があります。
jQuery
jQueryは、非常に単純なことしかやっていません。書いていないけど、jQueryなので当然jQueryの読み込みが別途必要。
$(function () {
$('div.line').each(function () {
var $win = $(window),
$winH = $win.height(),
$connect = $(this),
position = $connect.offset().top,
current = 0,
scroll;
$win.on('load scroll', function () {
scroll = $win.scrollTop();
current = (1 - (position - scroll) / $winH) * 2 * 100;
if (current > 99.9) {
current = 100;
}
if (scroll > position - $winH) {
$connect.css({width: current + '%'});
}
});
});
});
太(赤)字の部分が値を取得する計算式になっています。多分、他にもっとスマートな書き方があるんだろうけど、思いつかなかった。もっと良い方法があれば教えてください(小声)
対象の要素(div.line)が画面に現れた時を0として、画面の半分までスクロールした時に、widthの値が100%になるようにしてあります。ゴールの位置を決めているのが太(赤)字部分の「2」な訳ですが、これを変更することで100%までの位置を変えることができます(数が小さいほど上へ)。
太(赤)字部分の「* 100」を外せば0から1の範囲で値が変わるようになるので、opacity
やなんかに使えますね。スクロールに併せてフェードインさせることができるようになります。
小数点以下を切り下げたり切り上げたりしていないのは、その方が滑らかだからです。スクロールの処理も間引いたりしていません。その方が滑らかだからです。
スクロールとアニメーション
最近の凝ったWebサイトでは、スクロールとアニメーションを連動したテクニックを多く目にしますが、スクロールとの連動はパフォーマンスの低下に繋がり、ユーザーの体感速度を阻害する恐れがあります。
ただ流行っているからということでやたらに使うのではなく、要所要所での効果的な使い方を心がけたいものです(自分に言い聞かせている)。
まとめ
width
や opacity
だけじゃなく、数値を指定するタイプのCSSプロパティで幅広く使えるかと思います。SVGにもいいですね。