JSFiddle - React, Tailwind, and code Playground
by Prathameshsb
HTML
<body class="main-container">
<svg style="position: absolute; width: 0; height: 0; visibility: hidden;">
<filter id='noiseFilter'>
<feTurbulence
type='fractalNoise'
baseFrequency='0.5' numOctaves="2"
stitchTiles='stitch'/>
<feColorMatrix in="colorNoise" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 2.5 -1" />
<feComposite operator="in" in2="SourceGraphic" result="monoNoise"/>
<feBlend in="SourceGraphic" in2="monoNoise" mode="screen" />
</filter>
</svg>
<section class="topSection">
<div class="cursor"></div>
<div class="shapes">
<div class="shape shape-1"></div>
<div class="shape shape-2"></div>
<div class="shape shape-3"></div>
</div>
<div class="content">
<div class="text-container">
<h1 id="text1"></h1>
<h1 id="text2"></h1>
</div>
<svg id="filters">
<defs>
<filter id="threshold">
<feColorMatrix in="SourceGraphic" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 255 -140" />
</filter>
</defs>
</svg>
<div class='name-tag'>
<h3><span class='iam-font'>I'm</span> <span class='highlighter-name'>Prathamesh</span></h3>
</div>
<div class='tagline-container'>
<span class='hoverme'>hover me</span><br><span class='hoverme'>↘</span>
<div class='tagline tooltip'>
{ Product Designer
<div class='tooltip-content prodDes'>
<img src="https://media.tenor.com/DdnZxQbfO1AAAAAM/bob-ross-bob.gif" alt="Product Designer Tooltip">
</div>
</div>
<div class='tagline-dot'>|</div>
<div class='tagline tooltip'>
Frontend Engineer }
<div class='tooltip-content frontEng'>
<img src="https://i.pinimg.com/originals/6c/90/28/6c90288d7e10d46d18895f17f420a92c.gif" alt="Frontend Engineer Tooltip">
</div>
...
CSS
@import "https://fonts.googleapis.com/css?family=Raleway";
@import 'https://fonts.googleapis.com/css?family=Inconsolata';
@import 'https://fonts.googleapis.com/css?family=Reenie+Beanie&display=swap';
body {
background: white;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
}
.topSection {
position: relative; /* Keeps the relative positioning */
height: 100vh;
overflow: hidden;
display: flex; /* Updated to use flexbox */
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
}
/* Ensure .shapes and .content use position: absolute to be positioned within .topSection */
.shapes, .content, .cursor {
position: absolute; /* Keeps the absolute positioning for overlapping */
top: 50%; /* Centers vertically */
left: 50%; /* Centers horizontally */
transform: translate(-50%, -50%); /* Ensures true centering from the middle */
width: 100%; /* May adjust depending on requirement */
height: 100%; /* May adjust depending on requirement */
}
/* No changes needed for .shapes and .shape, just ensuring they are scoped to .topSection */
.shapes {
font-family: 'Montserrat', sans-serif;
background: #191919;
}
.shape {
will-change: transform;
position: absolute;
border-radius: 50%;
filter: url(#noiseFilter); /* Apply the noise filter here */
}
/* Specific shapes */
.shape.shape-1 {
background: #99c2ff;
width: 300px;
height: 300px;
margin: -150px 0 0 -150px;
}
.shape.shape-2 {
background: #ffecec;
width: 240px;
height: 240px;
margin: -120px 0 0 -120px;
}
.shape.shape-3 {
background: #ffcc57;
width: 170px;
height: 170px;
margin: -85px 0 0 -85px;
}
.content {
font-family: 'Montserrat', sans-serif;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
mix-blend-mode: difference;
color: #fff;
}
.topSection h1 {
font-size: 200px;
...
JavaScript
document.body.addEventListener("mousemove", evt => {
const mouseX = evt.clientX;
const mouseY = evt.clientY;
gsap.set(".topSection .cursor", {
x: mouseX,
y: mouseY
});
gsap.to(".topSection .shape", {
x: mouseX,
y: mouseY,
stagger: -0.1
});
});
document.addEventListener("DOMContentLoaded", function() {
// Get the h1 element
const h1 = document.querySelector('.topSection h1');
if (h1) {
const rect = h1.getBoundingClientRect(); // Get the position of the h1 tag
// Calculate center position of h1
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
// Set initial positions of cursor and shapes
gsap.set(".cursor", { x: centerX, y: centerY });
gsap.set(".shape", { x: centerX, y: centerY, stagger: -0.1 });
// If you want to animate them from this position when the mouse moves
document.body.addEventListener("mousemove", evt => {
gsap.to(".cursor", { duration: 0.3, x: evt.clientX, y: evt.clientY });
gsap.to(".shape", { duration: 0.3, x: evt.clientX, y: evt.clientY, stagger: -0.1 });
});
}
});
const elts = {
text1: document.getElementById("text1"),
text2: document.getElementById("text2")
};
const texts = [
"Hello",
"नमस्ते",
"Hola",
"こんにちは",
"Bonjour",
"안녕하세요",
"Olá",
"你好"
];
const morphTime = 1;
const cooldownTime = 0.25;
let textIndex = texts.length - 1;
let time = new Date();
let morph = 0;
let cooldown = cooldownTime;
elts.text1.textContent = texts[textIndex % texts.length];
elts.text2.textContent = texts[(textIndex + 1) % texts.length];
function doMorph() {
morph -= cooldown;
cooldown = 0;
let fraction = morph / morphTime;
if (fraction > 1) {
cooldown = cooldownTime;
fraction = 1;
}
setMorph(fraction);
}
function setMorph(fraction) {
...