JSFiddle - React, Tailwind, and code Playground
by HDL52
HTML
<ul class="menu-hover-image">
<li class="menu-item">
<a href="#">
<h1>Home</h1>
<span># 1</span>
</a>
</li>
<li class="menu-item">
<a href="#">
<h1>Projects</h1>
<span># 2</span>
</a>
</li>
<li class="menu-item">
<a href="#">
<h1>Blogs</h1>
<span># 3</span>
</a>
</li>
<li class="menu-item">
<a href="#">
<h1>About</h1>
<span># 4</span>
</a>
</li>
<div class="cursor"></div>
</ul>
SCSS
@import url("https://fonts.googleapis.com/css?family=Lora:400,400i,700");
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #121212;
overflow: hidden;
}
.menu-hover-image {
position: relative;
width: 56rem;
margin-bottom: 12rem;
font-family: Lora, serif;
list-style-type: none;
.cursor {
position: absolute;
top: -50%;
left: -25%;
z-index: -1;
width: 600px;
height: 400px;
background-image: linear-gradient(120deg, #a1c4fd 0%, #c2e9fb 100%);
background-position: 50% 50%;
background-size: cover;
opacity: 0;
}
.menu-item {
$menu-image-urls: url('https://raw.githubusercontent.com/Hongda-OSU/PicGo-2.3.1/master/imgied0v0dgsgyqeoh7804b0ca54buj0qd.jpg'),
url('https://raw.githubusercontent.com/Hongda-OSU/PicGo-2.3.1/master/imge39twvhffwemdsipqncbwko5vayrxgd.jpg'),
url('https://raw.githubusercontent.com/Hongda-OSU/PicGo-2.3.1/master/imgodr8vukcwco0h34p0ngc84462vs454j.jpg'),
url('https://raw.githubusercontent.com/Hongda-OSU/PicGo-2.3.1/master/imgj1udos782ybmzugwd1ltkozc9zxj3gz.jpg');
@for $i from 1 through 4 {
&:nth-child(#{$i}):hover~.cursor {
background-image: nth($menu-image-urls, $i);
}
}
a {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
text-decoration: none;
color: white;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
mix-blend-mode: difference;
transform: translate3d(0, 0, 0); // just make "mix-blend-mode" work properly.
}
}
}
JavaScript
// https://codepen.io/alphardex/pen/OJPmQGz
let menuItems = document.querySelectorAll(".menu-hover-image .menu-item")
let cursor = document.querySelector(".menu-hover-image .cursor")
let getXY = (e) => [e.clientX, e.clientY]
menuItems.forEach((menuItem) => {
// use mouseenter and mouseleave to toggle cursor since they won't bubble!
menuItem.addEventListener("mouseenter", (e) => {
let [x, y] = getXY(e)
cursor.animate(
[
{
opacity: 0,
transform: `translate(${x}px, ${y}px) scale(0)`,
},
{
opacity: 1,
transform: `translate(${x}px, ${y}px) scale(1)`,
},
],
{ duration: 300, fill: "forwards" },
)
menuItem.addEventListener("mouseleave", (e) => {
let [x, y] = getXY(e)
cursor.animate(
[
{
opacity: 1,
transform: `translate(${x}px, ${y}px) scale(1)`,
},
{
opacity: 0,
transform: `translate(${x}px, ${y}px) scale(0)`,
},
],
{ duration: 300, fill: "forwards" },
)
})
})
// move the cursor when mouse moves.
menuItem.addEventListener("mousemove", (e) => {
let [x, y] = getXY(e)
cursor.animate(
[
{
transform: `translate(${x}px, ${y}px)`,
},
{
transform: `translate(${x}px, ${y}px)`,
},
],
{ duration: 500, delay: 50, fill: "forwards" },
)
})
})