Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
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
- Host: GitHub
- URL: https://github.com/breadadams/scroller-motion
- Owner: breadadams
- License: mit
- Created: 2020-04-29T19:37:28.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-07-31T10:01:20.000Z (3 months ago)
- Last Synced: 2024-09-29T00:26:09.901Z (about 1 month ago)
- Topics: framer-motion, motion, react, scroll, smooth-scroll
- Language: TypeScript
- Homepage: https://scroller-motion.js.org
- Size: 6.06 MB
- Stars: 67
- Watchers: 4
- Forks: 5
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
๐น
scroller-motionBringing 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)