Javascript

【Javascript】スクロールに合わせて要素をアニメーションさせるScrollReveal

December 3, 2017
ScrollReveal

ScrollRevealはウェブやモバイルブラウザ用にスクロールに合わせて要素を簡単にアニメーション化させるスクロールアニメーションライブラリ。

Getting Started

Installation

<script src="https://unpkg.com/scrollreveal/dist/scrollreveal.min.js"></script>

The Basics

<!-- HTML -->
<div class="foo"> Foo </div>
<div class="bar"> Bar </div>
// JavaScript
window.sr = ScrollReveal();
sr.reveal('.foo');
sr.reveal('.bar');

Configuration

Practical Example

// Changing the defaults
window.sr = ScrollReveal({ reset: true });

// Customizing a reveal set
sr.reveal('.foo', { duration: 200 });

The Starting Defaults

// 'bottom', 'left', 'top', 'right'
origin: 'bottom',

// Can be any valid CSS distance, e.g. '5rem', '10%', '20vw', etc.
distance: '20px',

// Time in milliseconds.
duration: 500,
delay: 0,

// Starting angles in degrees, will transition from these values to 0 in all axes.
rotate: { x: 0, y: 0, z: 0 },

// Starting opacity value, before transitioning to the computed opacity.
opacity: 0,

// Starting scale value, will transition from this value to 1
scale: 0.9,

// Accepts any valid CSS easing, e.g. 'ease', 'ease-in-out', 'linear', etc.
easing: 'cubic-bezier(0.6, 0.2, 0.1, 1)',

// `<html>` is the default reveal container. You can pass either:
// DOM Node, e.g. document.querySelector('.fooContainer')
// Selector, e.g. '.fooContainer'
container: window.document.documentElement,

// true/false to control reveal animations on mobile.
mobile: true,

// true:  reveals occur every time elements become visible
// false: reveals occur once as elements become visible
reset: false,

// 'always' — delay for all reveal animations
// 'once'   — delay only the first time reveals occur
// 'onload' - delay only for animations triggered by first load
useDelay: 'always',

// Change when an element is considered in the viewport. The default value
// of 0.20 means 20% of an element must be visible for its reveal to occur.
viewFactor: 0.2,

// Pixel values that alter the container boundaries.
// e.g. Set `{ top: 48 }`, if you have a 48px tall fixed toolbar.
// --
// Visual Aid: https://scrollrevealjs.org/assets/viewoffset.png
viewOffset: { top: 0, right: 0, bottom: 0, left: 0 },

// Callbacks that fire for each triggered element reveal, and reset.
beforeReveal: function (domEl) {},
beforeReset: function (domEl) {},

// Callbacks that fire for each completed element reveal, and reset.
afterReveal: function (domEl) {},
afterReset: function (domEl) {}

Advanced

Sequenced Animations

// interval passed to reveal
window.sr = ScrollReveal({ duration: 2000 });
sr.reveal('.box', 50);

// or...

// interval and custom config passed to reveal
window.sr = ScrollReveal();
sr.reveal('.box', { duration: 2000 }, 50);

Working With DOM Nodes

sr.reveal(document.getElementById('foo'));
sr.reveal(document.querySelectorAll('.bar'));

Custom/Multiple Containers

<div id="fooContainer">
  <div class="foo"> Foo 1 </div>
  <div class="foo"> Foo 2 </div>
  <div class="foo"> Foo 3 </div>
</div>

<div id="barContainer">
  <div class="bar"> Bar 1 </div>
  <div class="bar"> Bar 2 </div>
  <div class="bar"> Bar 3 </div>
</div>
window.sr = ScrollReveal();

// as a DOM node...
var fooContainer = document.getElementById('fooContainer');
sr.reveal('.foo', { container: fooContainer });

// as a selector...
sr.reveal('.bar', { container: '#barContainer' });

Asynchronous Content

<!-- index.html -->
<div id="fooContainer">
  <div class="foo">foo</div>
  <div class="foo">foo</div>
  <div class="foo">foo</div>
</div>

<!-- ajax.html -->
<div class="foo">foo async</div>
<div class="foo">foo async</div>
<div class="foo">foo async</div>
var fooContainer, content, sr, xmlhttp;

fooContainer = document.getElementById('fooContainer');

sr = ScrollReveal();
sr.reveal('.foo', { container: fooContainer });

// Setup a new asynchronous request...
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == XMLHttpRequest.DONE) {
    if (xmlhttp.status == 200) {

      // Turn our response into HTML...
      var content = document.createElement('div');
      content.innerHTML = xmlhttp.responseText;
      content = content.childNodes;

      // Add each element to the DOM...
      for (var i = 0; i < content.length; i++) {
        fooContainer.appendChild(content[ i ]);
      };

      // Finally!
      sr.sync();
    }
  }
}

xmlhttp.open('GET', 'ajax.html', true);
xmlhttp.send();

Tips

<!DOCTYPE html>
<html>
  <head>
    <!-- load and instantiate ScrollReveal first -->
    <script src="js/scrollreveal.min.js"></script>
    <script>
      window.sr = ScrollReveal();
    </script>
  </head>
  <body>

    <div class="fooContainer">
      <div class="fooReveal"> Foo </div>
      <div class="fooReveal"> Foo </div>
      <div class="fooReveal"> Foo </div>
    </div>

    <!-- make reveal calls last -->
    <script>
      sr.reveal('.fooReveal', { container: '.fooContainer' });
    </script>

  </body>
</html>

Improve User Experience

<!DOCTYPE html>
<html>
  <head>
    <!-- load and instantiate ScrollReveal first -->
    <script src="js/scrollreveal.min.js"></script>
    <script>
      window.sr = ScrollReveal();

      // Add class to <html> if ScrollReveal is supported
      // Note: this method is deprecated, and only works in version 3
      if (sr.isSupported()) {
        document.documentElement.classList.add('sr');
      }

    </script>

    <style>

      /* Ensure elements load hidden before ScrollReveal runs */
      .sr .fooReveal { visibility: hidden; }

    </style>

  </head>
  <body>

    <div class="fooContainer">
      <div class="fooReveal"> Foo </div>
      <div class="fooReveal"> Foo </div>
      <div class="fooReveal"> Foo </div>
    </div>

    <!-- make reveal calls last -->
    <script>
      sr.reveal('.fooReveal', { container: '.fooContainer' });
    </script>

  </body>
</html>

Add Perspective to 3D Rotation

<!DOCTYPE html>
<html>
  <head>
    <!-- load and instantiate ScrollReveal first -->
    <script src="js/scrollreveal.min.js"></script>
    <script>
      window.sr = ScrollReveal();

      // Add class to <html> if ScrollReveal is supported
      // Note: this method is deprecated, and only works in version 3
      if (sr.isSupported()) {
        document.documentElement.classList.add('sr');
      }

    </script>

    <style>

      /* Ensure elements load hidden before ScrollReveal runs */
      .sr .fooReveal { visibility: hidden; }

      /* add perspective to your container */
      .fooContainer { perspective: 800px; }

    </style>

  </head>
  <body>

    <div class="fooContainer">
      <div class="fooReveal"> Foo </div>
      <div class="fooReveal"> Foo </div>
      <div class="fooReveal"> Foo </div>
    </div>

  <!-- make reveal calls last -->
    <script>
      // use rotation in reveal configuration
      sr.reveal('.fooReveal', { container: '.fooContainer', rotate: {x: 65} });
    </script>

  </body>
</html>

MIT