'how to use a styled component to play an animation on scroll in react
I've been trying to use styled-component animations to make my navbar change color upon scrolling down and returning it to the original color when I scroll back up. the only issue I'm currently facing is that I have no idea how to only trigger it when you scroll down the page and return it back to normal when I hit the top again.
const ChangeColor = keyframes`
0%{
background-color: #121314;
}
100%{
background-color: white;
}
`;
const GeneralContainer = styled.body`
background-color: #121314;
height: 10000px;
margin: 0;
`;
const NavBarContainer = styled.div`
border: 1px green solid;
height: 64px;
position: fixed;
width: 100%;
animation: ${NavForward} 1s linear alternate forwards 1; //I just want this to fire once when I scroll downward and fire again when I return to the top of the page.
`;
export default function Home() {
const [offset, setOffset] = useState(0);
const [isUpper, setIsUpper] = useState(true); // was trying to use this to trigger but couldnt
useEffect(() => {
const onScroll = () => {
setOffset(window.pageYOffset);
if (window.pageYOffset > 30 && isUpper === true) {
setIsUpper(false);
} else if (window.pageYOffset <= 30 && isUpper === false) {
setIsUpper(true);
}
};
// clean up code
window.removeEventListener("scroll", onScroll);
window.addEventListener("scroll", onScroll, { passive: true });
return () => window.removeEventListener("scroll", onScroll);
}, []);
return (
<GeneralContainer>
<NavBarContainer
isUpper={isUpper}
scoll={offset}
></NavBarContainer>
</GeneralContainer>
);
}
Solution 1:[1]
You could do something like this:
// Get a hook function
const {
useState,
useEffect
} = React;
const Home = () => {
const [offset, setOffset] = useState(0);
const [isUpper, setIsUpper] = useState(true); // was trying to use this to trigger but couldnt
useEffect(() => {
const onScroll = () => {
setOffset(window.pageYOffset);
if (window.pageYOffset > 30) {
setIsUpper(false);
} else if (window.pageYOffset <= 30) {
setIsUpper(true);
}
};
// clean up code
window.removeEventListener("scroll", onScroll);
window.addEventListener("scroll", onScroll, {
passive: true
});
return () => window.removeEventListener("scroll", onScroll);
}, []);
return ( <nav className ={isUpper ? 'top' : ''} > < /nav>
);
};
// Render it
ReactDOM.render( <
Home / > ,
document.getElementById("react")
);
body {
height: 2000px;
}
nav {
height: 50px;
position: fixed;
top: 0;
width: 100%;
background-color: red;
transition: background-color 1s ease;
}
nav.top {
background-color: blue;
transition: background-color 1s ease;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Charlie Araya |
