| Server IP : 103.243.232.44 / Your IP : 216.73.216.250 Web Server : LiteSpeed System : Linux server17213-10344.hostycare.online 5.14.0-687.38.1.el9_8.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Aug 12 17:19:12 EDT 2026 x86_64 User : iamakash ( 1400) PHP Version : 8.1.34 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /home/iamakash/.trash/js/ |
Upload File : |
// ============================================================
// FTN Consortium — main.js
// ============================================================
// ---- Mobile menu ----
const hamburger = document.getElementById('hamburger');
const mobileMenu = document.getElementById('mobileMenu');
if (hamburger && mobileMenu) {
hamburger.addEventListener('click', () => mobileMenu.classList.toggle('open'));
document.addEventListener('click', e => {
if (!hamburger.contains(e.target) && !mobileMenu.contains(e.target))
mobileMenu.classList.remove('open');
});
}
// ---- Navbar shadow on scroll ----
const navbar = document.getElementById('navbar');
window.addEventListener('scroll', () => {
if (navbar) navbar.style.boxShadow = window.scrollY > 20 ? '0 2px 20px rgba(0,0,0,0.3)' : 'none';
}, { passive: true });
// ---- Scroll-to-top button ----
const scrollTopBtn = document.getElementById('scrollTop');
if (scrollTopBtn) {
window.addEventListener('scroll', () => scrollTopBtn.classList.toggle('visible', window.scrollY > 400), { passive: true });
scrollTopBtn.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' }));
}
// ---- Fade-in on scroll ----
const fadeEls = document.querySelectorAll('.fade-in');
if (fadeEls.length) {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry, i) => {
if (entry.isIntersecting) {
setTimeout(() => entry.target.classList.add('visible'), i * 90);
observer.unobserve(entry.target);
}
});
}, { threshold: 0.1 });
fadeEls.forEach(el => observer.observe(el));
}
// ---- Portfolio filter ----
const filterBtns = document.querySelectorAll('.filter-btn');
const portfolioCards = document.querySelectorAll('.portfolio-card[data-category]');
filterBtns.forEach(btn => {
btn.addEventListener('click', () => {
filterBtns.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const f = btn.dataset.filter;
portfolioCards.forEach(card => {
card.style.display = (f === 'all' || card.dataset.category === f) ? 'block' : 'none';
});
});
});
// ---- Smooth scroll for anchor links ----
document.querySelectorAll('a[href^="#"]').forEach(link => {
link.addEventListener('click', e => {
const target = document.querySelector(link.getAttribute('href'));
if (target) {
e.preventDefault();
window.scrollTo({ top: target.offsetTop - 80, behavior: 'smooth' });
}
});
});
// ---- Animate stat numbers ----
function animateCount(el, target, duration) {
const isSpecial = isNaN(parseInt(target));
if (isSpecial) return;
const suffix = target.replace(/[0-9]/g, '');
const num = parseInt(target);
let startTime = null;
const step = (ts) => {
if (!startTime) startTime = ts;
const progress = Math.min((ts - startTime) / duration, 1);
const ease = 1 - Math.pow(1 - progress, 3);
el.textContent = Math.floor(ease * num) + suffix;
if (progress < 1) requestAnimationFrame(step);
else el.textContent = target;
};
requestAnimationFrame(step);
}
const statNums = document.querySelectorAll('.stat-box .number, .hero-stat .number');
const statObs = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animateCount(entry.target, entry.target.textContent.trim(), 1400);
statObs.unobserve(entry.target);
}
});
}, { threshold: 0.6 });
statNums.forEach(el => statObs.observe(el));
// ---- Hero Slider ----
const heroSection = document.getElementById('heroSection');
const slides = document.querySelectorAll('.hslide');
const dots = document.querySelectorAll('.sdot');
const prevBtn = document.getElementById('sliderPrev');
const nextBtn = document.getElementById('sliderNext');
const progressFill = document.getElementById('sliderProgress');
const SLIDE_DURATION = 5500;
if (slides.length > 1) {
let current = 0;
let autoTimer = null;
let paused = false;
function startProgress() {
if (!progressFill) return;
progressFill.style.transition = 'none';
progressFill.style.width = '0%';
requestAnimationFrame(() => requestAnimationFrame(() => {
progressFill.style.transition = `width ${SLIDE_DURATION}ms linear`;
progressFill.style.width = '100%';
}));
}
function goTo(n) {
const prev = current;
current = ((n % slides.length) + slides.length) % slides.length;
if (prev === current) return;
slides[prev].classList.add('leaving');
slides[prev].classList.remove('active');
dots[prev].classList.remove('active');
setTimeout(() => slides[prev].classList.remove('leaving'), 900);
slides[current].classList.add('active');
dots[current].classList.add('active');
startProgress();
}
function startAuto() {
clearInterval(autoTimer);
autoTimer = setInterval(() => { if (!paused) goTo(current + 1); }, SLIDE_DURATION);
}
// Controls
if (prevBtn) prevBtn.addEventListener('click', () => { goTo(current - 1); startAuto(); });
if (nextBtn) nextBtn.addEventListener('click', () => { goTo(current + 1); startAuto(); });
dots.forEach((dot, i) => dot.addEventListener('click', () => { goTo(i); startAuto(); }));
// Pause on hover
if (heroSection) {
heroSection.addEventListener('mouseenter', () => { paused = true; });
heroSection.addEventListener('mouseleave', () => { paused = false; });
}
// Touch / swipe support
let touchStartX = 0;
if (heroSection) {
heroSection.addEventListener('touchstart', e => { touchStartX = e.touches[0].clientX; }, { passive: true });
heroSection.addEventListener('touchend', e => {
const diff = touchStartX - e.changedTouches[0].clientX;
if (Math.abs(diff) > 50) { goTo(diff > 0 ? current + 1 : current - 1); startAuto(); }
}, { passive: true });
}
startProgress();
startAuto();
}