Files
FTCWebsite/static/js/scripts.js
abhiramtx 09a0787374 Add feature cards and update team section layout
Refactors the home page to include a new values grid with four cards and restructures the "Meet Our Team" section to display text alongside an image, with responsive adjustments for mobile. Updates JavaScript to trigger animations for the new cards and adjusts parallax scrolling trigger for the team image. Modifies CSS to implement the new grid and section layouts, including hover effects and media queries.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 5e584ab0-c340-4432-97ef-1972582b60e9
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: 6f97b00a-bb59-41e0-873f-8825c7854d1f
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d0a1d46d-d203-4308-bc6a-312ac7c0243b/5e584ab0-c340-4432-97ef-1972582b60e9/MFdA8rN
2025-11-08 22:32:03 +00:00

405 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.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');
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
}
});
}
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, .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 + '%';
});
}