Files
tscb-site/js/enhance.js
ka-official e1bb749c80 Add next-level animations and visual enhancements to the website
Integrates CSS and JavaScript for enhanced animations, including scroll progress, floating orbs, magnetic buttons, and animated gradients, while also fixing responsive image display issues on the About Us page.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 8702cea6-5379-4542-9446-7e71f9f057ab
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 0d23a4eb-ce23-497a-86bc-d3de3958ac06
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/705de26f-a3c1-41e6-845d-88f96627134c/8702cea6-5379-4542-9446-7e71f9f057ab/ejKynqE
Replit-Helium-Checkpoint-Created: true
2026-03-17 20:37:29 +00:00

358 lines
13 KiB
JavaScript

(function () {
"use strict";
/* ============================
Scroll Progress Bar
============================ */
var progressBar = document.createElement('div');
progressBar.id = 'tscb-progress';
document.body.prepend(progressBar);
window.addEventListener('scroll', function () {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
var progress = (scrollTop / scrollHeight) * 100;
progressBar.style.width = progress + '%';
}, { passive: true });
/* ============================
Hero Decorative Orbs
============================ */
var hero = document.querySelector('.hero');
if (hero) {
['hero-orb-1', 'hero-orb-2', 'hero-orb-3'].forEach(function (cls) {
var orb = document.createElement('div');
orb.className = cls;
hero.prepend(orb);
});
}
/* ============================
Intersection Observer: Stagger counters
============================ */
function observeElements(selector, className, threshold) {
var elements = document.querySelectorAll(selector);
if (!elements.length) return;
var observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
entry.target.classList.add(className);
observer.unobserve(entry.target);
}
});
}, { threshold: threshold || 0.2, rootMargin: '0px 0px -60px 0px' });
elements.forEach(function (el) { observer.observe(el); });
}
observeElements('.counter-item', 'is-visible', 0.2);
observeElements('.sponsor-logo-item', 'is-visible', 0.15);
observeElements('.about-list-item', 'is-visible', 0.15);
/* ============================
GSAP Enhanced Animations (if GSAP available)
============================ */
window.addEventListener('load', function () {
if (typeof gsap === 'undefined' || typeof ScrollTrigger === 'undefined') return;
gsap.registerPlugin(ScrollTrigger);
/* --- Hero content stagger --- */
var heroContent = document.querySelector('.hero-content .section-title');
if (heroContent) {
var heroKids = heroContent.querySelectorAll('h3, p');
gsap.from(heroKids, {
y: 40,
opacity: 0,
duration: 1,
stagger: 0.2,
ease: 'power3.out',
delay: 0.3
});
}
/* --- Counter numbers enhanced count-up feel --- */
var counterBox = document.querySelector('.counter-box');
if (counterBox) {
gsap.from(counterBox, {
scrollTrigger: {
trigger: counterBox,
start: 'top 80%',
},
scaleX: 0.92,
scaleY: 0.95,
opacity: 0,
duration: 0.9,
ease: 'power3.out'
});
}
/* --- Service items stagger entrance --- */
var serviceItems = document.querySelectorAll('.service-item');
if (serviceItems.length) {
gsap.from(serviceItems, {
scrollTrigger: {
trigger: serviceItems[0].closest('.our-services') || serviceItems[0],
start: 'top 75%',
},
y: 60,
opacity: 0,
duration: 0.8,
stagger: 0.15,
ease: 'back.out(1.4)'
});
}
/* --- About list items stagger --- */
var aboutItems = document.querySelectorAll('.about-list-item');
if (aboutItems.length) {
gsap.from(aboutItems, {
scrollTrigger: {
trigger: aboutItems[0].parentElement,
start: 'top 80%',
},
x: -30,
opacity: 0,
duration: 0.7,
stagger: 0.12,
ease: 'power2.out'
});
}
/* --- Sponsor logos stagger entrance --- */
var sponsorItems = document.querySelectorAll('.sponsor-logo-item');
if (sponsorItems.length) {
gsap.from(sponsorItems, {
scrollTrigger: {
trigger: document.querySelector('.sponsors-logo-grid'),
start: 'top 80%',
},
y: 40,
scale: 0.88,
opacity: 0,
duration: 0.7,
stagger: 0.15,
ease: 'back.out(1.7)'
});
}
/* --- CTA section reveal --- */
var ctaBox = document.querySelector('.cta-box');
if (ctaBox) {
gsap.from(ctaBox, {
scrollTrigger: {
trigger: ctaBox,
start: 'top 85%',
},
y: 30,
opacity: 0,
duration: 0.9,
ease: 'power2.out'
});
}
/* --- Section titles enhanced parallax --- */
var sectionTitles = document.querySelectorAll('.section-row .section-title');
sectionTitles.forEach(function (title) {
gsap.from(title, {
scrollTrigger: {
trigger: title,
start: 'top 85%',
},
y: 25,
opacity: 0,
duration: 0.8,
ease: 'power2.out'
});
});
/* --- Team member items stagger --- */
var teamItems = document.querySelectorAll('.team-member-item');
if (teamItems.length) {
gsap.from(teamItems, {
scrollTrigger: {
trigger: teamItems[0].closest('.our-teams') || teamItems[0],
start: 'top 75%',
},
y: 50,
opacity: 0,
duration: 0.8,
stagger: 0.14,
ease: 'back.out(1.4)'
});
}
/* --- Mission image floating --- */
var missionImg = document.querySelector('.mission-img figure');
if (missionImg) {
gsap.to(missionImg, {
y: -18,
duration: 3.5,
ease: 'sine.inOut',
yoyo: true,
repeat: -1
});
}
/* --- Mission life circle pulse --- */
var lifeCircle = document.querySelector('.mission-life-circle img');
if (lifeCircle) {
gsap.to(lifeCircle, {
boxShadow: '0 0 0 12px rgba(217, 40, 0, 0.12)',
duration: 2,
ease: 'sine.inOut',
yoyo: true,
repeat: -1
});
}
/* --- Orb parallax on scroll --- */
var orbs = document.querySelectorAll('.hero-orb-1, .hero-orb-2, .hero-orb-3');
if (orbs.length && document.querySelector('.hero')) {
orbs.forEach(function (orb, i) {
var speed = (i + 1) * 0.08;
gsap.to(orb, {
scrollTrigger: {
trigger: '.hero',
start: 'top top',
end: 'bottom top',
scrub: 1
},
y: (i % 2 === 0 ? -1 : 1) * 120 * speed * 10,
x: (i % 2 === 0 ? 1 : -1) * 40 * speed * 5,
ease: 'none'
});
});
}
/* --- Counter section scale in --- */
var counterItems = document.querySelectorAll('.counter-item');
if (counterItems.length) {
counterItems.forEach(function (item, i) {
gsap.from(item, {
scrollTrigger: {
trigger: item,
start: 'top 85%',
},
y: 35,
scale: 0.92,
opacity: 0,
duration: 0.75,
delay: i * 0.1,
ease: 'back.out(1.5)'
});
});
}
/* --- Sponsors footer line --- */
var sponsorFooter = document.querySelector('.sponsors-footer');
if (sponsorFooter) {
gsap.from(sponsorFooter, {
scrollTrigger: {
trigger: sponsorFooter,
start: 'top 90%'
},
y: 20,
opacity: 0,
duration: 0.7,
ease: 'power2.out'
});
}
});
/* ============================
Magnetic Button Effect (subtle)
============================ */
var magnetBtns = document.querySelectorAll('.btn-default, .readmore-btn');
magnetBtns.forEach(function (btn) {
btn.addEventListener('mousemove', function (e) {
var rect = btn.getBoundingClientRect();
var cx = rect.left + rect.width / 2;
var cy = rect.top + rect.height / 2;
var dx = (e.clientX - cx) / (rect.width / 2);
var dy = (e.clientY - cy) / (rect.height / 2);
var strength = btn.classList.contains('readmore-btn') ? 6 : 8;
btn.style.transform = 'translate(' + (dx * strength) + 'px, ' + (dy * strength) + 'px)';
});
btn.addEventListener('mouseleave', function () {
btn.style.transform = '';
btn.style.transition = 'transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)';
});
btn.addEventListener('mouseenter', function () {
btn.style.transition = 'transform 0.1s ease';
});
});
/* ============================
Active nav link highlight
============================ */
var currentPath = window.location.pathname.split('/').pop() || 'index.html';
var navLinks = document.querySelectorAll('.main-menu .nav-item a');
navLinks.forEach(function (link) {
var href = link.getAttribute('href') || '';
var linkFile = href.split('/').pop();
if (linkFile === currentPath || (currentPath === '' && linkFile === 'index.html')) {
link.closest('.nav-item').classList.add('active');
}
});
/* ============================
Smooth Ticker Speed Boost on hover
============================ */
var tickerBoxes = document.querySelectorAll('.scrolling-ticker-box');
tickerBoxes.forEach(function (box) {
box.addEventListener('mouseenter', function () {
box.style.animationPlayState = 'paused';
var content = box.querySelectorAll('.scrolling-content');
content.forEach(function (c) { c.style.animationPlayState = 'paused'; });
});
box.addEventListener('mouseleave', function () {
box.style.animationPlayState = '';
var content = box.querySelectorAll('.scrolling-content');
content.forEach(function (c) { c.style.animationPlayState = ''; });
});
});
/* ============================
Image tilt effect on about images
============================ */
var tiltImages = document.querySelectorAll('.about-img-1, .about-img-2, .mission-img .image-anime');
tiltImages.forEach(function (el) {
el.addEventListener('mousemove', function (e) {
var rect = el.getBoundingClientRect();
var cx = rect.left + rect.width / 2;
var cy = rect.top + rect.height / 2;
var dx = (e.clientX - cx) / (rect.width / 2);
var dy = (e.clientY - cy) / (rect.height / 2);
var img = el.querySelector('img, figure');
if (img) {
img.style.transform = 'perspective(600px) rotateY(' + (dx * 4) + 'deg) rotateX(' + (-dy * 4) + 'deg) scale(1.03)';
img.style.transition = 'transform 0.1s ease';
}
});
el.addEventListener('mouseleave', function () {
var img = el.querySelector('img, figure');
if (img) {
img.style.transform = '';
img.style.transition = 'transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1)';
}
});
});
/* ============================
Counter box animated number suffix
============================ */
// Ensure counter values have proper styling after WOW init
document.addEventListener('DOMContentLoaded', function () {
var counterTitles = document.querySelectorAll('.counter-title h2');
counterTitles.forEach(function (h2) {
h2.style.letterSpacing = '-0.02em';
});
});
})();