16. Scroll: Refresh
The useTransform()
hook is used to transform the vertical scroll distance to the small circle’s scale
and opacity
.
Code component
const items = [0, 1, 2, 3, 4]
const height = 70
const padding = 10
const size = 150
export default function CC_16_Scroll_Refresh(props) {
const scrollY = useMotionValue(0)
const scale = useTransform(scrollY, [0, 100], [0, 1])
const opacity = useTransform(scrollY, [0, 100], [0, 1])
return (
<div>
<motion.div
style={{
width: 40,
height: 40,
borderRadius: "50%",
backgroundColor: "#fff",
position: "absolute",
top: 120,
left: "50%",
marginLeft: -20,
scale: scale,
opacity: opacity,
}}
/>
<motion.div
style={{
width: size,
height: size,
borderRadius: 30,
overflow: "hidden",
position: "relative",
transform: "translateZ(0)",
cursor: "grab",
}}
whileTap={{ cursor: "grabbing" }}
>
<motion.div
style={{
width: size,
height: getHeight(items),
y: scrollY,
}}
drag="y"
dragConstraints={{
top: -getHeight(items) + size,
bottom: 0,
}}
>
{items.map((index) => {
return (
<div
style={{
width: size,
height: height,
borderRadius: 20,
backgroundColor: "#fff",
marginBottom:
index !== items.length - 1 ? 10 : 0,
}}
/>
)
})}
</motion.div>
</motion.div>
</div>
)
}
function getHeight(items) {
const totalHeight = items.length * height
const totalPadding = (items.length - 1) * padding
const totalScroll = totalHeight + totalPadding
return totalScroll
}
Code overrides
Pro tip: Don’t use a ‘native’ scroll with overrides, or things will not work.
You can only use useMotionValue()
inside an override function (or code component). That’s not convenient when you need to share the value between overrides, so here I used the non-hook version: motionValue()
.
const scrollY = motionValue(0)
export function Circle(Component): ComponentType<any> {
return (props) => {
const { style, ...rest } = props
const scale = useTransform(scrollY, [0, 100], [0, 1])
const opacity = useTransform(scrollY, [0, 100], [0, 1])
return <Component {...rest} style={{ ...style, scale, opacity }} />
}
}
export function Scroll(Component): ComponentType {
return (props) => {
return <Component {...props} contentOffsetY={scrollY} />
}
}
2 comments on “16. Scroll: Refresh”
Leave a Reply
You must be logged in to post a comment.
Hej – I am having some trouble with the scroll refresh example.
Property ‘style’ does not exist on type ‘{ children?: ReactNode;}’
Any thoughts.
That’s just a TypeScript error. It’ll probably still work.
To get rid of the error: Give your override a type of
<any>
(like I did in the example project):Or put a
// @ts-ignore
before the line that gives the error