Scroll Animation for Floating Component

Hey everyone 👋 I came across a scroll animation effect and would love some feedback on optimization. Behavior I want: A floating component starts at the bottom-right corner. As the user scrolls down, it moves upward, and when it reaches the middle of the viewport, it stays there while the page continues to scroll. I’ve built a working solution in React (code below), but it doesn’t feel very optimized. If you have a cleaner or more efficient approach, I’d love to hear your thoughts! I’m also new to Discord, so please forgive me if I’m doing anything wrong 😊
import { useEffect, useRef } from "react";

const FloatingComponent = () => {
const componentRef = useRef<HTMLDivElement | null>(null);

useEffect(() => {
const bottomOffset = 20;

const handleScroll = () => {
if (!componentRef.current) return;

const viewportHeight = window.innerHeight;
const elementHeight = componentRef.current.offsetHeight;

const scrollY = window.scrollY;

const topOffset = viewportHeight - bottomOffset - elementHeight - scrollY;

//center position
const centerY = (viewportHeight - elementHeight) / 2;

// set the component top position
componentRef.current.style.top = `${Math.max(centerY, topOffset)}px`;
};

window.addEventListener("scroll", handleScroll);
window.addEventListener("resize", handleScroll);
handleScroll();

return () => {
window.removeEventListener("scroll", handleScroll);
window.removeEventListener("resize", handleScroll);
};
}, []);

return (
<div
ref={componentRef}
style={{
backgroundColor: "black",
color: "white",
width: "fit-content",
padding: "2rem",
borderRadius: "2rem",
position: "fixed",
right: "20px",
}}
>
Floating Component
</div>
);
};

export default FloatingComponent;
import { useEffect, useRef } from "react";

const FloatingComponent = () => {
const componentRef = useRef<HTMLDivElement | null>(null);

useEffect(() => {
const bottomOffset = 20;

const handleScroll = () => {
if (!componentRef.current) return;

const viewportHeight = window.innerHeight;
const elementHeight = componentRef.current.offsetHeight;

const scrollY = window.scrollY;

const topOffset = viewportHeight - bottomOffset - elementHeight - scrollY;

//center position
const centerY = (viewportHeight - elementHeight) / 2;

// set the component top position
componentRef.current.style.top = `${Math.max(centerY, topOffset)}px`;
};

window.addEventListener("scroll", handleScroll);
window.addEventListener("resize", handleScroll);
handleScroll();

return () => {
window.removeEventListener("scroll", handleScroll);
window.removeEventListener("resize", handleScroll);
};
}, []);

return (
<div
ref={componentRef}
style={{
backgroundColor: "black",
color: "white",
width: "fit-content",
padding: "2rem",
borderRadius: "2rem",
position: "fixed",
right: "20px",
}}
>
Floating Component
</div>
);
};

export default FloatingComponent;
0 Replies
No replies yetBe the first to reply to this messageJoin

Did you find this page helpful?