JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 95
  • Score
    100M100P100Q80010F
  • License MIT

๐Ÿ›น Elegant motion scrolling for React

Package Exports

  • scroller-motion
  • scroller-motion/dist/index.js
  • scroller-motion/dist/index.modern.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (scroller-motion) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

๐Ÿ›น
scroller-motion

NPM Package Version Project Storybook Tests Workflow Status Formatting Workflow Status

Bringing motion scrolling to React, built upon framer-motion


  1. Installation
  2. Usage
  3. Props
  4. useScrollerMotion
  5. Listeners
  6. Recipes
  7. About
  8. Contributing
  9. License

Installation

To begin you'll want to install scroller-motion as well as the peer dependencies:

npm install scroller-motion framer-motion react

# or

yarn add scroller-motion framer-motion react

Note: Due to the use of hooks the minimum required version of React is 16.8

Usage

Implementing scroller-motion couldn't be easier, simply wrap your page with the <ScrollerMotion> component. For example in a Next.js app this might look like the following:

/* pages/index.jsx */

import { ScrollerMotion } from 'scroller-motion'

export default () => (
  <ScrollerMotion>
    <MyComponent />
  </ScrollerMotion>
)

Most modern browsers implement an inertia bounce effect to the window while scrolling (upon reaching the start/end). This can cause unwanted visual effects, such as flickering, when using scroller-motion.

To fix this, you can disable overscroll-behavior in your project with the following CSS:

/* style.css */

html,
body {
  overscroll-behavior: none;
}

Props

All props are optional.

disabled

type: boolean
default: false

Completly disables and unmounts the ScrollerMotion component. Any children will be rendered through a React <Fragment> in this case (thus falling back to native scrolling).

scale

type: number
default: 1

View demo

Extends the scrollable length of the page, giving a "slow scroll" experience. For example if the page content is 1400px in height, <ScrollerMotion scale={1.5} /> would result in a scrollable length of 2100px (height * scale).

The lowest this value can be is 1, anything lower will be disregarded and 1 will be used in its place.

spring

type: SpringOptions
default: { mass: 1.25, stiffness: 200, damping: 50 }

View demo

The main configuration object for the scroll's spring transform, basically the 2nd parameter to framer-motion's useSpring.

You can disable the spring scroll by passing a falsy value to this prop, for example: <ScollerMotion spring={null} />.

useScrollerMotion hook

View demo

This hook allows you to consume the internal MotionValue values, returning an object of the following type:

{ scrollX: MotionValue, scrollY: MotionValue, x: MotionValue, y: MotionValue }
  • scrollX & scrollY: The current (spring) scroll position.
  • x & y: The current transform (useful for calculating scroll position when scale is in-use).

It must be used within a <ScrollerMotion />, to read the values in the parent component see Motion Listeners.

import { ScrollerMotion, useScrollerMotion } from 'scroller-motion'
import { motion } from 'framer-motion'

const MyComponent = () => {
  const { x, y } = useScrollerMotion()

  return <motion.div style={{ x, y }}>Hello world</motion.div>
}

export default () => (
  <ScrollerMotion>
    <MyComponent />
  </ScrollerMotion>
)

Motion Listeners

View demo

Another approach if you need to read/use the internal MotionValue values is via the ref prop on <ScrollerMotion />. The type of the ref is the same as the object returned from useScrollerMotion.

For example, if we want to use the y-axis scroll position:

import React, { useEffect, useRef } from 'react'
import { useMotionValue } from 'framer-motion'
import { ScrollerMotion, ScrollerMotionRef } from 'scroller-motion'

export default () => {
  const scrollerMotion = useRef<ScrollerMotionRef>()
  const scrollY = useMotionValue(0)

  useEffect(() => {
    const unsubscribe = scrollerMotion.current.scrollY.onChange((v) =>
      scrollY.set(v)
    )

    return () => unsubscribe()
  }, [scrollY])

  return (
    <ScrollerMotion ref={scrollerMotion}>
      <MyComponent scrollPosition={scrollY} />
    </ScrollerMotion>
  )
}

For accessing the native scroll value (without any spring motion) we suggest using framer-motion's useViewportScroll.

Recipes

  • Scroll to hash: Custom hook for handling scrolling to an element via a #hash anchor.

About

Scroller-motion was born from the need for motion/smooth scrolling in a couple of React projects. Given the fact that we were already using the beloved framer-motion for the rest of the animations & transitions, we decided to try it out for page scrolling too - and the results were impressive! Time for an emoji list:

  • ๐Ÿ€ Configurable motion via the spring prop
  • ๐ŸŒ "Slow scroll" via the scale prop
  • ๐Ÿ‘‚ Subscribe to the scroll values with useScrollerMotion
  • โš™๏ธ SSR compatible
  • ๐Ÿค– Fully typed w/ TypeScript
  • ๐ŸŽฃ Built around React hooks
  • โš–๏ธ Only 2.2kb gzipped

It's still considered a beta release, with a public roadmap for the stable v1 available here.

Note: Currently scroller-motion only supports motion scrolling on the main window/body. The stable release should allow for motion scrolling on any DOM element.

Contributing

These are the current scripts available for development:

# Start Storybook
npm run start

# Build dist files
npm run build

# Build static Storybook
npm run build:storybook

# Apply Prettier formatting
npm run prettier:format

# Check Prettier formatting
npm run prettier:check

# Run tests
npm run test

License

Released under the MIT License.
Authored and maintained by Wombak with help from contributors.

wombak.xyz ยท GitHub @wombak ยท Twitter @wombak_xyz