1.2.3 • Published 1 year ago

scroller-motion v1.2.3

Weekly downloads
4
License
MIT
Repository
github
Last release
1 year ago

  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

Typeboolean
Defaultfalse
DescriptionCompletly 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

Typenumber
Default1
DemoView demo
DescriptionExtends 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

TypeSpringOptions
Default{ mass: 1.25, stiffness: 200, damping: 50 }
DemoView demo
DescriptionThe 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

1.2.3

1 year ago

1.2.2

1 year ago

1.2.1

1 year ago

1.2.0

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago

1.0.0

2 years ago

0.0.1

3 years ago

0.0.2

3 years ago

0.0.1-beta.3

4 years ago

0.0.1-beta.2

4 years ago

0.0.1-beta.1

4 years ago

0.0.1-beta.0

4 years ago