From 8c3739fcbcbeb191b1dcc23e62e38ef12d7611d2 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Tue, 27 Nov 2018 15:03:20 +0000 Subject: [PATCH 1/5] adding viewport scroll --- dev/examples/viewport-scroll.tsx | 34 +++++++++++++++++++ package.json | 2 +- src/hooks/use-viewport-scroll.ts | 22 ++++++++++++ src/index.ts | 5 +-- .../use-motion-value.ts | 2 +- yarn.lock | 10 ++++++ 6 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 dev/examples/viewport-scroll.tsx create mode 100644 src/hooks/use-viewport-scroll.ts rename src/{hooks => motion-value}/use-motion-value.ts (95%) diff --git a/dev/examples/viewport-scroll.tsx b/dev/examples/viewport-scroll.tsx new file mode 100644 index 0000000000..9f2529c45a --- /dev/null +++ b/dev/examples/viewport-scroll.tsx @@ -0,0 +1,34 @@ +import * as React from "react" +import { motion, useViewportScroll, useTransform } from "@framer" + +const Item = motion.div({ + default: { + width: 100, + height: 100, + marginBottom: 100, + }, +}) + +const ItemColor = ({ i, scrollY }) => { + const base = -500 + i * 200 + + const backgroundColor = useTransform( + scrollY, + [base, base + 100, base + 200, base + 300], + ["rgba(255, 255, 255, 0.2)", "rgba(255, 255, 255, 1)", "rgba(255, 255, 255, 1)", "rgba(255, 0, 0, 0.2)"] + ) + + return +} + +export const App = () => { + const viewportScroll = useViewportScroll() + + return ( +
+ {Array.from(new Array(100), (x, i) => ( + + ))} +
+ ) +} diff --git a/package.json b/package.json index d3d4a2b0f7..a481a1cb48 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "webpack-dev-server": "^3.1.10" }, "dependencies": { - "@popmotion/popcorn": "^0.2.0", + "@popmotion/popcorn": "^0.3.0", "hey-listen": "^1.0.5", "popmotion": "8.5.3", "style-value-types": "^3.0.7", diff --git a/src/hooks/use-viewport-scroll.ts b/src/hooks/use-viewport-scroll.ts new file mode 100644 index 0000000000..3fe198fcd1 --- /dev/null +++ b/src/hooks/use-viewport-scroll.ts @@ -0,0 +1,22 @@ +import { useEffect } from "react" +import { useMotionValue } from "../motion-value/use-motion-value" + +const useViewportScroll = () => { + const x = useMotionValue(0) + const y = useMotionValue(0) + + useEffect(() => { + const onScroll = () => { + x.set(window.pageXOffset) + y.set(window.pageYOffset) + } + + window.addEventListener("scroll", onScroll, { passive: true }) + + return () => window.removeEventListener("scroll", onScroll) + }, []) + + return { x, y } +} + +export { useViewportScroll } diff --git a/src/index.ts b/src/index.ts index 62c5a01b7e..911059b2c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,10 @@ import { motion } from "./motion" -import { useMotionValue } from "./hooks/use-motion-value" +import { useMotionValue } from "./motion-value/use-motion-value" import { useTransform } from "./hooks/use-transform" import { usePose } from "./hooks/use-pose" +import { useViewportScroll } from "./hooks/use-viewport-scroll" -export { motion, useMotionValue, useTransform, usePose } +export { motion, useMotionValue, useTransform, usePose, useViewportScroll } export { useMouseEvents, useTouchEvents, usePointerEvents } from "./events" export { usePanGesture } from "./gestures" diff --git a/src/hooks/use-motion-value.ts b/src/motion-value/use-motion-value.ts similarity index 95% rename from src/hooks/use-motion-value.ts rename to src/motion-value/use-motion-value.ts index 4bede2a6a1..468d407835 100644 --- a/src/hooks/use-motion-value.ts +++ b/src/motion-value/use-motion-value.ts @@ -1,5 +1,5 @@ import { useMemo } from "react" -import { motionValue } from "../motion-value" +import { motionValue } from "." /** * For advanced use-cases, you can assume external control of the motion values used by `motion` components. diff --git a/yarn.lock b/yarn.lock index d1113013dc..604017eb8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -79,6 +79,16 @@ hey-listen "^1.0.5" style-value-types "^3.0.7" +"@popmotion/popcorn@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@popmotion/popcorn/-/popcorn-0.3.0.tgz#d75da7a0def2a949016d1cd3794f36514d69019f" + integrity sha512-iTPnu07k8mGBuJEt9NhAJ132sd0dNG9/AwqzJeKHjZA9aqtxnP9X0AFbklJrGc18HdPtdzwvGufpcJerSMGdvQ== + dependencies: + "@popmotion/easing" "^1.0.1" + framesync "^4.0.1" + hey-listen "^1.0.5" + style-value-types "^3.0.7" + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" From 08d6b9db6cddcbfdb5ab30e8ca345f6f49183863 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Tue, 27 Nov 2018 15:08:50 +0000 Subject: [PATCH 2/5] updating docs --- src/hooks/use-viewport-scroll.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/hooks/use-viewport-scroll.ts b/src/hooks/use-viewport-scroll.ts index 3fe198fcd1..04c7f78fda 100644 --- a/src/hooks/use-viewport-scroll.ts +++ b/src/hooks/use-viewport-scroll.ts @@ -1,6 +1,13 @@ import { useEffect } from "react" import { useMotionValue } from "../motion-value/use-motion-value" +/** + * `useViewportScroll` provides `MotionValue`s that update when the viewport scrolls. + * + * This makes it possible to transform viewport scroll into other values. + * + * For instance, highlighting different table of contents items to correspond with page scroll. + */ const useViewportScroll = () => { const x = useMotionValue(0) const y = useMotionValue(0) From 12dab1c08fbcf2aef32b5203f8d2a2f140f82b36 Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Tue, 27 Nov 2018 15:43:15 +0000 Subject: [PATCH 3/5] updating test --- src/hooks/use-transform.ts | 10 ++++------ src/motion/__tests__/component.test.tsx | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/hooks/use-transform.ts b/src/hooks/use-transform.ts index 391f925b30..1fbf376421 100644 --- a/src/hooks/use-transform.ts +++ b/src/hooks/use-transform.ts @@ -1,5 +1,5 @@ import { useMemo, useRef, MutableRefObject } from "react" -import { MotionValue } from "../motion-value" +import { MotionValue, Transformer } from "../motion-value" import { interpolate } from "@popmotion/popcorn" /** @@ -46,8 +46,6 @@ import { interpolate } from "@popmotion/popcorn" * }; * ``` * - * - * * @param {MotionValue} value - The `MotionValue` to transform * @param {number[]} from - A linear numerical sequence. * @param {string[] | number[]} to - A series of numbers, colors or @@ -58,9 +56,9 @@ export const useTransform = (value: MotionValue, from: number[], to: string[] | return useMemo( () => { if (transformedValue.current) transformedValue.current.destroy() - transformedValue.current = value.addChild({ - transformer: interpolate(from, to), - }) + + const transformer = interpolate(from, to) as Transformer + transformedValue.current = value.addChild({ transformer }) return transformedValue.current }, [value, ...from, ...to] diff --git a/src/motion/__tests__/component.test.tsx b/src/motion/__tests__/component.test.tsx index 4bd3a0a7be..18fbe7ec5f 100644 --- a/src/motion/__tests__/component.test.tsx +++ b/src/motion/__tests__/component.test.tsx @@ -1,7 +1,7 @@ import { fireEvent, render } from "react-testing-library" import { motion } from "../" import * as React from "react" -import { useMotionValue } from "../../hooks/use-motion-value" +import { useMotionValue } from "../../motion-value/use-motion-value" import { useTransform } from "../../hooks/use-transform" import { usePose } from "../../hooks/use-pose" import styled from "styled-components" From 6a9c941d435af0f88eee2b926ede7eafed20120c Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Wed, 28 Nov 2018 09:59:07 +0000 Subject: [PATCH 4/5] latest --- src/hooks/use-viewport-scroll.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/hooks/use-viewport-scroll.ts b/src/hooks/use-viewport-scroll.ts index 04c7f78fda..100cb5507e 100644 --- a/src/hooks/use-viewport-scroll.ts +++ b/src/hooks/use-viewport-scroll.ts @@ -1,5 +1,6 @@ import { useEffect } from "react" import { useMotionValue } from "../motion-value/use-motion-value" +import { useEvent } from "../events/use-event" /** * `useViewportScroll` provides `MotionValue`s that update when the viewport scrolls. @@ -12,16 +13,12 @@ const useViewportScroll = () => { const x = useMotionValue(0) const y = useMotionValue(0) - useEffect(() => { - const onScroll = () => { - x.set(window.pageXOffset) - y.set(window.pageYOffset) - } + const onScroll = () => { + x.set(window.pageXOffset) + y.set(window.pageYOffset) + } - window.addEventListener("scroll", onScroll, { passive: true }) - - return () => window.removeEventListener("scroll", onScroll) - }, []) + useEvent("scroll", window, onScroll, { passive: true }) return { x, y } } From e48502bd1b00a1e6b7ed6ab1de67abe1c69cf9ae Mon Sep 17 00:00:00 2001 From: InventingWithMonster Date: Wed, 28 Nov 2018 10:00:59 +0000 Subject: [PATCH 5/5] addressing comments --- src/hooks/use-transform.ts | 4 ++-- src/hooks/use-viewport-scroll.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hooks/use-transform.ts b/src/hooks/use-transform.ts index 1fbf376421..8a2fe27278 100644 --- a/src/hooks/use-transform.ts +++ b/src/hooks/use-transform.ts @@ -1,5 +1,5 @@ import { useMemo, useRef, MutableRefObject } from "react" -import { MotionValue, Transformer } from "../motion-value" +import { MotionValue } from "../motion-value" import { interpolate } from "@popmotion/popcorn" /** @@ -57,7 +57,7 @@ export const useTransform = (value: MotionValue, from: number[], to: string[] | () => { if (transformedValue.current) transformedValue.current.destroy() - const transformer = interpolate(from, to) as Transformer + const transformer = interpolate(from, to) transformedValue.current = value.addChild({ transformer }) return transformedValue.current }, diff --git a/src/hooks/use-viewport-scroll.ts b/src/hooks/use-viewport-scroll.ts index 100cb5507e..3e00ff5c80 100644 --- a/src/hooks/use-viewport-scroll.ts +++ b/src/hooks/use-viewport-scroll.ts @@ -1,4 +1,3 @@ -import { useEffect } from "react" import { useMotionValue } from "../motion-value/use-motion-value" import { useEvent } from "../events/use-event"