Enhance website appearance with animations and smooth scrolling effects
Integrates Lenis and GSAP for advanced scrolling animations, parallax effects, and dynamic UI elements. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 5e584ab0-c340-4432-97ef-1972582b60e9 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 298b9878-6940-427f-99ca-03452da5b40f Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d0a1d46d-d203-4308-bc6a-312ac7c0243b/5e584ab0-c340-4432-97ef-1972582b60e9/MFdA8rN
This commit is contained in:
@@ -1,4 +1,62 @@
|
||||
let lenis;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
|
||||
lenis = new Lenis({
|
||||
duration: 1.2,
|
||||
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
|
||||
smoothWheel: true,
|
||||
smoothTouch: false,
|
||||
touchMultiplier: 2,
|
||||
infinite: false
|
||||
});
|
||||
|
||||
function raf(time) {
|
||||
lenis.raf(time);
|
||||
requestAnimationFrame(raf);
|
||||
}
|
||||
requestAnimationFrame(raf);
|
||||
|
||||
lenis.on('scroll', ScrollTrigger.update);
|
||||
|
||||
gsap.ticker.lagSmoothing(0);
|
||||
|
||||
ScrollTrigger.scrollerProxy(document.body, {
|
||||
scrollTop(value) {
|
||||
if (arguments.length) {
|
||||
lenis.scrollTo(value, { immediate: true });
|
||||
}
|
||||
return lenis.scroll || 0;
|
||||
},
|
||||
getBoundingClientRect() {
|
||||
return {
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
};
|
||||
},
|
||||
pinType: document.body.style.transform ? "transform" : "fixed"
|
||||
});
|
||||
|
||||
ScrollTrigger.defaults({ scroller: document.body });
|
||||
|
||||
ScrollTrigger.addEventListener('refresh', () => lenis.update());
|
||||
ScrollTrigger.refresh();
|
||||
|
||||
let lastScrollTop = 0;
|
||||
const nav = document.querySelector('nav');
|
||||
|
||||
lenis.on('scroll', ({ scroll }) => {
|
||||
if (scroll > 100) {
|
||||
nav?.classList.add('scrolled');
|
||||
} else {
|
||||
nav?.classList.remove('scrolled');
|
||||
}
|
||||
lastScrollTop = scroll;
|
||||
});
|
||||
|
||||
const currentPath = window.location.pathname;
|
||||
|
||||
const navLinks = document.querySelectorAll('.nav-item-center, .nav-item-left');
|
||||
@@ -30,4 +88,293 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
this.classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
initParallaxEffects();
|
||||
initScrollAnimations();
|
||||
initMagneticButtons();
|
||||
initFloatingElements();
|
||||
initPageLoadAnimation();
|
||||
initCustomCursor();
|
||||
initScrollIndicator();
|
||||
});
|
||||
|
||||
function initParallaxEffects() {
|
||||
const heroImage = document.querySelector('.hero-team-image');
|
||||
if (heroImage) {
|
||||
gsap.to(heroImage, {
|
||||
yPercent: 30,
|
||||
ease: "none",
|
||||
scrollTrigger: {
|
||||
trigger: heroImage.parentElement,
|
||||
start: "top top",
|
||||
end: "bottom top",
|
||||
scrub: 1
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const baseImage = document.querySelector('.overlay-container .base');
|
||||
if (baseImage) {
|
||||
gsap.to(baseImage, {
|
||||
yPercent: 20,
|
||||
ease: "none",
|
||||
scrollTrigger: {
|
||||
trigger: '.bg',
|
||||
start: "top top",
|
||||
end: "bottom top",
|
||||
scrub: 1.5
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const meetTeamImage = document.querySelector('#meet-our-team');
|
||||
if (meetTeamImage) {
|
||||
gsap.to(meetTeamImage, {
|
||||
yPercent: 15,
|
||||
ease: "none",
|
||||
scrollTrigger: {
|
||||
trigger: '.meet-our-team-container',
|
||||
start: "top bottom",
|
||||
end: "bottom top",
|
||||
scrub: 1
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const sponsorCards = document.querySelectorAll('.sponsors-card');
|
||||
sponsorCards.forEach((card, index) => {
|
||||
gsap.to(card, {
|
||||
y: -30 * (index % 2 === 0 ? 1 : -1),
|
||||
ease: "none",
|
||||
scrollTrigger: {
|
||||
trigger: card,
|
||||
start: "top bottom",
|
||||
end: "bottom top",
|
||||
scrub: 1
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function initScrollAnimations() {
|
||||
const fadeUpElements = document.querySelectorAll('.home-info, .stats-container, .sub-header, .sub-content, .sponsors-container, .hero-image-section, .card, .member-card, .robo-card, .competition-card');
|
||||
|
||||
fadeUpElements.forEach((element, index) => {
|
||||
gsap.fromTo(element,
|
||||
{
|
||||
opacity: 0,
|
||||
y: 60
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
duration: 1,
|
||||
ease: "power3.out",
|
||||
scrollTrigger: {
|
||||
trigger: element,
|
||||
start: "top 85%",
|
||||
end: "top 60%",
|
||||
toggleActions: "play none none reverse"
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const statsCards = document.querySelectorAll('.stats-card');
|
||||
statsCards.forEach((card, index) => {
|
||||
gsap.fromTo(card,
|
||||
{
|
||||
opacity: 0,
|
||||
scale: 0.8,
|
||||
y: 40
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
y: 0,
|
||||
duration: 0.8,
|
||||
delay: index * 0.1,
|
||||
ease: "back.out(1.7)",
|
||||
scrollTrigger: {
|
||||
trigger: card,
|
||||
start: "top 85%",
|
||||
toggleActions: "play none none reverse"
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const headings = document.querySelectorAll('.heading');
|
||||
headings.forEach(heading => {
|
||||
gsap.fromTo(heading,
|
||||
{
|
||||
opacity: 0,
|
||||
scale: 0.9,
|
||||
y: 30
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
y: 0,
|
||||
duration: 0.8,
|
||||
ease: "power2.out",
|
||||
scrollTrigger: {
|
||||
trigger: heading,
|
||||
start: "top 90%",
|
||||
toggleActions: "play none none reverse"
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const footerText = document.querySelector('.footer-text');
|
||||
if (footerText) {
|
||||
gsap.fromTo(footerText,
|
||||
{
|
||||
opacity: 0,
|
||||
y: 40
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
duration: 1.2,
|
||||
delay: 0.5,
|
||||
ease: "power3.out"
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function initMagneticButtons() {
|
||||
const buttons = document.querySelectorAll('.stats-button, .bottom-center-button, #sponsors-more-button, .home-but');
|
||||
|
||||
buttons.forEach(button => {
|
||||
button.addEventListener('mouseenter', function(e) {
|
||||
gsap.to(button, {
|
||||
scale: 1.05,
|
||||
duration: 0.3,
|
||||
ease: "power2.out"
|
||||
});
|
||||
});
|
||||
|
||||
button.addEventListener('mouseleave', function(e) {
|
||||
gsap.to(button, {
|
||||
scale: 1,
|
||||
x: 0,
|
||||
y: 0,
|
||||
duration: 0.3,
|
||||
ease: "elastic.out(1, 0.5)"
|
||||
});
|
||||
});
|
||||
|
||||
button.addEventListener('mousemove', function(e) {
|
||||
const rect = button.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left - rect.width / 2;
|
||||
const y = e.clientY - rect.top - rect.height / 2;
|
||||
|
||||
gsap.to(button, {
|
||||
x: x * 0.3,
|
||||
y: y * 0.3,
|
||||
duration: 0.3,
|
||||
ease: "power2.out"
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function initFloatingElements() {
|
||||
const memberCards = document.querySelectorAll('.member-card');
|
||||
memberCards.forEach((card, index) => {
|
||||
gsap.to(card, {
|
||||
y: -10,
|
||||
duration: 2 + (index % 3) * 0.5,
|
||||
repeat: -1,
|
||||
yoyo: true,
|
||||
ease: "sine.inOut",
|
||||
delay: index * 0.2
|
||||
});
|
||||
});
|
||||
|
||||
const cards = document.querySelectorAll('.card, .card-sponsors');
|
||||
cards.forEach((card, index) => {
|
||||
gsap.to(card, {
|
||||
y: -8,
|
||||
duration: 2.5 + (index % 2) * 0.5,
|
||||
repeat: -1,
|
||||
yoyo: true,
|
||||
ease: "sine.inOut",
|
||||
delay: index * 0.15
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function initPageLoadAnimation() {
|
||||
gsap.fromTo('body',
|
||||
{ opacity: 0 },
|
||||
{ opacity: 1, duration: 0.6, ease: "power2.out" }
|
||||
);
|
||||
|
||||
const nav = document.querySelector('nav');
|
||||
if (nav) {
|
||||
gsap.fromTo(nav,
|
||||
{ y: -100, opacity: 0 },
|
||||
{ y: 0, opacity: 1, duration: 0.8, delay: 0.2, ease: "power3.out" }
|
||||
);
|
||||
}
|
||||
|
||||
const bg = document.querySelector('.bg');
|
||||
if (bg) {
|
||||
gsap.fromTo(bg,
|
||||
{ scale: 1.1, opacity: 0 },
|
||||
{ scale: 1, opacity: 1, duration: 1.5, ease: "power2.out" }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function initCustomCursor() {
|
||||
if (window.innerWidth <= 850) return;
|
||||
|
||||
const cursor = document.createElement('div');
|
||||
cursor.className = 'custom-cursor';
|
||||
document.body.appendChild(cursor);
|
||||
|
||||
const follower = document.createElement('div');
|
||||
follower.className = 'custom-cursor-follower';
|
||||
document.body.appendChild(follower);
|
||||
|
||||
let mouseX = 0, mouseY = 0;
|
||||
let followerX = 0, followerY = 0;
|
||||
|
||||
document.addEventListener('mousemove', (e) => {
|
||||
mouseX = e.clientX;
|
||||
mouseY = e.clientY;
|
||||
cursor.style.left = mouseX + 'px';
|
||||
cursor.style.top = mouseY + 'px';
|
||||
});
|
||||
|
||||
function animateFollower() {
|
||||
followerX += (mouseX - followerX) * 0.1;
|
||||
followerY += (mouseY - followerY) * 0.1;
|
||||
follower.style.left = followerX + 'px';
|
||||
follower.style.top = followerY + 'px';
|
||||
requestAnimationFrame(animateFollower);
|
||||
}
|
||||
animateFollower();
|
||||
|
||||
const hoverElements = document.querySelectorAll('a, button, .stats-card, .card, .member-card, .robo-card, .sponsors-card');
|
||||
hoverElements.forEach(el => {
|
||||
el.addEventListener('mouseenter', () => cursor.classList.add('hover'));
|
||||
el.addEventListener('mouseleave', () => cursor.classList.remove('hover'));
|
||||
});
|
||||
}
|
||||
|
||||
function initScrollIndicator() {
|
||||
const indicator = document.createElement('div');
|
||||
indicator.className = 'scroll-indicator';
|
||||
document.body.appendChild(indicator);
|
||||
|
||||
lenis.on('scroll', ({ scroll, limit }) => {
|
||||
const progress = (scroll / limit) * 100;
|
||||
indicator.style.width = progress + '%';
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user