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
This commit is contained in:
357
js/enhance.js
Normal file
357
js/enhance.js
Normal file
@@ -0,0 +1,357 @@
|
||||
(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';
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user