:root {
--bg: #121212;
}
a {
color: white;
text-decoration: none;
}
a:hover {
color: white;
}
.bg {
background-color: var(--bg);
}
p {
text-transform: uppercase;
font-weight: bold;
}
.content p {
background: -webkit-linear-gradient(45deg, #fa9b8b 0%, #f27481 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.hidden-content {
--x: 0px;
--y: 0px;
--size: 5px;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgb(251, 156, 132);
background: -moz-linear-gradient(
180deg,
rgba(251, 156, 132, 1) 0%,
rgba(240, 102, 128, 1) 50%,
rgba(129, 36, 112, 1) 100%
);
background: -webkit-linear-gradient(
180deg,
rgba(251, 156, 132, 1) 0%,
rgba(240, 102, 128, 1) 50%,
rgba(129, 36, 112, 1) 100%
);
background: linear-gradient(
180deg,
rgba(251, 156, 132, 1) 0%,
rgba(240, 102, 128, 1) 50%,
rgba(129, 36, 112, 1) 100%
);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#fb9c84",endColorstr="#812470",GradientType=1);
color: var(--bg);
--mask: radial-gradient(
circle at var(--x) var(--y),
black var(--size),
transparent 0
);
-webkit-mask-image: var(--mask);
mask-image: var(--mask);
pointer-events: none;
visibility: hidden;
}
console.clear();
const content = document.querySelector(".content");
const link = document.querySelector("a");
const linkIcon = document.querySelector(".btn-icon");
let linkAnimated = false;
let xTo = gsap.quickTo(".hidden-content", "--x", {
duration: 0.4,
ease: "power4.out"
}),
yTo = gsap.quickTo(".hidden-content", "--y", {
duration: 0.4,
ease: "power4.out"
});
let tl = gsap.timeline({ paused: true });
tl.to(".hidden-content", {
"--size": 250,
duration: 0.75,
ease: "back.out(1.7)"
});
let hoveringContent = gsap.utils.toArray("p", content);
hoveringContent.forEach((el) => {
el.addEventListener("mouseenter", () => {
tl.restart();
});
el.addEventListener("mouseleave", () => {
tl.reverse();
});
});
/***************************************
Btn Hovering
***************************************/
let btnTl = gsap.timeline({ paused: true });
btnTl.to(".hidden-content", {
"--size": 20,
duration: 0.75,
ease: "back.out(1.7)"
});
link.addEventListener("mouseenter", (e) => {
linkAnimated = true;
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
let iconRect = linkIcon.getBoundingClientRect();
let centerX = iconRect.left + iconRect.width / 2;
let centerY = iconRect.top + iconRect.height / 2 + scrollTop;
yTo(centerY);
xTo(centerX);
btnTl.restart();
});
link.addEventListener("mouseleave", (e) => {
linkAnimated = false;
btnTl.reverse();
});
/***************************************
Add Mask on First Mouse Movement
***************************************/
window.addEventListener("mousemove", onFirstMove);
function onFirstMove(e) {
window.removeEventListener("mousemove", onFirstMove);
gsap.set(".hidden-content", { autoAlpha: 1, "--x": e.pageX, "--y": e.pageY });
window.addEventListener("mousemove", (e) => {
if (!linkAnimated) {
yTo(e.pageY);
xTo(e.pageX);
}
});
}
/***************************************
Only for the preview image
***************************************/
gsap.set(".hidden-content", {
autoAlpha: 1,
"--x": window.innerWidth / 3,
"--y": window.innerHeight / 2
});
tl.progress(0.2);