Restored to 'f05d289edb8ae4d0d34f6679f8fd4aa4f4f27d21'

Replit-Restored-To: f05d289edb
This commit is contained in:
keshavanand12
2026-03-17 22:43:09 +00:00
parent 1507ed5c9f
commit 15e669ff81
5 changed files with 301 additions and 449 deletions

View File

@@ -1,6 +1,6 @@
/* =====================================================
TSCB — Homepage GSAP Masterpiece
Linked ONLY in index.html | v2.0 (mobile-aware)
Linked ONLY in index.html | v1.0
===================================================== */
(function () {
@@ -9,17 +9,14 @@
/* Guard: only run when there is a hero section */
if (!document.querySelector('.hero')) return;
/* Register GSAP plugins */
/* Register GSAP plugins (safe to call multiple times) */
gsap.registerPlugin(ScrollTrigger);
/* ── Mobile detection ── */
var isMobile = window.matchMedia('(max-width: 767px)').matches ||
('ontouchstart' in window && window.innerWidth < 900);
/* ====================================================
1. HERO — ORBS ENTRANCE
1. HERO — ORBS ENTRANCE + MOUSE PARALLAX
==================================================== */
/* Orbs drift in after preloader */
gsap.from('.hero-orb-1', {
scale: 0.2, opacity: 0, duration: 2.8,
ease: 'power3.out', delay: 0.85
@@ -33,14 +30,14 @@
ease: 'power3.out', delay: 1.3
});
/* Orb subtle glow pulse */
/* Orb glow pulse after preloader (subtle depth feel) */
gsap.to('.hero-orb-1', {
opacity: 0.85, scale: 1.08,
duration: 3, ease: 'sine.inOut',
yoyo: true, repeat: -1, delay: 1.8
});
/* Orb scroll parallax — desktop + mobile */
/* Orb scroll parallax */
ScrollTrigger.create({
trigger: '.hero',
start: 'top top',
@@ -54,114 +51,95 @@
}
});
/* Hero parallax:
Desktop → mouse-follow
Mobile → gentle continuous drift (no cursor needed) */
/* Hero mouse parallax — orbs follow the cursor */
var heroEl = document.querySelector('.hero');
if (!isMobile) {
heroEl.addEventListener('mousemove', function (e) {
var rect = heroEl.getBoundingClientRect();
var xR = (e.clientX - rect.left) / rect.width - 0.5;
var yR = (e.clientY - rect.top) / rect.height - 0.5;
gsap.to('.hero-orb-1', { x: xR * 55, y: yR * 35, duration: 1.8, ease: 'power2.out', overwrite: 'auto' });
gsap.to('.hero-orb-2', { x: xR * -40, y: yR * -25, duration: 2.0, ease: 'power2.out', overwrite: 'auto' });
gsap.to('.hero-orb-3', { x: xR * 25, y: yR * 18, duration: 1.4, ease: 'power2.out', overwrite: 'auto' });
});
} else {
/* Mobile: slow ambient drift on orbs */
gsap.to('.hero-orb-2', {
x: 30, y: -20,
duration: 4, ease: 'sine.inOut',
yoyo: true, repeat: -1, delay: 0.5
});
gsap.to('.hero-orb-3', {
x: -20, y: 15, rotate: 20,
duration: 5, ease: 'sine.inOut',
yoyo: true, repeat: -1, delay: 1
});
}
heroEl.addEventListener('mousemove', function (e) {
var rect = heroEl.getBoundingClientRect();
var xR = (e.clientX - rect.left) / rect.width - 0.5;
var yR = (e.clientY - rect.top) / rect.height - 0.5;
gsap.to('.hero-orb-1', { x: xR * 55, y: yR * 35, duration: 1.8, ease: 'power2.out', overwrite: 'auto' });
gsap.to('.hero-orb-2', { x: xR * -40, y: yR * -25, duration: 2.0, ease: 'power2.out', overwrite: 'auto' });
gsap.to('.hero-orb-3', { x: xR * 25, y: yR * 18, duration: 1.4, ease: 'power2.out', overwrite: 'auto' });
});
/* ====================================================
2. COUNTER SECTION — single clean entrance
(replaces the previous 3-stage cascade that caused
the "spasm" effect; waypoints/counterUp still runs)
2. COUNTER SECTION — 3-STAGE DRAMATIC ENTRANCE
(counter-item has no .wow class — safe to animate)
==================================================== */
var counterSection = document.querySelector('.our-counter');
if (counterSection) {
/* One unified entrance: box scales in, items slide up together */
var counterTl = gsap.timeline({
scrollTrigger: {
trigger: '.our-counter',
start: 'top 82%',
once: true
}
/* Stage 1 — the whole box scales in */
gsap.from('.counter-box', {
scrollTrigger: { trigger: '.our-counter', start: 'top 78%', once: true },
scale: 0.88, opacity: 0, borderRadius: '40px',
duration: 1.2, ease: 'power4.out',
immediateRender: false
});
counterTl
.from('.counter-box', {
scale: 0.9, opacity: 0,
duration: 0.9, ease: 'power3.out',
immediateRender: false
})
.from('.counter-item', {
y: 40, opacity: 0,
duration: 0.65, stagger: 0.12,
ease: 'power3.out',
immediateRender: false
}, '-=0.5');
/* Stage 2 — individual items slide up with stagger */
gsap.from('.counter-item', {
scrollTrigger: { trigger: '.our-counter', start: 'top 78%', once: true },
y: 60, opacity: 0,
duration: 0.85, stagger: 0.18, delay: 0.25,
ease: 'back.out(1.6)',
immediateRender: false
});
/* Counter hover — desktop only */
if (!isMobile) {
document.querySelectorAll('.counter-item').forEach(function (item) {
item.addEventListener('mouseenter', function () {
gsap.to(item.querySelector('.counter-title h2'), {
scale: 1.12, color: '#d92800',
duration: 0.35, ease: 'back.out(2)'
});
});
item.addEventListener('mouseleave', function () {
gsap.to(item.querySelector('.counter-title h2'), {
scale: 1, color: '',
duration: 0.5, ease: 'power2.out'
});
/* Stage 3 — counter h2 numbers pop with elastic */
gsap.from('.counter-title h2', {
scrollTrigger: { trigger: '.our-counter', start: 'top 78%', once: true },
scale: 0.4, opacity: 0,
duration: 1.1, stagger: 0.2, delay: 0.55,
ease: 'elastic.out(1.1, 0.52)',
immediateRender: false
});
/* Counter hover — h2 magnify */
document.querySelectorAll('.counter-item').forEach(function (item) {
item.addEventListener('mouseenter', function () {
gsap.to(item.querySelector('.counter-title h2'), {
scale: 1.12, color: '#d92800',
duration: 0.35, ease: 'back.out(2)'
});
});
}
item.addEventListener('mouseleave', function () {
gsap.to(item.querySelector('.counter-title h2'), {
scale: 1, color: '',
duration: 0.5, ease: 'power2.out'
});
});
});
}
/* ====================================================
3. MISSION IMAGE — SCROLL PARALLAX (desktop only)
On mobile the parallax y-shift breaks the stacked
layout and makes the image float out of place.
3. MISSION IMAGE — SCROLL PARALLAX
(the reveal animation in function.js still runs)
==================================================== */
if (!isMobile) {
gsap.to('.mission-img', {
scrollTrigger: {
trigger: '.our-mission',
start: 'top bottom',
end: 'bottom top',
scrub: 1.8
},
y: -60, ease: 'none'
});
gsap.to('.mission-img', {
scrollTrigger: {
trigger: '.our-mission',
start: 'top bottom',
end: 'bottom top',
scrub: 1.8
},
y: -60, ease: 'none'
});
gsap.to('.mission-life-circle', {
scrollTrigger: {
trigger: '.our-mission',
start: 'top bottom',
end: 'bottom top',
scrub: 2.5
},
y: -95, rotate: 35, ease: 'none'
});
}
gsap.to('.mission-life-circle', {
scrollTrigger: {
trigger: '.our-mission',
start: 'top bottom',
end: 'bottom top',
scrub: 2.5
},
y: -95, rotate: 35, ease: 'none'
});
/* ====================================================
4. SERVICE TICKER — FADE IN
4. SERVICE TICKER — FADE IN + SUBTLE SCALE
==================================================== */
gsap.from('.service-ticker', {
@@ -173,63 +151,55 @@
});
/* ====================================================
5. SERVICE CARDS
Desktop → 3D tilt on hover
Mobile → slide-up stagger on scroll
5. SERVICE CARDS — 3D TILT ON HOVER
(entrance handled by WOW.js — we layer on tilt only)
==================================================== */
if (!isMobile) {
document.querySelectorAll('.service-item').forEach(function (card) {
card.style.transformStyle = 'preserve-3d';
card.addEventListener('mousemove', function (e) {
var rect = card.getBoundingClientRect();
var rotX = ((e.clientY - rect.top - rect.height / 2) / (rect.height / 2)) * -10;
var rotY = ((e.clientX - rect.left - rect.width / 2) / (rect.width / 2)) * 10;
gsap.to(card, {
rotationX: rotX, rotationY: rotY,
transformPerspective: 700,
duration: 0.35, ease: 'power2.out', overwrite: 'auto'
});
});
card.addEventListener('mouseleave', function () {
gsap.to(card, {
rotationX: 0, rotationY: 0,
duration: 0.75, ease: 'elastic.out(1, 0.45)', overwrite: 'auto'
});
document.querySelectorAll('.service-item').forEach(function (card) {
card.style.transformStyle = 'preserve-3d';
card.addEventListener('mousemove', function (e) {
var rect = card.getBoundingClientRect();
var rotX = ((e.clientY - rect.top - rect.height / 2) / (rect.height / 2)) * -10;
var rotY = ((e.clientX - rect.left - rect.width / 2) / (rect.width / 2)) * 10;
gsap.to(card, {
rotationX: rotX, rotationY: rotY,
transformPerspective: 700,
duration: 0.35, ease: 'power2.out', overwrite: 'auto'
});
});
} else {
/* Mobile: tap-scale feedback */
document.querySelectorAll('.service-item').forEach(function (card) {
card.addEventListener('touchstart', function () {
gsap.to(card, { scale: 0.97, duration: 0.15, ease: 'power2.out' });
}, { passive: true });
card.addEventListener('touchend', function () {
gsap.to(card, { scale: 1, duration: 0.35, ease: 'elastic.out(1.2, 0.5)' });
}, { passive: true });
card.addEventListener('mouseleave', function () {
gsap.to(card, {
rotationX: 0, rotationY: 0,
duration: 0.75, ease: 'elastic.out(1, 0.45)', overwrite: 'auto'
});
});
}
});
/* ====================================================
6. SPONSORS — GUARANTEED VISIBILITY
Two-trigger system: ScrollTrigger + load-time check
gsap.set() owns initial state (no CSS opacity:0 ever)
==================================================== */
var sponsorItems = document.querySelectorAll('.sponsor-logo-item');
if (sponsorItems.length) {
gsap.set(sponsorItems, { opacity: 0, y: 50, scale: 0.82 });
/* Immediately set invisible via GSAP — no CSS conflict */
gsap.set(sponsorItems, { opacity: 0, y: 60, scale: 0.78, rotationY: 15 });
var sponsorsPlayed = false;
function playSponsors() {
if (sponsorsPlayed) return;
sponsorsPlayed = true;
gsap.to(sponsorItems, {
opacity: 1, y: 0, scale: 1,
duration: 0.8, stagger: 0.15,
ease: 'back.out(1.6)'
opacity: 1, y: 0, scale: 1, rotationY: 0,
duration: 0.9, stagger: 0.22,
ease: 'back.out(1.8)',
clearProps: 'rotationY'
});
}
/* Trigger 1: normal scroll */
ScrollTrigger.create({
trigger: '.our-sponsors-section',
start: 'top 88%',
@@ -237,6 +207,7 @@
onEnter: playSponsors
});
/* Trigger 2: already visible when page finishes loading */
window.addEventListener('load', function () {
setTimeout(function () {
var sec = document.querySelector('.our-sponsors-section');
@@ -248,45 +219,43 @@
}, 980);
});
/* 3D tilt — desktop only */
if (!isMobile) {
sponsorItems.forEach(function (card) {
card.style.transformStyle = 'preserve-3d';
card.addEventListener('mousemove', function (e) {
var rect = card.getBoundingClientRect();
var rotX = ((e.clientY - rect.top - rect.height / 2) / (rect.height / 2)) * -8;
var rotY = ((e.clientX - rect.left - rect.width / 2) / (rect.width / 2)) * 8;
gsap.to(card, {
rotationX: rotX, rotationY: rotY,
transformPerspective: 500,
duration: 0.3, ease: 'power2.out', overwrite: 'auto'
});
});
card.addEventListener('mouseleave', function () {
gsap.to(card, {
rotationX: 0, rotationY: 0,
duration: 0.65, ease: 'elastic.out(1, 0.45)', overwrite: 'auto'
});
/* 3D tilt on hover — works after animation completes */
sponsorItems.forEach(function (card) {
card.style.transformStyle = 'preserve-3d';
card.addEventListener('mousemove', function (e) {
var rect = card.getBoundingClientRect();
var rotX = ((e.clientY - rect.top - rect.height / 2) / (rect.height / 2)) * -8;
var rotY = ((e.clientX - rect.left - rect.width / 2) / (rect.width / 2)) * 8;
gsap.to(card, {
rotationX: rotX, rotationY: rotY,
transformPerspective: 500,
duration: 0.3, ease: 'power2.out', overwrite: 'auto'
});
});
}
card.addEventListener('mouseleave', function () {
gsap.to(card, {
rotationX: 0, rotationY: 0,
duration: 0.65, ease: 'elastic.out(1, 0.45)', overwrite: 'auto'
});
});
});
}
/* ====================================================
7. CTA BOX — SPLIT ENTRANCE
(cta-box-btn has .wow — we animate cta-box-content only)
==================================================== */
gsap.from('.cta-box-content', {
scrollTrigger: { trigger: '.cta-box', start: 'top 82%', once: true },
x: isMobile ? 0 : -70,
y: isMobile ? 30 : 0,
opacity: 0,
x: -70, opacity: 0,
duration: 1.1, ease: 'power4.out',
immediateRender: false
});
/* ====================================================
8. GLOBAL SCROLL PROGRESS FLASH
8. GLOBAL SCROLL PROGRESS + SECTION FLASH
Brief red flash on the progress bar when entering a section
==================================================== */
var sectionFlashSections = document.querySelectorAll('.our-counter, .our-services, .our-sponsors-section, .cta-box');
@@ -306,6 +275,7 @@
/* ====================================================
9. ABOUT-LIST ICON BOXES — STAGGER SPIN-IN
(icons inside .about-list-item — no .wow class on the icon)
==================================================== */
gsap.from('#home-about .about-list-item .icon-box', {
@@ -317,82 +287,29 @@
});
/* ====================================================
10. MOBILE-SPECIFIC SCROLL ANIMATIONS
Beautiful slide-in effects activated by scroll
(replaces cursor-dependent hover animations)
10. SCROLL-TRIGGERED BACKGROUND GRADIENT SHIFT
on the hero as user scrolls away
==================================================== */
if (isMobile) {
/* About section list items: stagger slide from left */
gsap.from('#home-about .about-list-item', {
scrollTrigger: { trigger: '#home-about .about-content-body', start: 'top 88%', once: true },
x: -30, opacity: 0,
duration: 0.6, stagger: 0.15,
ease: 'power3.out',
immediateRender: false
});
/* Mission section: text slides in from left, image from bottom */
gsap.from('.mission-content .section-title', {
scrollTrigger: { trigger: '.our-mission', start: 'top 85%', once: true },
x: -40, opacity: 0,
duration: 0.75, ease: 'power3.out',
immediateRender: false
});
gsap.from('.mission-image', {
scrollTrigger: { trigger: '.mission-image', start: 'top 90%', once: true },
y: 50, opacity: 0,
duration: 0.8, ease: 'power3.out',
immediateRender: false
});
/* Service items: alternate slide from left/right */
document.querySelectorAll('.service-item').forEach(function (card, i) {
gsap.from(card, {
scrollTrigger: { trigger: card, start: 'top 90%', once: true },
x: i % 2 === 0 ? -40 : 40,
opacity: 0,
duration: 0.65,
ease: 'power3.out',
immediateRender: false
});
});
/* CTA box: gentle scale pop */
gsap.from('.cta-box', {
scrollTrigger: { trigger: '.cta-box', start: 'top 90%', once: true },
scale: 0.95, opacity: 0,
duration: 0.75, ease: 'back.out(1.8)',
immediateRender: false
});
}
/* ====================================================
11. HERO BRIGHTNESS SHIFT ON SCROLL (desktop only)
==================================================== */
if (!isMobile) {
ScrollTrigger.create({
trigger: '.hero',
start: 'top top',
end: 'bottom top',
scrub: 1,
onUpdate: function (self) {
heroEl.style.filter = 'brightness(' + (1 - self.progress * 0.18) + ')';
}
});
}
ScrollTrigger.create({
trigger: '.hero',
start: 'top top',
end: 'bottom top',
scrub: 1,
onUpdate: function (self) {
heroEl.style.filter = 'brightness(' + (1 - self.progress * 0.18) + ')';
}
});
/* ====================================================
FINALIZE: refresh ScrollTrigger after full load
(handles lazy images and font layout shifts)
==================================================== */
window.addEventListener('load', function () {
setTimeout(function () {
ScrollTrigger.refresh();
}, 400);
}, 300);
});
})();