React Scrollama

Simple scrollytelling with the IntersectionObserver in React.

README

React Scrollama


npm version


React Scrollama is a simple library for scrollytelling in React, utilizing the IntersectionObserver. It's adapted from Russel Samora's Scrollama.

Some examples:

17 interactive visualization
stories
using React Scrollama
    for scrollytelling

Comment Tati a imprimé
sa marque à Barbès

by Fabien Casaleggio

The scramble to secure
America’s voting machines

by Beatrice Jin

Sex Diversity Among Grad
Students is Stagnating

by Jason Kao

Demo


A live demo lives here, presented at ReactNYC.

Basic step triggers Sticky graphic on the side

Install


React Scrollama can be installed as an npm package:
  1. ```
  2. $ npm install react-scrollama
  3. ```

Note: Version 2.2.0 removed the IntersectionObserver polyfill from the build. If you want cross-browser support, you should include it yourself.

Usage


A Scrollama component wraps a set of steps. Each Step component must wrap a DOM element (i.e. not just text).

  1. ``` js
  2. <Scrollama onStepEnter={callback} offset={0.5}>
  3.   <Step data={1}>
  4.     <div>...</div>
  5.   </Step>
  6.   <Step data={2}>
  7.     <div>...</div>
  8.   </Step>
  9. </Scrollama>
  10. ```

`` provides an interface for listening in on scroll triggers like entering or exiting a step. (Here's [a full list](#scrollama) of available props.)

A basic example:

  1. ``` js
  2. import React, { useState } from 'react';
  3. import { Scrollama, Step } from 'react-scrollama';

  4. const ScrollamaDemo = () => {
  5.   const [currentStepIndex, setCurrentStepIndex] = useState(null);

  6.   // This callback fires when a Step hits the offset threshold. It receives the
  7.   // data prop of the step, which in this demo stores the index of the step.
  8.   const onStepEnter = ({ data }) => {
  9.     setCurrentStepIndex(data);
  10.   };

  11.   return (
  12.     <div style={{ margin: '50vh 0', border: '2px dashed skyblue' }}>
  13.       <div style={{ position: 'sticky', top: 0, border: '1px solid orchid' }}>
  14.         I'm sticky. The current triggered step index is: {currentStepIndex}
  15.       </div>
  16.       <Scrollama offset={0.5} onStepEnter={onStepEnter} debug>
  17.         {[1, 2, 3, 4].map((_, stepIndex) => (
  18.           <Step data={stepIndex} key={stepIndex}>
  19.             <div
  20.               style={{
  21.                 margin: '50vh 0',
  22.                 border: '1px solid gray',
  23.                 opacity: currentStepIndex === stepIndex ? 1 : 0.2,
  24.               }}
  25.             >
  26.               I'm a Scrollama Step of index {stepIndex}
  27.             </div>
  28.           </Step>
  29.         ))}
  30.       </Scrollama>
  31.     </div>
  32.   );
  33. };

  34. export default ScrollamaDemo;
  35. ```

API


React Scrollama components do not render into the DOM. They are meant to set up Intersection Observers on the elements inside the `` components. In the code above, only the `
` elements would show up in the DOM.

Scrollama


These are the props you can set on the Scrollama component itself:

PropTypeDefaultDescription
|----------------|---------------------------|---------|-----------------------------------------------------------------------------------------|
offset`number`0.3How
threshold`number`4Granularity
onStepEnter`function`|
onStepExit`function`|
onStepProgress`function`|
debug`boolean`falseWhether

The onStepEnter and onStepExit callbacks receive one argument, an object, with the following properties:

  1. ``` js
  2. {
  3.   element, // The DOM node of the step that was triggered
  4.   data, // The data supplied to the step
  5.   direction, // 'up' or 'down'
  6.   entry, // the original `IntersectionObserver` entry
  7. }
  8. ```

The onStepProgress callback receives one argument, an object, with the following properties:

  1. ``` js
  2. {
  3.   element, // The DOM node of the step that was triggered
  4.   data, // The data supplied to the step
  5.   progress, // The percent of completion of the step (0 to 1)
  6.   direction, // 'up' or 'down'
  7.   entry, // the original `IntersectionObserver` entry
  8. }
  9. ```

To create a fixed graphic with text scrolling beside/over it, use position: sticky;. How to use position sticky.

Step


A `Step` element can contain one child, which must be a DOM element. To use a React component as the child node, it [must be wrapped with a DOM element](https://github.com/jsonkao/react-scrollama/issues/19#issuecomment-624861326) like `
`.

These are the props you can set on the Step component:

PropTypeDefaultDescription
|------|------|---------|------------------------------------------------------------------|
dataany|

You will also probably want to set a key prop on each Step if you're transforming an array of data into a list of Step elements (see Lists and Keys).

Thank you to everyone who made this possible!



Features roadmap


Currently, there is no way to throttle/customize React Scrollama's resize listener 😢. We're working on this in #44.
Fire previous step triggers if they were jumped

Lmk if you need these features ASAP.