<div id="app">
<ul>
<li>Music</li>
<li>Movies</li>
<li>Apps</li>
<div class="focus-el el--1"></div>
<div class="focus-el el--2"></div>
</ul>
</div>
<div class="support">
<a href="https://twitter.com/DevLoop01" target="_blank"><i class="fab fa-twitter-square"></i></a>
<a href="https://dribbble.com/devloop01" target="_blank"><i class="fab fa-dribbble"></i></a>
</div>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
$background: #1355f6;
body {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: $background;
overflow: hidden;
}
$font-family: "montserrat";
$container-width: 350px;
$border-radius: 35px;
$element-count: 3;
#app {
width: $container-width;
height: $container-width;
display: grid;
place-items: center;
ul {
position: relative;
width: $container-width;
height: 50px;
display: grid;
grid-template-columns: repeat($element-count, 1fr);
border-radius: $border-radius;
background: rgba(255, 255, 255, 0.65);
box-shadow:
0 12.5px 10px rgba(0, 0, 0, 0.08),
0 100px 80px rgba(0, 0, 0, 0.03)
;
overflow: hidden;
li {
list-style: none;
display: grid;
place-items: center;
font-family: $font-family;
color: $background;
z-index: 10;
cursor: pointer;
}
.focus-el {
position: absolute;
left: 0;
top: 0;
width: calc(100% / #{$element-count});
height: 100%;
border-radius: $border-radius;
background: #fff;
box-shadow:
0 12.5px 10px rgba(0, 0, 0, 0.015),
0 100px 80px rgba(0, 0, 0, 0.03)
;
&.el--2 {
left: calc(-100% / #{$element-count});
}
}
}
}
.support{
position: absolute;
right: 10px;
bottom: 10px;
padding: 10px;
display: flex;
a{
margin: 0 10px;
color: #e1f2fb;
font-size: 1.8rem;
backface-visibility: hidden;
transition: all 350ms cubic-bezier(0.38,-0.12, 0.24, 1.91);
&:hover{
transform: scale(1.1);
}
}
}
View Compiled
console.clear();
const liContainer = document.querySelector("ul");
const liEls = [...document.querySelectorAll("ul li")];
const slideEl_1 = document.querySelector(".focus-el.el--1");
const slideEl_2 = document.querySelector(".focus-el.el--2");
gsap.defaults({
ease: "ease.inOut",
});
let tl = gsap.timeline();
let liRect = liContainer.getBoundingClientRect();
let slideEl_1_DefaultWidth = slideEl_1.getBoundingClientRect().width;
let slideEl_1_DefaultLeft = slideEl_1.getBoundingClientRect().left;
let slideEl_2_DefaultLeft = slideEl_2.getBoundingClientRect().left;
let startPosIndex = 1;
let reachedEnd = false;
let activeIndex = startPosIndex;
let animationDuration = 0.2;
liEls.forEach((el, index) => {
let elRect = el.getBoundingClientRect();
el.addEventListener("mousedown", () => {
if (reachedEnd && index + 1 == startPosIndex) {
tl.to(slideEl_1, animationDuration, { left: `${liRect.width}px` });
tl.to(
slideEl_2,
animationDuration,
{ left: `${elRect.left - liRect.left}px` },
`-=${animationDuration}`
);
tl.set(
slideEl_1,
{ left: `${slideEl_1_DefaultLeft - liRect.left}px` },
`+=${animationDuration}`
);
tl.set(
slideEl_2,
{ left: `${slideEl_2_DefaultLeft - liRect.left}px` },
`+=${animationDuration}`
);
}
let timesWidth = index + 1 - activeIndex + 1 <= 0 ? 1 : index + 1 - activeIndex + 1;
activeIndex = index + 1;
tl.to(slideEl_1, animationDuration, { width: `${timesWidth * slideEl_1_DefaultWidth}px` });
if (index + 1 != startPosIndex || reachedEnd == false) {
tl.to(slideEl_1, animationDuration, {
left: `${elRect.left - liRect.left}px`,
width: `${slideEl_1_DefaultWidth}px`,
});
}
if (index + 1 == liEls.length) {
reachedEnd = true;
} else {
reachedEnd = false;
}
});
});