I am looking for a solution to apply a scroll based animation to my navbar. When i scroll down or up, i want to hide/show the navbar with a scroll animation. After some research i always find only solutions like the following.
var lastScrollTop; // This Varibale will store the top position navbar = document.getElementById('navbar'); // Get The NavBar window.addEventListener('scroll',function(){ //on every scroll this funtion will be called var scrollTop = window.pageYOffset || document.documentElement.scrollTop; //This line will get the location on scroll if(scrollTop > lastScrollTop){ //if it will be greater than the previous navbar.style.top='-80px'; //set the value to the negetive of height of navbar } else{ navbar.style.top='0'; } lastScrollTop = scrollTop; //New Position Stored });
body{ margin:0; padding:0; } .container{ background:url('https://images.unsplash.com/photo-1497250681960-ef046c08a56e') no-repeat center center; height:170vh; } #navbar{ position:fixed; top:0; left:0; width:100%; background:blue; border-radius:0 0 30px 30px; color:white; text-align:center; /*Define a height for NavBar*/ height:80px; transition: 0.5s; /*and a transition time for a smooth appearence*/ } footer{ text-align:center; position:relative; bottom:0; left:0; }
<div class="container"> <navbar id="navbar"> <h1>NAVBAR<h1> </navbar> </div> <footer> <h3>End of the Page</h3> </footer>
If you scroll down or up, a css class or a style definition is applied to the navbar. But i want to show/hide the navbar, based on how much you scrolled. Say you open the page, the navbar is visible top: 0px
, so you need to scroll maybe 80px
down and every pixel you scrolled down, the navbar will be hidden pixel by pixel – so we get a nice scroll animation, instead of apply a property. The same happens when we scroll back up, only in reverse of course.
The idea comes from medium.com. If you open a post in mobile view, you can see a footer overlay which will be hide/show based on how much you scrolled:
How can i create the same kind of animation? Any ideas?
Advertisement
Answer
You have to change the value of scroll top.
… // (1) if (lastScrollTop == undefined) { lastScrollTop = scrollTop; } // (2) if(scrollTop - lastScrollTop >= 80) { // if you've scrolled down 80px navbar.style.top='-80px'; //set the value to the negetive of height of navbar // (3) lastScrollTop = scrollTop; // New Position Stored // (4) } else if (lastScrollTop - scrollTop >= 80) { // if you've scrolled up 80px navbar.style.top='0'; // (5) lastScrollTop = scrollTop; // New Position Stored } …
Since the lastScrollTop isn’t being changed on every scroll, it needs to be set initially (when it has no value)
For example: If
scrollTop
is, 81, andlastScrollTop
is 1, thenscrollTop - lastScrollTop
will be 80 (and the condition is true). That will work after you have scrolled down 80 pxNow that 80px has been reached, reset the property.
Similar logic to
(2)
, just reversed.Same as
(3)
I hope this helps!
P.S. You can change the value, 80, to any number you want.
Edit:
This gets the distance between the last scroll and the current position, and changes the nav bar style based on that.
const navbar = document.getElementById("navbar"); let lastScrollTop = 0; addEventListener("scroll", () => { // Current scroll position const scrollTop = window.pageYOffset || document.documentElement.scrollTop; // check scroll direction const distance = scrollTop - lastScrollTop; const currentTop = parseInt( getComputedStyle(navbar).top.split("px") ); // Clamp value between -80 and 0 let amount = Math.max( Math.min( currentTop + (distance < 0 ? Math.abs(distance) // scrolling up : -Math.abs(distance)// scrolling down ) * 40, // (1) 0 ), -80 ); console.log(amount, currentTop, Math.abs(distance)); navbar.style.top = `${amount}px`; lastScrollTop = scrollTop; });
body { margin: 0; padding: 0; } .container { background: url("https://images.unsplash.com/photo-1497250681960-ef046c08a56e") no-repeat center center; height: 170vh; } #navbar { position: fixed; top: 0; left: 0; width: 100%; background: blue; border-radius: 0 0 30px 30px; color: white; text-align: center; /*Define a height for NavBar*/ height: 80px; transition: 0.5s; /*and a transition time for a smooth appearence*/ } footer { text-align: center; position: relative; bottom: 0; left: 0; }
<!DOCTYPE html> <html> <head> </head> <body> <div class="container"> <navbar id="navbar"> <h1>NAVBAR</h1> </navbar> </div> <footer> <h3>End of the Page</h3> </footer> </body> </html>
- This value can be changed to suit your needs — for reasons I couldn’t figure out, I needed to add this in order to make it scroll fast enough.
I hope this can point you in the right direction!