{"id":14961216,"url":"https://github.com/breadadams/scroller-motion","last_synced_at":"2025-08-24T21:18:55.979Z","repository":{"id":40462484,"uuid":"260024810","full_name":"breadadams/scroller-motion","owner":"breadadams","description":"🛹 Elegant motion scrolling for React","archived":false,"fork":false,"pushed_at":"2024-07-31T10:01:20.000Z","size":6352,"stargazers_count":70,"open_issues_count":7,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-24T06:45:26.241Z","etag":null,"topics":["framer-motion","motion","react","scroll","smooth-scroll"],"latest_commit_sha":null,"homepage":"https://scroller-motion.js.org","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/breadadams.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-29T19:37:28.000Z","updated_at":"2025-03-10T21:57:51.000Z","dependencies_parsed_at":"2024-12-22T09:18:53.639Z","dependency_job_id":"c47513cd-f158-4795-8013-5fa039613015","html_url":"https://github.com/breadadams/scroller-motion","commit_stats":{"total_commits":112,"total_committers":3,"mean_commits":"37.333333333333336","dds":0.0535714285714286,"last_synced_commit":"b6378d89af5033a6bc9bdbba264fc2cdc5cece66"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breadadams%2Fscroller-motion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breadadams%2Fscroller-motion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breadadams%2Fscroller-motion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breadadams%2Fscroller-motion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/breadadams","download_url":"https://codeload.github.com/breadadams/scroller-motion/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161804,"owners_count":21057655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["framer-motion","motion","react","scroll","smooth-scroll"],"created_at":"2024-09-24T13:24:12.802Z","updated_at":"2025-04-10T05:24:27.944Z","avatar_url":"https://github.com/breadadams.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch2 align=\"center\"\u003e🛹 \u003cbr /\u003escroller-motion\u003c/h2\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/scroller-motion\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/scroller-motion?style=flat-square\" alt=\"NPM Package Version\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://scroller-motion.js.org/\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/storybooks/brand/master/badge/badge-storybook.svg\" alt=\"Project Storybook\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/breadadams/scroller-motion/actions/workflows/formatting.yml\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://github.com/breadadams/scroller-motion/actions/workflows/tests.yml/badge.svg\" alt=\"Tests Workflow Status\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/breadadams/scroller-motion/actions/workflows/formatting.yml\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://github.com/breadadams/scroller-motion/actions/workflows/formatting.yml/badge.svg\" alt=\"Formatting Workflow Status\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003ch4 align=\"center\"\u003eBringing motion scrolling to React, built upon \u003ca href=\"https://github.com/framer/motion\" target=\"_blank\"\u003eframer-motion\u003c/a\u003e\u003c/h4\u003e\n\n---\n\n1. [Installation](#installation)\n1. [Usage](#usage)\n1. [Props](#props)\n1. [useScrollerMotion](#usescrollermotion-hook)\n1. [Listeners](#motion-listeners)\n1. [Recipes](#recipes)\n1. [About](#about)\n1. [Contributing](#contributing)\n1. [License](#license)\n\n---\n\n### Installation\n\nTo begin you'll want to install **scroller-motion** as well as the peer dependencies:\n\n```bash\nnpm install scroller-motion framer-motion react\n\n# or\n\nyarn add scroller-motion framer-motion react\n```\n\n\u003e Note: Due to the use of [hooks](https://reactjs.org/docs/hooks-intro.html) the minimum required version of React is 16.8\n\n### Usage\n\nImplementing **scroller-motion** couldn't be easier, simply wrap your page with the `\u003cScrollerMotion\u003e` component. For example in a [Next.js](https://nextjs.org/) app this might look like the following:\n\n```jsx\n/* pages/index.jsx */\n\nimport { ScrollerMotion } from 'scroller-motion'\n\nexport default () =\u003e (\n  \u003cScrollerMotion\u003e\n    \u003cMyComponent /\u003e\n  \u003c/ScrollerMotion\u003e\n)\n```\n\nMost 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**.\n\nTo 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:\n\n```css\n/* style.css */\n\nhtml,\nbody {\n  overscroll-behavior: none;\n}\n```\n\n### Props\n\nAll props are optional.\n\n#### `disabled`\n\n|                 |                                                                                                                                                                                  |\n| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Type**        | `boolean`                                                                                                                                                                        |\n| **Default**     | `false`                                                                                                                                                                          |\n| **Description** | Completly disables and unmounts the `ScrollerMotion` component. Any children will be rendered through a React `\u003cFragment\u003e` in this case (thus falling back to native scrolling). |\n\n#### `scale`\n\n|                 |                                                                                                                                                                                                                                                                                                                                                                    |\n| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| **Type**        | `number`                                                                                                                                                                                                                                                                                                                                                           |\n| **Default**     | `1`                                                                                                                                                                                                                                                                                                                                                                |\n| **Demo**        | [**View demo**](https://scroller-motion.js.org/?path=/story/scrollermotion--custom-scale)                                                                                                                                                                                                                                                                          |\n| **Description** | Extends the scrollable length of the page, giving a \"slow scroll\" experience. For example if the page content is **1400px** in height, `\u003cScrollerMotion scale={1.5} /\u003e` would result in a scrollable length of **2100px** (`height * scale`).\u003cbr/\u003e\u003cbr/\u003e The lowest this value can be is `1`, anything lower will be disregarded and `1` will be used in its place. |\n\n#### `spring`\n\n|                 |                                                                                                                                                                                                                                                                                                          |\n| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Type**        | [`SpringOptions`](https://github.com/framer/motion/blob/2fa59a6e7c0a83647c8193ad37667a4f018143e2/packages/framer-motion/src/animation/types.ts#L31)                                                                                                                                                      |\n| **Default**     | `{ mass: 1.25, stiffness: 200, damping: 50 }`                                                                                                                                                                                                                                                            |\n| **Demo**        | [**View demo**](https://scroller-motion.js.org/?path=/story/scrollermotion--custom-spring)                                                                                                                                                                                                               |\n| **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/).\u003cbr/\u003e\u003cbr/\u003e You can disable the spring scroll by passing a falsy value to this prop, for example: `\u003cScollerMotion spring={null} /\u003e`. |\n\n### `useScrollerMotion` hook\n\n[**View demo**](https://scroller-motion.js.org/?path=/story/scrollermotion--use-scroller-motion)\n\nThis hook allows you to consume the internal `MotionValue` values, returning an object of the following type:\n\n```ts\n{\n  scrollX: MotionValue,\n  scrollXProgress: MotionValue,\n  scrollY: MotionValue,\n  scrollYProgress: MotionValue,\n  x: MotionValue,\n  y: MotionValue\n}\n```\n\n- `scrollX` \u0026 `scrollY`: The current scroll position.\n- `scrollXProgress` \u0026 `scrollYProgress`: A `0` to `1` transform of `scrollX|scrollY`, similar to those returned by [`useScroll`](https://www.framer.com/docs/use-scroll/#usage).\n- `x` \u0026 `y`: A negative representation of `scrollX|scrollY`.\n\nIt must be used within a `\u003cScrollerMotion /\u003e`, to read the values in the parent component see [Motion Listeners](#motion-listeners).\n\n\u003e ℹ️ 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).\n\n```tsx\nimport { ScrollerMotion, useScrollerMotion } from 'scroller-motion'\nimport { motion } from 'framer-motion'\n\nconst MyComponent = () =\u003e {\n  const { x, y } = useScrollerMotion()\n\n  return \u003cmotion.div style={{ x, y }}\u003eHello world\u003c/motion.div\u003e\n}\n\nexport default () =\u003e (\n  \u003cScrollerMotion\u003e\n    \u003cMyComponent /\u003e\n  \u003c/ScrollerMotion\u003e\n)\n```\n\n### Motion Listeners\n\n[**View demo**](https://scroller-motion.js.org/?path=/story/scrollermotion--motion-listeners)\n\nAnother approach if you need to read/use the internal `MotionValue` values is via the `ref` prop on `\u003cScrollerMotion /\u003e`. The type of the ref is the same as the object returned from [`useScrollerMotion`](#usescrollermotion-hook).\n\nFor example, if we want to use the y-axis scroll position:\n\n```tsx\nimport { useEffect, useRef } from 'react'\nimport { useMotionValue } from 'framer-motion'\nimport { ScrollerMotion, ScrollerMotionRef } from 'scroller-motion'\n\nexport default () =\u003e {\n  const scrollerMotion = useRef\u003cScrollerMotionRef\u003e()\n  const scrollY = useMotionValue(0)\n\n  useEffect(() =\u003e {\n    const unsubscribe = scrollerMotion.current.scrollY.onChange((v) =\u003e\n      scrollY.set(v)\n    )\n\n    return () =\u003e unsubscribe()\n  }, [scrollY])\n\n  return (\n    \u003cScrollerMotion ref={scrollerMotion}\u003e\n      \u003cMyComponent scrollPosition={scrollY} /\u003e\n    \u003c/ScrollerMotion\u003e\n  )\n}\n```\n\n\u003e ℹ️ 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).\n\n### Recipes\n\n- [**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.\n- [**Horizontal scroll**](https://github.com/breadadams/scroller-motion/issues/24#issuecomment-1105743496): Convert vertical mousewheel events to horizontal window scroll.\n- [**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).\n\n### About\n\n**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 \u0026 transitions, we decided to try it out for page scrolling too - and the results were impressive! Time for an emoji list:\n\n- 🏀 Configurable motion via the `spring` prop\n- 🖱 \"Slow scroll\" via the `scale` prop\n- 📡 Subscribe to the scroll values with `useScrollerMotion`\n- ⚙️ SSR compatible\n- 🤖 Fully typed w/ TypeScript\n- 🪝 Built around React hooks\n- ⚖️ Only ~2kb gzipped\n\n### Contributing\n\nThese are the current scripts available for development:\n\n```bash\n# Start Storybook\nnpm run start\n\n# Build dist files\nnpm run build\n\n# Build static Storybook\nnpm run build:storybook\n\n# Apply Prettier formatting\nnpm run prettier:format\n\n# Check Prettier formatting\nnpm run prettier:check\n\n# Run tests\nnpm run test\n```\n\n### License\n\nReleased under the [MIT](https://github.com/breadadams/scroller-motion/blob/master/LICENSE) License.\u003cbr\u003e\nAuthored and maintained by Brad Adams with help from [contributors](https://github.com/breadadams/scroller-motion/contributors).\n\n\u003e [breadadams.com](https://breadadams.com) · GitHub [@breadadams](https://github.com/breadadams) · Twitter [@breadadams](https://twitter.com/breadadams)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbreadadams%2Fscroller-motion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbreadadams%2Fscroller-motion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbreadadams%2Fscroller-motion/lists"}