diff --git a/.yarn/cache/@motionone-animation-npm-10.10.1-d0255a2947-11c5361043.zip b/.yarn/cache/@motionone-animation-npm-10.10.1-d0255a2947-11c5361043.zip
deleted file mode 100644
index 16f8a06d55..0000000000
Binary files a/.yarn/cache/@motionone-animation-npm-10.10.1-d0255a2947-11c5361043.zip and /dev/null differ
diff --git a/.yarn/cache/@motionone-animation-npm-10.12.0-1d89e3c156-1e7c230da2.zip b/.yarn/cache/@motionone-animation-npm-10.12.0-1d89e3c156-1e7c230da2.zip
new file mode 100644
index 0000000000..b74c577a4a
Binary files /dev/null and b/.yarn/cache/@motionone-animation-npm-10.12.0-1d89e3c156-1e7c230da2.zip differ
diff --git a/.yarn/cache/@motionone-dom-npm-10.11.1-762dc658fd-df57870e05.zip b/.yarn/cache/@motionone-dom-npm-10.11.1-762dc658fd-df57870e05.zip
deleted file mode 100644
index 26f44926f8..0000000000
Binary files a/.yarn/cache/@motionone-dom-npm-10.11.1-762dc658fd-df57870e05.zip and /dev/null differ
diff --git a/.yarn/cache/@motionone-dom-npm-10.12.0-bbffbf0daa-123356f28e.zip b/.yarn/cache/@motionone-dom-npm-10.12.0-bbffbf0daa-123356f28e.zip
new file mode 100644
index 0000000000..8a2130a6a4
Binary files /dev/null and b/.yarn/cache/@motionone-dom-npm-10.12.0-bbffbf0daa-123356f28e.zip differ
diff --git a/.yarn/cache/@motionone-easing-npm-10.9.0-ba0b919b6e-b0c63b161e.zip b/.yarn/cache/@motionone-easing-npm-10.12.0-5be92ac408-81f3a31829.zip
similarity index 70%
rename from .yarn/cache/@motionone-easing-npm-10.9.0-ba0b919b6e-b0c63b161e.zip
rename to .yarn/cache/@motionone-easing-npm-10.12.0-5be92ac408-81f3a31829.zip
index 60de7db8ab..0df605644e 100644
Binary files a/.yarn/cache/@motionone-easing-npm-10.9.0-ba0b919b6e-b0c63b161e.zip and b/.yarn/cache/@motionone-easing-npm-10.12.0-5be92ac408-81f3a31829.zip differ
diff --git a/.yarn/cache/@motionone-generators-npm-10.9.0-c2d3b358e8-f1d8aa5064.zip b/.yarn/cache/@motionone-generators-npm-10.12.0-3107d354ec-9e55478e2c.zip
similarity index 87%
rename from .yarn/cache/@motionone-generators-npm-10.9.0-c2d3b358e8-f1d8aa5064.zip
rename to .yarn/cache/@motionone-generators-npm-10.12.0-3107d354ec-9e55478e2c.zip
index 4b21a5f953..ec0caf5ca2 100644
Binary files a/.yarn/cache/@motionone-generators-npm-10.9.0-c2d3b358e8-f1d8aa5064.zip and b/.yarn/cache/@motionone-generators-npm-10.12.0-3107d354ec-9e55478e2c.zip differ
diff --git a/.yarn/cache/@motionone-types-npm-10.9.0-0083d58cd6-aab2966c8a.zip b/.yarn/cache/@motionone-types-npm-10.12.0-93c236a2da-91b53fa78f.zip
similarity index 59%
rename from .yarn/cache/@motionone-types-npm-10.9.0-0083d58cd6-aab2966c8a.zip
rename to .yarn/cache/@motionone-types-npm-10.12.0-93c236a2da-91b53fa78f.zip
index aa8a84a883..6a6c1d2798 100644
Binary files a/.yarn/cache/@motionone-types-npm-10.9.0-0083d58cd6-aab2966c8a.zip and b/.yarn/cache/@motionone-types-npm-10.12.0-93c236a2da-91b53fa78f.zip differ
diff --git a/.yarn/cache/@motionone-utils-npm-10.9.0-59a43b5270-b13d9eb6d6.zip b/.yarn/cache/@motionone-utils-npm-10.12.0-066c183e92-407e43e9bc.zip
similarity index 52%
rename from .yarn/cache/@motionone-utils-npm-10.9.0-59a43b5270-b13d9eb6d6.zip
rename to .yarn/cache/@motionone-utils-npm-10.12.0-066c183e92-407e43e9bc.zip
index 2f0ccad72d..069efe4d7d 100644
Binary files a/.yarn/cache/@motionone-utils-npm-10.9.0-59a43b5270-b13d9eb6d6.zip and b/.yarn/cache/@motionone-utils-npm-10.12.0-066c183e92-407e43e9bc.zip differ
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 63f0732ac7..aca5eef531 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,16 @@ Framer Motion adheres to [Semantic Versioning](http://semver.org/).
Undocumented APIs should be considered internal and may change without warning.
+## [6.5.0] 2022-07-13
+
+### Added
+
+- `useScroll` for creating scroll-linked animations.
+
+### Deprecated
+
+- `useViewportScroll` and `useElementScroll`.
+
## [6.4.3] 2022-07-08
### Fixed
diff --git a/packages/framer-motion/package.json b/packages/framer-motion/package.json
index 154778f6a5..e375294ef0 100644
--- a/packages/framer-motion/package.json
+++ b/packages/framer-motion/package.json
@@ -62,7 +62,7 @@
"react-dom": ">=16.8 || ^17.0.0 || ^18.0.0"
},
"dependencies": {
- "@motionone/dom": "^10.11.1",
+ "@motionone/dom": "10.12.0",
"framesync": "6.0.1",
"hey-listen": "^1.0.8",
"popmotion": "11.0.3",
diff --git a/packages/framer-motion/src/index.ts b/packages/framer-motion/src/index.ts
index 1edbf463c3..a8d5a92d2d 100644
--- a/packages/framer-motion/src/index.ts
+++ b/packages/framer-motion/src/index.ts
@@ -31,6 +31,7 @@ export { resolveMotionValue } from "./value/utils/resolve-motion-value"
export { useTransform } from "./value/use-transform"
export { useSpring } from "./value/use-spring"
export { useVelocity } from "./value/use-velocity"
+export { useScroll } from "./value/use-scroll"
export { useElementScroll } from "./value/scroll/use-element-scroll"
export { useViewportScroll } from "./value/scroll/use-viewport-scroll"
export { useTime } from "./value/use-time"
diff --git a/packages/framer-motion/src/value/scroll/use-element-scroll.ts b/packages/framer-motion/src/value/scroll/use-element-scroll.ts
index 772f398422..e8be5ed8d0 100644
--- a/packages/framer-motion/src/value/scroll/use-element-scroll.ts
+++ b/packages/framer-motion/src/value/scroll/use-element-scroll.ts
@@ -1,84 +1,11 @@
import { RefObject } from "react"
-import { useConstant } from "../../utils/use-constant"
-import {
- createScrollMotionValues,
- ScrollMotionValues,
- createScrollUpdater,
-} from "./utils"
-import { addDomEvent } from "../../events/use-dom-event"
-import { useIsomorphicLayoutEffect } from "../../utils/use-isomorphic-effect"
-import { invariant } from "hey-listen"
-
-const getElementScrollOffsets = (element: HTMLElement) => () => {
- return {
- xOffset: element.scrollLeft,
- yOffset: element.scrollTop,
- xMaxOffset: element.scrollWidth - element.offsetWidth,
- yMaxOffset: element.scrollHeight - element.offsetHeight,
- }
-}
-
-/**
- * Returns MotionValues that update when the provided element scrolls:
- *
- * - `scrollX` — Horizontal scroll distance in pixels.
- * - `scrollY` — Vertical scroll distance in pixels.
- * - `scrollXProgress` — Horizontal scroll progress between `0` and `1`.
- * - `scrollYProgress` — Vertical scroll progress between `0` and `1`.
- *
- * This element must be set to `overflow: scroll` on either or both axes to report scroll offset.
- *
- * ```jsx
- * export const MyComponent = () => {
- * const ref = useRef()
- * const { scrollYProgress } = useElementScroll(ref)
- *
- * return (
- *
- *
- *
- * )
- * }
- * ```
- *
- * @public
- */
-export function useElementScroll(
- ref: RefObject
-): ScrollMotionValues {
- const values = useConstant(createScrollMotionValues)
-
- useIsomorphicLayoutEffect(() => {
- const element = ref.current
-
- invariant(
- !!element,
- "ref provided to useScroll must be passed into a HTML element."
- )
- if (!element) return
-
- const updateScrollValues = createScrollUpdater(
- values,
- getElementScrollOffsets(element)
- )
-
- const scrollListener = addDomEvent(
- element,
- "scroll",
- updateScrollValues
- )
-
- const resizeListener = addDomEvent(
- element,
- "resize",
- updateScrollValues
- )
-
- return () => {
- scrollListener && scrollListener()
- resizeListener && resizeListener()
- }
- }, [])
-
- return values
+import { warnOnce } from "../../utils/warn-once"
+import { useScroll } from "../use-scroll"
+
+export function useElementScroll(ref: RefObject) {
+ warnOnce(
+ false,
+ "useElementScroll is deprecated. Convert to useScroll({ container: ref })."
+ )
+ return useScroll({ container: ref })
}
diff --git a/packages/framer-motion/src/value/scroll/use-viewport-scroll.ts b/packages/framer-motion/src/value/scroll/use-viewport-scroll.ts
index 562375d44d..8c5524f445 100644
--- a/packages/framer-motion/src/value/scroll/use-viewport-scroll.ts
+++ b/packages/framer-motion/src/value/scroll/use-viewport-scroll.ts
@@ -1,67 +1,7 @@
-import {
- createScrollMotionValues,
- createScrollUpdater,
- ScrollMotionValues,
-} from "./utils"
-import { addDomEvent } from "../../events/use-dom-event"
-import { useIsomorphicLayoutEffect } from "../../utils/use-isomorphic-effect"
+import { warnOnce } from "../../utils/warn-once"
+import { useScroll } from "../use-scroll"
-let viewportScrollValues: ScrollMotionValues
-
-function getViewportScrollOffsets() {
- return {
- xOffset: window.pageXOffset,
- yOffset: window.pageYOffset,
- xMaxOffset: document.body.clientWidth - window.innerWidth,
- yMaxOffset: document.body.clientHeight - window.innerHeight,
- }
-}
-
-let hasListeners = false
-
-function addEventListeners() {
- hasListeners = true
-
- const updateScrollValues = createScrollUpdater(
- viewportScrollValues,
- getViewportScrollOffsets
- )
-
- addDomEvent(window, "scroll", updateScrollValues)
- addDomEvent(window, "resize", updateScrollValues)
-}
-
-/**
- * Returns MotionValues that update when the viewport scrolls:
- *
- * - `scrollX` — Horizontal scroll distance in pixels.
- * - `scrollY` — Vertical scroll distance in pixels.
- * - `scrollXProgress` — Horizontal scroll progress between `0` and `1`.
- * - `scrollYProgress` — Vertical scroll progress between `0` and `1`.
- *
- * **Warning:** Setting `body` or `html` to `height: 100%` or similar will break the `Progress`
- * values as this breaks the browser's capability to accurately measure the page length.
- *
- * ```jsx
- * export const MyComponent = () => {
- * const { scrollYProgress } = useViewportScroll()
- * return
- * }
- * ```
- *
- * @public
- */
-export function useViewportScroll(): ScrollMotionValues {
- /**
- * Lazy-initialise the viewport scroll values
- */
- if (!viewportScrollValues) {
- viewportScrollValues = createScrollMotionValues()
- }
-
- useIsomorphicLayoutEffect(() => {
- !hasListeners && addEventListeners()
- }, [])
-
- return viewportScrollValues
+export function useViewportScroll() {
+ warnOnce(false, "useViewportScroll is deprecated. Convert to useScroll().")
+ return useScroll()
}
diff --git a/packages/framer-motion/src/value/use-scroll.ts b/packages/framer-motion/src/value/use-scroll.ts
new file mode 100644
index 0000000000..c6a564087a
--- /dev/null
+++ b/packages/framer-motion/src/value/use-scroll.ts
@@ -0,0 +1,43 @@
+import { scroll, ScrollOptions } from "@motionone/dom"
+import { RefObject } from "react"
+import { motionValue } from "."
+import { useIsomorphicLayoutEffect } from "../three-entry"
+import { useConstant } from "../utils/use-constant"
+
+interface UseScrollOptions extends Omit {
+ container?: RefObject
+ target?: RefObject
+}
+
+const createScrollMotionValues = () => ({
+ scrollX: motionValue(0),
+ scrollY: motionValue(0),
+ scrollXProgress: motionValue(0),
+ scrollYProgress: motionValue(0),
+})
+
+export function useScroll({
+ container,
+ target,
+ ...options
+}: UseScrollOptions = {}) {
+ const values = useConstant(createScrollMotionValues)
+
+ useIsomorphicLayoutEffect(() => {
+ return scroll(
+ ({ x, y }) => {
+ values.scrollX.set(x.current)
+ values.scrollXProgress.set(x.progress)
+ values.scrollY.set(y.current)
+ values.scrollYProgress.set(y.progress)
+ },
+ {
+ ...options,
+ container: container?.current || undefined,
+ target: target?.current || undefined,
+ }
+ )
+ }, [])
+
+ return values
+}
diff --git a/yarn.lock b/yarn.lock
index b986d1937f..82994f1a16 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2393,68 +2393,68 @@ __metadata:
languageName: node
linkType: hard
-"@motionone/animation@npm:^10.10.1":
- version: 10.10.1
- resolution: "@motionone/animation@npm:10.10.1"
+"@motionone/animation@npm:^10.12.0":
+ version: 10.12.0
+ resolution: "@motionone/animation@npm:10.12.0"
dependencies:
- "@motionone/easing": ^10.9.0
- "@motionone/types": ^10.9.0
- "@motionone/utils": ^10.9.0
+ "@motionone/easing": ^10.12.0
+ "@motionone/types": ^10.12.0
+ "@motionone/utils": ^10.12.0
tslib: ^2.3.1
- checksum: 11c5361043403f586cbe7e731dd801b3ea7e1bab4c0e1281e86b0a535841eca114fdc9606462d4a72324d6a2aac940debe5bc0910c334f3bfff250ce1a519f12
+ checksum: 1e7c230da289ee3e3906288d5efb98f4c2c641b1be2d97b6136384b632db74e67c2ab36e99547467aebbcdf00a02f070356fc3a739a67f57213373b5a9631d04
languageName: node
linkType: hard
-"@motionone/dom@npm:^10.11.1":
- version: 10.11.1
- resolution: "@motionone/dom@npm:10.11.1"
+"@motionone/dom@npm:10.12.0":
+ version: 10.12.0
+ resolution: "@motionone/dom@npm:10.12.0"
dependencies:
- "@motionone/animation": ^10.10.1
- "@motionone/generators": ^10.9.0
- "@motionone/types": ^10.9.0
- "@motionone/utils": ^10.9.0
+ "@motionone/animation": ^10.12.0
+ "@motionone/generators": ^10.12.0
+ "@motionone/types": ^10.12.0
+ "@motionone/utils": ^10.12.0
hey-listen: ^1.0.8
tslib: ^2.3.1
- checksum: df57870e059c4d702da62148ae6e872e4dc75d85d948ca51eccd33bbf345b8e4ec42d83f9471115eb1e38aaff6074686ee4ed3cb5906ba5d2fa7ed230f4f8b2a
+ checksum: 123356f28e44362c4f081aae3df22e576f46bfcb07e01257b2ac64a115668448f29b8de67e4b6e692c5407cffb78ffe7cf9fa1bc064007482bab5dd23a69d380
languageName: node
linkType: hard
-"@motionone/easing@npm:^10.9.0":
- version: 10.9.0
- resolution: "@motionone/easing@npm:10.9.0"
+"@motionone/easing@npm:^10.12.0":
+ version: 10.12.0
+ resolution: "@motionone/easing@npm:10.12.0"
dependencies:
- "@motionone/utils": ^10.9.0
+ "@motionone/utils": ^10.12.0
tslib: ^2.3.1
- checksum: b0c63b161ec595b08eab3dea37da175c5ed09e3383b8553e0346c24c000e4e5b411fc02ee0b697a0821745082343207b6a4432f6aa741d22b3371da807bffcee
+ checksum: 81f3a3182927ec2b24e129a31b873f66ba711bdd47fd465cc02ddd50e41da752e11325fccbdc27f06d02f9321d8c79d085f896b5b9d4ce549246f873ce352967
languageName: node
linkType: hard
-"@motionone/generators@npm:^10.9.0":
- version: 10.9.0
- resolution: "@motionone/generators@npm:10.9.0"
+"@motionone/generators@npm:^10.12.0":
+ version: 10.12.0
+ resolution: "@motionone/generators@npm:10.12.0"
dependencies:
- "@motionone/types": ^10.9.0
- "@motionone/utils": ^10.9.0
+ "@motionone/types": ^10.12.0
+ "@motionone/utils": ^10.12.0
tslib: ^2.3.1
- checksum: f1d8aa5064ae6e138c0873a077368b46ff6c2fc6fa3d6855aaf54b456a65ce32a708e33e4a6010c9e38dd1454aaa83251acba10fb2b1d2b5c2c47148a89e4879
+ checksum: 9e55478e2caab63268ff14c8f9e4d3cbb4a83f5e6aecd0f8be8bcd81a65c38bb2c9484174b74d757426c314c059ecbd949c73e2f5eaa8c70454455ba4b838d2a
languageName: node
linkType: hard
-"@motionone/types@npm:^10.9.0":
- version: 10.9.0
- resolution: "@motionone/types@npm:10.9.0"
- checksum: aab2966c8a6d85d5d5b008457aa0cfb671436c441c2fd11a97bca4b01c61ba0f46f030ecc6e8b917f032eb9eef47e48f5b3898566e02af48d9a96ec2fd899bf9
+"@motionone/types@npm:^10.12.0":
+ version: 10.12.0
+ resolution: "@motionone/types@npm:10.12.0"
+ checksum: 91b53fa78f464f5f6be32c44b5ac3c041fc25ff5ed19274d6bc561e207ee6abfcd9fdc89c9a4d9990059f1eb055594e318ab34d2f5f894b6bedaf975b1e54c59
languageName: node
linkType: hard
-"@motionone/utils@npm:^10.9.0":
- version: 10.9.0
- resolution: "@motionone/utils@npm:10.9.0"
+"@motionone/utils@npm:^10.12.0":
+ version: 10.12.0
+ resolution: "@motionone/utils@npm:10.12.0"
dependencies:
- "@motionone/types": ^10.9.0
+ "@motionone/types": ^10.12.0
hey-listen: ^1.0.8
tslib: ^2.3.1
- checksum: b13d9eb6d6f4de4b315fd77ccf7537d3bd30e66d7930c52fe6f17f134f84d97ba7c9807d6ec9245328f36cfeec217751f1a716a9cf0fd5c4b4cdc44c24907f5d
+ checksum: 407e43e9bcefd11520bbd60378bcb0109d671aabbdf05b2d3b8ce1b3fccd54fae48b5d3f628050f0f2624fc04d12a5bc4b24f32c504e6994d56c79997f75a6fa
languageName: node
linkType: hard
@@ -7779,7 +7779,7 @@ __metadata:
resolution: "framer-motion@workspace:packages/framer-motion"
dependencies:
"@emotion/is-prop-valid": ^0.8.2
- "@motionone/dom": ^10.11.1
+ "@motionone/dom": 10.12.0
framesync: 6.0.1
hey-listen: ^1.0.8
jest: ^27.4.7