Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/breadadams/scroller-motion

๐Ÿ›น Elegant motion scrolling for React
https://github.com/breadadams/scroller-motion

framer-motion motion react scroll smooth-scroll

Last synced: 28 days ago
JSON representation

๐Ÿ›น Elegant motion scrolling for React

Awesome Lists containing this project

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](#installation)
1. [Usage](#usage)
1. [Props](#props)
1. [useScrollerMotion](#usescrollermotion-hook)
1. [Listeners](#motion-listeners)
1. [Recipes](#recipes)
1. [About](#about)
1. [Contributing](#contributing)
1. [License](#license)

---

### Installation

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

```bash
npm install scroller-motion framer-motion react

# or

yarn add scroller-motion framer-motion react
```

> Note: Due to the use of [hooks](https://reactjs.org/docs/hooks-intro.html) the minimum required version of React is 16.8

### Usage

Implementing **scroller-motion** couldn't be easier, simply wrap your page with the `` component. For example in a [Next.js](https://nextjs.org/) app this might look like the following:

```jsx
/* pages/index.jsx */

import { ScrollerMotion } from 'scroller-motion'

export default () => (



)
```

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](https://github.com/breadadams/scroller-motion/issues/7), when using **scroller-motion**.

To fix this, you can disable [`overscroll-behavior`](https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior) in your project with the following CSS:

```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 `` in this case (thus falling back to native scrolling). |

#### `scale`

| | |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Type** | `number` |
| **Default** | `1` |
| **Demo** | [**View demo**](https://scroller-motion.js.org/?path=/story/scrollermotion--custom-scale) |
| **Description** | Extends the scrollable length of the page, giving a "slow scroll" experience. For example if the page content is **1400px** in height, `` 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`](https://github.com/framer/motion/blob/2fa59a6e7c0a83647c8193ad37667a4f018143e2/packages/framer-motion/src/animation/types.ts#L31) |
| **Default** | `{ mass: 1.25, stiffness: 200, damping: 50 }` |
| **Demo** | [**View demo**](https://scroller-motion.js.org/?path=/story/scrollermotion--custom-spring) |
| **Description** | The main configuration object for the scroll's spring transform, basically the 2nd parameter to framer-motion's [useSpring](https://www.framer.com/docs/use-spring/).

You can disable the spring scroll by passing a falsy value to this prop, for example: ``. |

### `useScrollerMotion` hook

[**View demo**](https://scroller-motion.js.org/?path=/story/scrollermotion--use-scroller-motion)

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

```ts
{
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`](https://www.framer.com/docs/use-scroll/#usage).
- `x` & `y`: A negative representation of `scrollX|scrollY`.

It must be used within a ``, to read the values in the parent component see [Motion Listeners](#motion-listeners).

> โ„น๏ธ For accessing _native_ scroll values (without spring motion or scale calculation) we suggest using framer-motion's [`useScroll`](https://www.framer.com/docs/use-scroll).

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

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

return Hello world
}

export default () => (



)
```

### Motion Listeners

[**View demo**](https://scroller-motion.js.org/?path=/story/scrollermotion--motion-listeners)

Another approach if you need to read/use the internal `MotionValue` values is via the `ref` prop on ``. The type of the ref is the same as the object returned from [`useScrollerMotion`](#usescrollermotion-hook).

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

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

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

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

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

return (



)
}
```

> โ„น๏ธ For accessing _native_ scroll values (without spring motion or scale calculation) we suggest using framer-motion's [`useScroll`](https://www.framer.com/docs/use-scroll).

### Recipes

- [**Hash anchor scroll**](https://github.com/breadadams/scroller-motion/issues/3#issuecomment-817216563): Scroll the window to a DOM element when clicking a `#hash` anchor.
- [**Horizontal scroll**](https://github.com/breadadams/scroller-motion/issues/24#issuecomment-1105743496): Convert vertical mousewheel events to horizontal window scroll.
- [**Tab scroll**](https://github.com/breadadams/scroller-motion/issues/22#issuecomment-1119969437): 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`](https://github.com/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:

```bash
# 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](https://github.com/breadadams/scroller-motion/blob/master/LICENSE) License.

Authored and maintained by Brad Adams with help from [contributors](https://github.com/breadadams/scroller-motion/contributors).

> [breadadams.com](https://breadadams.com) ยท GitHub [@breadadams](https://github.com/breadadams) ยท Twitter [@breadadams](https://twitter.com/breadadams)