[JavaScript General] CSS, jQuery, JavaScript による Smooth Scrolling の実装例と Easing に関するまとめ
いわゆる「ページのトップへ戻る」ボタンや「ページ内リンク」の移動に対して実装するアニメーションスクロールに関して。
主に下記の記事に掲載されていた内容と過去に書いていたコード等について、個人的な memo.
> * [Smooth Scrolling | CSS-Tricks](https://css-tricks.com/snippets/jquery/smooth-scrolling/)
> * [CSSだけでも実装できる!ページ内アンカーやページ上部にアニメーションでスクロールさせるCSS, JavaScriptのまとめ | コリス](https://coliss.com/articles/build-websites/operation/work/scroll-page-smoothly-by-css-and-javascript.html)
## CSS
`scroll-behavior: smooth` プロパティを利用する方法。
IE, Edge, Safari 等で動かないので Polyfill が必要になります。
– スクロールするコンテナに対してプロパティをあてる。
– ユーザーエージェント定義のタイミング関数を使い、ユーザーエージェント定義の時間をかけて、円滑にスクロールする。
“`css
html {
scroll-behavior: smooth;
}
“`
> * [scroll-behavior | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/scroll-behavior)
> * [Can I use… Support tables for HTML5, CSS3, etc](https://caniuse.com/#search=scroll-behavior)
> * [iamdustan/smoothscroll: Scroll Behavior polyfill](https://github.com/iamdustan/smoothscroll)
アニメーションに特別な指定が無いプロジェクトであれば、現状一番自然な実装かも知れませんね。
## jQuery
### jQuery を利用した方法
このブログの過去記事に載っていたもので、よくある実装。
意外にも、そのものズバリの記事は書いていませんでした。
> * [[Grunt & Yeoman] grunt-contrib-uglify で JavaScript ファイルの結合・難読化・圧縮をする | deadwood](https://www.d-wood.com/blog/2013/11/25_5063.html)
“`javascript
$(function() {
$(“#back-to-top”).hide();
$(window).scroll(function() {
if ($(this).scrollTop() > 60) {
$(“#back-to-top”).fadeIn();
} else {
$(“#back-to-top”).fadeOut();
}
});
$(“#back-to-top a”).click(function() {
$(“body,html”).animate({
scrollTop: 0
}, 500);
return false;
});
});
“`
Github で過去のリポジトリを検索したところ、こういった実装も利用していました。
現在は少し実装方法が変わっていました。
> * [Smooth Scrolling | CSS-Tricks](https://css-tricks.com/snippets/jquery/smooth-scrolling/#article-header-id-1)
“`javascript
// To capsule for WordPress
jQuery(function($) {
“use strict”;
$(‘a[href*=”#”]:not([href=”#”])’).click(function () {
if (location.pathname.replace(/^\//, ”) === this.pathname.replace(/^\//, ”) && location.hostname === this.hostname) {
var target = $(this.hash);
target = target.length ? target : $(‘[name=’ + this.hash.slice(1) + ‘]’);
if (target.length) {
$(‘html,body’).animate({
scrollTop: target.offset().top
}, 500);
return false;
}
}
});
});
“`
その他。
> * [jQueryでページ内スクロールの速度・位置をカスタマイズする | UX MILK](https://uxmilk.jp/40702)
“`javascript
// ページ内リンクのみ取得します。
$(‘a[href^=#]’).click(function(){
//デフォルトのイベントをキャンセル
event.preventDefault();
// 移動先となる要素を取得します。
var target = $(this.hash);
if (!target.length) return;
// 移動先の位置を取得します
var targetY = target.offset().top;
// animateで移動します
$(‘body’).animate({scrollTop: targetY}, 500, ‘swing’);
});
“`
### jQuery Plugin を利用した方法
過去記事掲載。何かのプロジェクトで利用されていて調査しました。
> * [[jQuery] jquery-smooth-scroll: ページ内リンクをスムースにスクロールさせる | deadwood](https://www.d-wood.com/blog/2014/12/09_7301.html)
その他。
> * [bartholomej/material-scrolltop: Lightweight, Material Design inspired plugin for scrolling on top of the html page (with jQuery)](https://github.com/bartholomej/material-scrollTop)
おまけ。Vue.js のコンポーネント。
> * [caiofsouza/vue-backtotop: A Back-to-top component for Vue.js, which scroll page to the top when clicked](https://github.com/caiofsouza/vue-backtotop)
## JavaScript
Vanilla JavaScript つまり jQuery に依存していない。
> * [tanrax/simplescrollup: Simple plugin in Javascript to animate scrolling when you return to the top of the page](https://github.com/tanrax/simplescrollup)
> * [callmecavs/jump.js: A modern smooth scrolling library.](https://github.com/callmecavs/jump.js)
> * [cferdinandi/smooth-scroll: A lightweight script to animate scrolling to anchor links.](https://github.com/cferdinandi/smooth-scroll)
### Easing
> * [Easing Function 早見表](https://easings.net/ja)
イージングに関する部分のソースを読むと、Robert Penner さんという名前をたびたび見かけます。
> * [Robert Penner’s Easing Functions](http://robertpenner.com/easing/)
その理由?
> はっきりとした起源はわからなかったのですが、どうやら、世の中に存在するイージングは、氏の考えたイージングそのものであるか、そのバリエーションであるものが多いようです。イージングのことを調べていると、いつもRobert Pennerという名前が出てきます。
>
> [イージングの仕組み – イージングとはなにか | CodeGrid](https://app.codegrid.net/entry/easing-1)
ライブラリ。
> * [Simple Easing Functions in Javascript – see https://github.com/gre/bezier-easing](https://gist.github.com/gre/1650294)
> * [jaxgeller/ez.js: Importable easing functions in es6 for tweening](https://github.com/jaxgeller/ez.js)
### requestAnimationFrame
> * [window.requestAnimationFrame | MDN](https://developer.mozilla.org/ja/docs/Web/API/Window/requestAnimationFrame)
> * [いまさらrequestAnimationFrameを理解する – console.lealog();](https://lealog.hateblo.jp/entry/2013/10/01/235736)
> * [Canvas と requestAnimationFrame でアニメーション – Qiita](https://qiita.com/hoo-chan/items/398cfc8514c0f1cd984d)
> * [Basic animations | MDN](https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Canvas_tutorial/Basic_animations)
## 補遺
HTML
“`html:test
“`
CSS
“`css
.js-scroll-up {
background-color: #eee;
color: #fff;
cursor: pointer;
height: 60px;
width: 60px;
// layout
display: none;
position: fixed;
bottom: 0;
right: 0;
}
“`
jQuery
“`javascript
$(() => {
const win = $(window);
const jsScrollUp = $(‘.js-scroll-up’);
win.on(‘load scroll’, function scrollToTop() {
const scrollValue = $(this).scrollTop();
if (scrollValue > 100) {
jsScrollUp.fadeIn();
} else {
jsScrollUp.fadeOut();
}
});
jsScrollUp.on(‘click’, () => {
$(‘body,html’).animate({
scrollTop: 0,
}, 500);
});
});
“`