[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);
});
});
“`