<h2 class="info">Full Page Navigation</h2>
<button class="nav-button">
<div class="line line__1"></div>
<div class="line line__2"></div>
<div class="line line__3"></div>
</button>
<nav>
<div class="nav__background"></div>
<ul>
<li><a href="#0">Home</a></li>
<li><a href="#0">About</a></li>
<li><a href="#0">Contact</a></li>
<li><a href="#0">Dance</a></li>
</ul>
</nav>
<div class="support">
<a href="https://twitter.com/DevLoop01" target="_blank"><i class="fab fa-twitter-square"></i></a>
<a href="https://codepen.io/dev_loop/" target="_blank"><i class="fab fa-codepen"></i></a>
</div>
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
background-image: url("https://source.unsplash.com/lfyKGQWEbew/1200x700");
background-size: cover;
font-family: "montserrat";
z-index: 2;
&::after{
content: '';
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.3);
}
}
a {
text-decoration: none;
text-transform: uppercase;
user-select: none;
}
button {
background: none;
border: none;
&:focus {
outline: none;
}
}
h2.info {
position: absolute;
font-size: 4.5vw;
width: 100%;
text-align: center;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.75);
pointer-events: none;
user-select: none;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 5;
}
.nav-button {
$width: 25px;
$transition-time: 350ms;
position: absolute;
top: 20px;
right: 20px;
width: #{$width + 10px};
height: #{$width + 10px};
@include flex-center();
flex-direction: column;
cursor: pointer;
z-index: 12;
&.close {
.line {
&__1 {
transform: rotate(45deg) translate(2px, -3px);
}
&__2 {
transform: rotate(-45deg);
}
&__3 {
transform: rotate(45deg) translate(-2px, 3px);
}
}
}
.line {
width: $width;
background: #fff;
height: 2px;
margin: 3px 0;
transition: all $transition-time cubic-bezier(0.9, 0, 0.33, 1);
&__1 {
width: $width;
transform-origin: left;
}
&__2 {
width: $width;
transform-origin: center;
}
&__3 {
width: $width;
transform-origin: right;
}
}
}
nav {
width: 100%;
height: 100%;
@include flex-center();
z-index: 10;
ul {
position: relative;
height: 600px;
width: 300px;
li {
position: absolute;
width: 100%;
list-style: none;
text-align: center;
left: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
z-index: 10;
@for $i from 1 through 4 {
&:nth-child(#{$i}) {
top: #{$i * 20%};
}
}
a {
position: relative;
font-size: 2.8rem;
-webkit-text-stroke: 2px #fff;
color: transparent;
font-weight: bold;
letter-spacing: 2px;
opacity: 0;
&::after {
position: absolute;
content: attr(data-text);
width: 100%;
height: 100%;
left: 0;
top: 0;
color: #fff;
clip-path: polygon(100% 100%, 100% 0px, 100% 100%, 0% 100%);
transition: all 250ms ease;
pointer-events: none;
}
&:hover {
&::after {
clip-path: polygon(0% 0%, 100% 0px, 100% 100%, 0% 100%);
}
}
}
}
}
.nav__background {
position: absolute;
width: 100%;
height: 100%;
background: rgba(34, 34, 34, 0.85);
backdrop-filter: blur(5px);
transform: scaleY(0);
z-index: 10;
}
}
.support{
position: fixed;
right: 10px;
bottom: 10px;
display: flex;
z-index: 8;
a{
margin: 0 10px;
color: #fff;
font-size: 2rem;
transition: all 400ms ease;
&:hover{
color: rgba(255, 255, 255, 0.35);
}
}
}
View Compiled
console.clear();
const listEls = Array.from(document.querySelectorAll("li"));
const button = document.querySelector(".nav-button");
const links = Array.from(document.querySelectorAll("li a"));
const listItems = Array.from(document.querySelectorAll("li"));
let menuActive = false;
let mousePos = { x: 0, y: 0 };
links.forEach(item => {
innerText = item.innerText;
item.setAttribute("data-text", innerText);
});
button.addEventListener("click", () => {
menuActive = !menuActive;
button.classList.toggle("close");
animateOpenCloseMenu();
});
function animateOpenCloseMenu() {
let navBG = document.querySelector(".nav__background");
let tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.45 } });
if (menuActive) {
tl.fromTo(
navBG,
{ scaleY: 0, transformOrigin: "bottom" },
{ scaleY: 1, transformOrigin: "top" }
);
tl.fromTo(links, { opacity: 0, top: "100%" }, { opacity: 1, top: "0%", stagger: 0.05, delay: -0.35 });
} else {
tl.fromTo(links, { opacity: 1, top: "0%" }, { opacity: 0, top: "100%", stagger: -0.05 });
tl.fromTo(
navBG,
{ scaleY: 1, transformOrigin: "top" },
{ scaleY: 0, transformOrigin: "bottom", delay: -0.35 }
);
}
}
animateOpenCloseMenu();
const options = {
distanceToMove: 15,
};
function updatePos(el) {
let dist = calculateDistance(el).distance;
let angle = calculateDistance(el).angle;
if (dist < 80) {
options.distanceToMove = dist;
gsap.to(el, 0.3, {
x: (Math.cos(angle) * options.distanceToMove) / 2,
y: (Math.sin(angle) * options.distanceToMove) / 12,
});
} else {
gsap.to(el, 0.3, {
x: 0,
y: 0,
});
}
}
function calculateDistance(el) {
let dx = mousePos.x - (el.getBoundingClientRect().left + el.offsetWidth / 2);
let dy = mousePos.y - (el.getBoundingClientRect().top + el.offsetHeight / 2);
let angle = Math.atan2(dy, dx);
let distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
return { distance, angle };
}
document.body.addEventListener("mousemove", e => {
mousePos.x = e.x;
mousePos.y = e.y;
if (menuActive) {
listEls.forEach(listEl => {
updatePos(listEl);
});
}
});