npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

scroller-motion

v1.2.3

Published

🛹 Elegant motion scrolling for React

Downloads

882

Readme


  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 | | Description | 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 | | Demo | View demo | | Description | 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 } | | Demo | View demo | | Description | 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,
  scrollXProgress: MotionValue,
  scrollY: MotionValue,
  scrollYProgress: MotionValue,
  x: MotionValue,
  y: MotionValue
}
  • scrollX & scrollY: The current scroll position.
  • scrollXProgress & scrollYProgress: A 0 to 1 transform of scrollX|scrollY, similar to those returned by useScroll.
  • x & y: A negative representation of scrollX|scrollY.

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

ℹ️ For accessing native scroll values (without spring motion or scale calculation) we suggest using framer-motion's useScroll.

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 { 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 native scroll values (without spring motion or scale calculation) we suggest using framer-motion's useScroll.

Recipes

  • Hash anchor scroll: Scroll the window to a DOM element when clicking a #hash anchor.
  • Horizontal scroll: Convert vertical mousewheel events to horizontal window scroll.
  • Tab scroll: Scroll the window to a DOM element when pressing the Tab key (useful for a11y purposes).

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 ~2kb gzipped

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 Brad Adams with help from contributors.

breadadams.com · GitHub @breadadams · Twitter @breadadams