Tiny mobile-friendly scrollytelling library

Overview

scrollytell

This is a tiny JavaScript library for creating animations that synchronize with scrolling. It uses requestAnimationFrame to check the scroll status and trigger scrollytelling events.

Check out the mobile-friendly examples that can be used as templates.

Before going over the API, let's establish a vocabulary.

chart
An area within the container designated for data visualization that uses sticky or fixed positioning. Typically this is an or and has a low z-order to allow explanatory text to flow over.

Not all scrollytell stories have charts. For example, the visualization area might be external to the container, although this could be hard to manage for small screens.

container
The outermost DOM element of concern for a single scrollytell story. Style must include overflow-y: scroll and position: relative.
developer HUD
Heads-up-display for development purposes. This is an overlay over the container that displays the guideline, active panel index, and progress value. It also draws semitransparent boxes over each panel's bounding box.
fullsize chart
Special configuration where the chart has the same height as the browser window.
guideline
An invisible line stretched horizontally over the middle of the container that does not scroll with its content. As panels cross the guideline they trigger scrollytell events.
panel
One of several block-level DOM elements that form a scrollytelling sequence. Panels trigger scrollytell events as they cross the guideline. The active panel is the panel that currently overlaps the guideline. Long panels may contain segments that vertically divide the panel into multiple pieces, but do not trigger scrollytell events.
progress value
Percentage in [0,1] that represents the vertical position of the active panel relative to the guideline. When the top of the panel aligns with the guideline, the progress value is 0. When the bottom of the panel aligns with the guideline, the progress value is 1.
story
The context for a scrollytell animation. Corresponds to a specific container element.

API

To use scrollytell, create a Story object and pass in a configuration object. The config contains event handlers and querySelector strings. The only two required fields are containerSelector (which should select a single DOM element) and panelSelector (which should select several DOM elements). Here's an example:

<-- disable this in production! enterHandler: (story, panel) => { console.info(`Entered panel ${panel}`); }, exitHandler: (story, panel) => { console.info(`Exited panel ${panel}`); }, progressHandler: (story, progress) => { const percentage = (100 * progress).toFixed(2); console.info(`Progress is now ${percentage}%`); } }); ">
import { Story } from "./scrollytell";

new Story({
    containerSelector: ".container",
    panelSelector: ".panels p",
    developerHud: true, // <-- disable this in production!
    enterHandler: (story, panel) => {
        console.info(`Entered panel ${panel}`);
    },
    exitHandler: (story, panel) => {
        console.info(`Exited panel ${panel}`);
    },
    progressHandler: (story, progress) => {
        const percentage = (100 * progress).toFixed(2);
        console.info(`Progress is now ${percentage}%`);
    }
});

To make a useful story, you'll probably want to do something useful in enterHandler and exitHandler, which are triggered during requestAnimationFrame when a panel crosses in or out of the guideline.

For continuous-style scrollytelling, you can provide a progressHandler which is triggered every time the progress value changes or the active panel changes. Instead of writing your own render loop, you can put your drawing code in the progress handler. This saves power on mobile devices because it only does work when the scroll position changes.

Additionally, the Story object exposes a few methods:

/**
 * Returns the zero-based index of the panel that is currently overlapping
 * the guideline. Returns -1 if no such panel exists.
 */
getActivePanelIndex(): number;

/**
 * Returns a percentage in the range [0, 1] that represents the position of
 * the active panel relative to the guideline. Returns 0 when the top of the
 * panel aligns with the guideline, +1 when the bottom of the panel aligns
 * with the guideline, and -1 if no panel is overlapping the guideline.
 */
getProgressValue(): number;

/**
 * Toggles the heads-up-display for development purposes. Do not enable
 * when your site is in production.
 */
showDeveloperHud(enable: boolean): void;

The above methods provide a way of using the library if you'd like to avoid the event handlers and instead create your own render loop that polls the status of the story.

For more information check out the examples and the TypeScript source.

Fullsize mode

If you want the chart to encompass the background of the container, you can enable fullsizeChart in the config and provide a chartSelector field. This resizes the chart to match the height of the initial window.

In fullsize mode you can also set segmentSelector in the config to select an additional set of elements that get resized to the initial window height. This is useful for creating fixed-sized panels or panel segments. Go to the segmented example to see this in action.

Issues

Because of its focus on mobile platforms, currently the scrollytell library does not gracefully handle situations where the container is resized by the user (e.g. if the container expands to fill a browser window). This may be fixed in the future.

Other resources

For step-by-step storytelling, take a look at AMP Stories. See also Mike Bostock's post How to Scroll.

Disclaimer

This is not an officially supported Google product.

Comments
  • Bump follow-redirects from 1.7.0 to 1.14.7

    Bump follow-redirects from 1.7.0 to 1.14.7

    Bumps follow-redirects from 1.7.0 to 1.14.7.

    Commits
    • 2ede36d Release version 1.14.7 of the npm package.
    • 8b347cb Drop Cookie header across domains.
    • 6f5029a Release version 1.14.6 of the npm package.
    • af706be Ignore null headers.
    • d01ab7a Release version 1.14.5 of the npm package.
    • 40052ea Make compatible with Node 17.
    • 86f7572 Fix: clear internal timer on request abort to avoid leakage
    • 2e1eaf0 Keep Authorization header on subdomain redirects.
    • 2ad9e82 Carry over Host header on relative redirects (#172)
    • 77e2a58 Release version 1.14.4 of the npm package.
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump follow-redirects from 1.14.7 to 1.14.8

    Bump follow-redirects from 1.14.7 to 1.14.8

    Bumps follow-redirects from 1.14.7 to 1.14.8.

    Commits
    • 3d81dc3 Release version 1.14.8 of the npm package.
    • 62e546a Drop confidential headers across schemes.
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump path-parse from 1.0.6 to 1.0.7

    Bump path-parse from 1.0.6 to 1.0.7

    Bumps path-parse from 1.0.6 to 1.0.7.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump http-proxy from 1.17.0 to 1.18.1

    Bump http-proxy from 1.17.0 to 1.18.1

    Bumps http-proxy from 1.17.0 to 1.18.1.

    Changelog

    Sourced from http-proxy's changelog.

    v1.18.1 - 2020-05-17

    Merged

    1.18.0 - 2019-09-18

    Merged

    Commits

    • [dist] New test fixtures. 7e4a0e5
    • [dist] End of an era. a9b09cc
    • [dist] Version bump. 1.18.0 9bbe486
    • [fix] Latest versions. 59c4403
    • [fix test] Update tests. dd1d08b
    • [dist] Update dependency ws to v3 [SECURITY] b00911c
    • [dist] .gitattributes all the things. fc93520
    • [dist] Regenerate package-lock.json. 16d4f8a
    Commits
    • 9b96cd7 1.18.1
    • 335aeeb Skip sending the proxyReq event when the expect header is present (#1447)
    • dba3966 Remove node6 support, add node12 to build (#1397)
    • 9bbe486 [dist] Version bump. 1.18.0
    • 6e4bef4 Added in auto-changelog module set to keepachangelog format (#1373)
    • d056241 fix 'Modify Response' readme section to avoid unnecessary array copying (#1300)
    • 244303b Fix incorrect target name for reverse proxy example (#1135)
    • b4028ba Fix modify response middleware example (#1139)
    • 77a9815 [dist] Update dependency async to v3 (#1359)
    • c662f9e Fix path to local http-proxy in examples. (#1072)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • [Suggestion] Implementing auto-zoom

    [Suggestion] Implementing auto-zoom

    Assuming that we are making a scrolling system that is intuitive and better that also allows for anchors lets also try and implement autozoom with a lasso or single gesture for large documents? as shown here. https://www-ui.is.s.u-tokyo.ac.jp/~takeo/research/autozoom/autozoom.htm

    The idea is old but I think needs more recognition in the age of skimming might end up being a good idea don't you think?

    especially when people are scrolling faster through posts and only need to see the titles or images in broader contexts.

    opened by jaibeer72 0
Owner
Google
Google ❤️ Open Source
Google
Adopt a friendly pet or item

android_register Registering users on Android Getting Started $ flutter clean $ flutter upgrade $ flutter pub get $ flutter run App on pre registratio

Srinjoy Chakravarty 3 Apr 28, 2021
Your friendly neighborhood application.

Welcome to Aas Pass ?? Inspiration Time and again we have observed an on-the-spot need for borrowing daily devices, enquiring about essential services

Satwik Dudeja 3 May 30, 2021
A beginner friendly flutter app displaying the time across various cities in the world.

World Time App in FLUTTER My first kinda big Flutter project. It is a revision of all basics and some advanced concepts of Flutter I've learnt so far.

Rohini Rao 5 Nov 11, 2022
The official sdk for the user-friendly API of Mega services on the Dart language.

megasdkdart The official sdk for the user-friendly API of Mega services in the Dart language. Example: import 'package:megasdkdart/megasdkdart.dart';

meg4cyberc4t 4 Mar 30, 2022
Tooling and libraries for processing dart test output into dev-friendly formats

better_test_reporter Introduction This is an application/library heavily inspired by dart-junitreport and dart-testreport. It takes what was done in t

Betterment 6 Sep 14, 2022
Friendly-Chat - Simple text messaging app coded in Dart using the Flutter framework

Friendly Chat A mobile application coded in the Dart programming language using

Vladislav Kostic 3 May 15, 2022
A mobile image uploader in which you can upload image to your personal gallery from either your camera or mobile gallery and it can detect your current geographic location and address using firebase firestore and storage.

Image Uploader In Flutter About It is an Image Uploader gallery which tracks your address from which you're uploading using Flutter and Image picker.

Prahen parija 6 Dec 20, 2022
Flutter library to create beautiful surveys (aligned with ResearchKit on iOS)

SurveyKit: Create beautiful surveys with Flutter (inspired by iOS ResearchKit Surveys)

QuickBird Studios 90 Dec 28, 2022
A type-safe command-line parsing library for Dart

plade Plade is a type-safe CLI parsing library for Dart. Highlights Fully type-safe and null-safe. Support for a variety of different parsing styles (

Ryan Gonzalez 6 Jan 1, 2022
Agent library for Internet Computer, in Dart

agent_dart An agent library built for Internet Computer, a plugin package for dart and flutter apps. Developers can build ones to interact with Dfinit

null 87 Dec 31, 2022
ThingsBoard PE API client library for Dart developers.

ThingsBoard PE API client library for Dart developers. It's compatible with TB PE 3.3.0. Usage A simple usage example: import 'package:thingsboard_pe_

ThingsBoard - Open-source IoT Platform 45 Sep 28, 2022
A Dart library for creating a Dart object to represent directory trees.

Directory Tree A Dart library for creating a Dart object to represent directory trees. Getting Started Import and initialize package import 'package:d

Chiziaruhoma Ogbonda 5 Dec 1, 2021
Complete Flutter OpenIdConnect Library

OpenIdConnect for Flutter Standards compliant OpenIdConnect library for flutter that supports: Code flow with PKCE (the evolution of implicit flow). T

null 50 Dec 24, 2022
🎞 Flutter media playback, broadcast & recording library for Windows, Linux & macOS. Written in C++ using libVLC & libVLC++. (Both audio & video)

dart_vlc Flutter media playback, broadcast, recording & chromecast library for Windows, Linux & macOS. Written in C++ using libVLC & libVLC++. Install

Hitesh Kumar Saini 417 Dec 29, 2022
Flutter example project to run Solidity smart contracts using web3Dart library

Fluthereum Description Flutter example project to run Solidity smart contracts using web3Dart library Dependencies web3dart: A dart library that conne

Marcos Carlomagno 72 Dec 27, 2022
more code then the original with cupertino library

this version only update flutter cupertino library for crud purpose with backend api this is not stable version yet both side. Youtube for flutter cup

nobody but me 1 Aug 21, 2022
Demo library index written in Flutter

demo_books A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if th

Nemanja Stošić 1 Sep 20, 2022
A playground for me to learn the Riverpod state management library in Flutter.

clothes_shop A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if

Benhenneda Majid 2 Oct 25, 2021
building a timer application using the bloc library

flutter_timer A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if

Simon Wambua 0 Nov 4, 2021