Files
FTCWebsite/static/js/scripts.js
abhiramtx 9916093cb1 Enhance website visuals with improved image transitions and button styling
Add a gradient overlay to the hero image section for smoother transitions. Modify button styles to adopt the blue button appearance, adjust hover effects to include a subtle shadow and opacity change, and remove the wavy animation from sponsor cards. Additionally, the navigation bar's clickability issue is addressed by ensuring correct pointer events. The dark overlay on the full team image is also deepened for better text contrast.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 5e584ab0-c340-4432-97ef-1972582b60e9
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: e6505caf-f55c-4cd8-acca-e892af468f4a
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d0a1d46d-d203-4308-bc6a-312ac7c0243b/5e584ab0-c340-4432-97ef-1972582b60e9/LO5wnCQ
2025-11-08 22:46:35 +00:00

392 lines
11 KiB
JavaScript

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.resize());
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');
navLinks.forEach(navItem => {
const link = navItem.querySelector('a');
if (link) {
const linkPath = new URL(link.href).pathname;
if (linkPath === currentPath || (currentPath === '/' && linkPath === '/')) {
navItem.classList.add('active');
}
}
});
const sidebarLinks = document.querySelectorAll('.sidebar a');
const hash = window.location.hash;
if (hash) {
sidebarLinks.forEach(link => {
if (link.getAttribute('href') === hash) {
link.classList.add('active');
}
});
} else if (sidebarLinks.length > 0) {
sidebarLinks[0].classList.add('active');
}
sidebarLinks.forEach(link => {
link.addEventListener('click', function() {
sidebarLinks.forEach(l => l.classList.remove('active'));
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: '.team-image-wrapper',
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, .team-section');
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 valueCards = document.querySelectorAll('.value-card');
valueCards.forEach((card, index) => {
gsap.fromTo(card,
{
opacity: 0,
scale: 0.9,
y: 40
},
{
opacity: 1,
scale: 1,
y: 0,
duration: 0.8,
delay: index * 0.15,
ease: "back.out(1.2)",
scrollTrigger: {
trigger: card,
start: "top 85%",
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 + '%';
});
}