Skip to content

An ambitious light-weight react module written in TypeScript for tracking scroll progress in a performant way. Developed for use with spring based animation libraries such as react-spring, but can be used with or without any library.

Notifications You must be signed in to change notification settings

olarsson/react-scrollsy

Repository files navigation

react-scrollsy v1.1

An ambitious light-weight react module written in TypeScript for tracking scroll progress in a performant way. Developed for use with spring based animation libraries such as react-spring, but can be used with or without any library.

Live demo / Code examples

Live demo: https://olarsson.github.io/react-scrollsy-examples/

Code examples: https://github.com/olarsson/react-scrollsy-examples/tree/master/src

Installation

npm i react-scrollsy

Usage

Here is a very basic example that tracks the scroll progress of the document.

import { ScrollTrackerDocument, ScrollTracker } from "react-scrollsy";

import { IScrollData, IScrollObject } from "react-scrollsy/dist/types";

import { useRef } from "react";

function App() {
  const refPageProgress = useRef(null);

  return (
    <ScrollTrackerDocument scrollThrottle={33}> // 1000 ms/30 fps = 33ms, limits the triggered events to 30 fps, optional
      {({ scrollData }: IScrollData) => {
        return (
          <ScrollTracker
            scrollData={scrollData}
            elem={refPageProgress}
            settings={{
              duration: {
                distance: 100,
                unit: "%",
                basedOn: "doc",
              },
            }}>
            {({ scrollObject }: IScrollObject) => {
              return <h1 ref={refPageProgress}>Here is the scroll progress: {scrollObject.progress}</h1>;
            }}
          </ScrollTracker>
        );
      }}
    </ScrollTrackerDocument>
  );
}

export default App;

Components

<ScrollTrackerDocument />

Sets the document as the main scrolling container. This or ScrollTrackerCustom must always be the parent of a ScrollTracker component.

Configuration and properties:

  • scrollThrottle - (number) throttles the recalculations in ms to this value when the document is scrolled.
  • resizeThrottle - (number) throttles the recalculations in ms to this value when the document is resized.

Creates a function which returns a scrollData object as such:

  • scrollData - (object, immutable) data returned from the component.
    • scrollTop - (number, px) the scroll position from the top.
    • containerHeight - (number, px) height of the container.
    • element - (number, px) the tracked element for scrolling (document).
    • percentProgress - (number, %) scroll progress in percent expressed as a number between 0 to 1.
    • scrollHeight - (number, px) the total scrollable height of the document.
<ScrollTrackerDocument>
  {({ scrollData }: IScrollData) => {
    return (
      // ScrollTracker components and other components can go inside here
    );
  }}
</ScrollTrackerDocument>

<ScrollTrackerCustom />

Sets a custom element as the main scrolling container. This or ScrollTrackerDocument must always be the parent of a ScrollTracker component.

Configuration and properties:

  • scrollThrottle - (number) throttles the recalculations to this value in ms when the element is scrolled.
  • resizeThrottle - (number) throttles the recalculations to this value in ms when the element is resized.
  • scrollingElement - (string, required) the selector for the main scrollable element to track scroll progress of.

Creates a function which returns a scrollData object as such:

  • scrollData - (object, immutable) data returned from the component.
    • scrollTop - (number, px) the scroll position from the top.
    • containerHeight - (number, px) height of the container.
    • element - (number, px) the tracked element for scrolling (custom element).
    • percentProgress - (number, %) scroll progress in percent expressed as a number between 0 to 1.
    • scrollHeight - (number, px) the total scrollable height of the document.
<ScrollTrackerCustom
  key={active.toString()} // forces a rerender of the tracker, use this if you for example hide the element with 'display: none'
  scrollingElement='#custom-scroll-container'>
  {({ scrollData }: IScrollData) => {
    return (
      // ScrollTracker components and other components can go inside here
    );
  }}
</ScrollTrackerCustom>

<ScrollTracker />

A specific DOM element and its progress based on its duration and offsets will be managed by this component.

Configuration and properties:

  • elem - (ref, required) sets the element reference to use when tracking scroll progress.
  • settings - (object, required)
    • duration - (object, required)
      • distance - (number, required) how long of the tracked elements duration calculations should be active for.
      • unit - (['px' | '%'], required) unit the distance should be measured in.
      • basedOn - (['doc' | 'elem' | 'vp'], required) the duration will be calculated based on distance + unit and what you chose here. 'doc' is the document, 'elem' is the element, 'vp' is the viewport height.
    • offsetTop - (object, optional)
      • ... - same props as the duration.
    • offsetBottom - (object, optional)
      • ... - same props as the duration.
  • onStart - (function, optional) callback to run when scroll progress begins.
  • onEnd - (function, optional) callback to run when scroll progress ends.

Creates a function which returns a scrollObject object as such:

  • scrollObject (object, immutable) - data returned from the component.
    • scrollData - (object, immutable) inherited from the main component.
    • progress - (number, %) scroll progress in percent expressed as a number between 0 to 1.
    • start - (number, px) the start position in pixels when scroll progress calculation should begin.
    • end - (number, px) the end position in pixels when scroll progress calculation should end.
<ScrollTracker
  scrollData={scrollData} // the scrollData object returned by either ScrollTrackerDocument or ScrollTrackerCustom
  elem={refElem}
  settings={{
    duration: {
      distance: 100,
      unit: "%",
      basedOn: "elem",
    },
    offsetTop: {
      distance: 25,
      unit: "%",
      basedOn: "vp",
    },
    offsetBottom: {
      distance: -200,
      unit: "px",
      basedOn: "", // when using px this can be left empty
    },
  }}>
  {({ scrollObject }: IScrollObject) => {
    return (
      // return for example the scrollObject.progress to reflect progress, and any other elements/components that you wish
    )
  }}
</ScrollTracker>

Whats new

Version 1.1
  • You can now throttle the scrolling events
  • resizeThrottle is no longer required
Version 1.0
  • Initial release

Todo

  • Write (more) tests
  • Refactor the ScrollTrackerCustom?

About

An ambitious light-weight react module written in TypeScript for tracking scroll progress in a performant way. Developed for use with spring based animation libraries such as react-spring, but can be used with or without any library.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published