React Scrollama
Simple scrollytelling with the IntersectionObserver in React.
README
React Scrollama
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:
- ```
- $ npm install react-scrollama
- ```
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).
- ``` js
- <Scrollama onStepEnter={callback} offset={0.5}>
- <Step data={1}>
- <div>...</div>
- </Step>
- <Step data={2}>
- <div>...</div>
- </Step>
- </Scrollama>
- ```
A basic example:
- ``` js
- import React, { useState } from 'react';
- import { Scrollama, Step } from 'react-scrollama';
- const ScrollamaDemo = () => {
- const [currentStepIndex, setCurrentStepIndex] = useState(null);
- // This callback fires when a Step hits the offset threshold. It receives the
- // data prop of the step, which in this demo stores the index of the step.
- const onStepEnter = ({ data }) => {
- setCurrentStepIndex(data);
- };
- return (
- <div style={{ margin: '50vh 0', border: '2px dashed skyblue' }}>
- <div style={{ position: 'sticky', top: 0, border: '1px solid orchid' }}>
- I'm sticky. The current triggered step index is: {currentStepIndex}
- </div>
- <Scrollama offset={0.5} onStepEnter={onStepEnter} debug>
- {[1, 2, 3, 4].map((_, stepIndex) => (
- <Step data={stepIndex} key={stepIndex}>
- <div
- style={{
- margin: '50vh 0',
- border: '1px solid gray',
- opacity: currentStepIndex === stepIndex ? 1 : 0.2,
- }}
- >
- I'm a Scrollama Step of index {stepIndex}
- </div>
- </Step>
- ))}
- </Scrollama>
- </div>
- );
- };
- export default ScrollamaDemo;
- ```
API
` elements would show up in the DOM.
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 `
Scrollama
These are the props you can set on the Scrollama component itself:
Prop | Type | Default | Description |
---|---|---|---|
|----------------|---------------------------|---------|-----------------------------------------------------------------------------------------| | |||
offset | `number` | 0.3 | How |
threshold | `number` | 4 | Granularity |
onStepEnter | `function` | | | |
onStepExit | `function` | | | |
onStepProgress | `function` | | | |
debug | `boolean` | false | Whether |
The onStepEnter and onStepExit callbacks receive one argument, an object, with the following properties:
- ``` js
- {
- element, // The DOM node of the step that was triggered
- data, // The data supplied to the step
- direction, // 'up' or 'down'
- entry, // the original `IntersectionObserver` entry
- }
- ```
The onStepProgress callback receives one argument, an object, with the following properties:
- ``` js
- {
- element, // The DOM node of the step that was triggered
- data, // The data supplied to the step
- progress, // The percent of completion of the step (0 to 1)
- direction, // 'up' or 'down'
- entry, // the original `IntersectionObserver` entry
- }
- ```
To create a fixed graphic with text scrolling beside/over it, use position: sticky;. How to use position sticky.
Step
`.
These are the props you can set on the Step component:
Prop | Type | Default | Description |
---|---|---|---|
|------|------|---------|------------------------------------------------------------------| | |||
data | any | | |
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.