added first three mockups
This commit is contained in:
+146
@@ -0,0 +1,146 @@
|
||||
|
||||
// ============================================
|
||||
// PRELOADER
|
||||
// ============================================
|
||||
window.addEventListener('load', () => {
|
||||
setTimeout(() => {
|
||||
document.getElementById('preloader').classList.add('hidden');
|
||||
document.body.style.overflow = 'visible';
|
||||
}, 2200);
|
||||
});
|
||||
document.body.style.overflow = 'hidden';
|
||||
|
||||
// ============================================
|
||||
// AOS INIT
|
||||
// ============================================
|
||||
AOS.init({
|
||||
duration: 700,
|
||||
once: true,
|
||||
easing: 'ease-out-cubic',
|
||||
offset: 60,
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// STICKY NAVBAR
|
||||
// ============================================
|
||||
const nav = document.getElementById('mainNav');
|
||||
window.addEventListener('scroll', () => {
|
||||
nav.classList.toggle('scrolled', window.scrollY > 50);
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// SMOOTH SCROLL FOR NAV LINKS
|
||||
// ============================================
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
const target = document.querySelector(this.getAttribute('href'));
|
||||
if (target) {
|
||||
e.preventDefault();
|
||||
const offset = nav.offsetHeight;
|
||||
const top = target.getBoundingClientRect().top + window.scrollY - offset;
|
||||
window.scrollTo({ top, behavior: 'smooth' });
|
||||
// Close mobile menu if open
|
||||
const bsCollapse = bootstrap.Collapse.getInstance(document.getElementById('navMenu'));
|
||||
if (bsCollapse) bsCollapse.hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// ANIMATED COUNTERS
|
||||
// ============================================
|
||||
const counters = document.querySelectorAll('[data-target]');
|
||||
const counterObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
const el = entry.target;
|
||||
const target = parseInt(el.dataset.target);
|
||||
const suffix = el.querySelector('span') ? el.querySelector('span').textContent : '';
|
||||
const duration = 1800;
|
||||
const step = Math.ceil(target / (duration / 16));
|
||||
let current = 0;
|
||||
const update = () => {
|
||||
current = Math.min(current + step, target);
|
||||
el.innerHTML = current.toLocaleString() + `<span>${suffix}</span>`;
|
||||
if (current < target) requestAnimationFrame(update);
|
||||
};
|
||||
update();
|
||||
counterObserver.unobserve(el);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.5 });
|
||||
counters.forEach(c => counterObserver.observe(c));
|
||||
|
||||
// ============================================
|
||||
// TESTIMONIAL SLIDER
|
||||
// ============================================
|
||||
(() => {
|
||||
const track = document.getElementById('testiTrack');
|
||||
const slides = track.children;
|
||||
const totalSlides = slides.length;
|
||||
const dots = document.querySelectorAll('.slider-dot');
|
||||
let current = 0;
|
||||
|
||||
const go = (idx) => {
|
||||
current = (idx + totalSlides) % totalSlides;
|
||||
track.style.transform = `translateX(-${current * 100}%)`;
|
||||
dots.forEach((d, i) => d.classList.toggle('active', i === current));
|
||||
};
|
||||
|
||||
document.getElementById('testiPrev').addEventListener('click', () => go(current - 1));
|
||||
document.getElementById('testiNext').addEventListener('click', () => go(current + 1));
|
||||
dots.forEach(d => d.addEventListener('click', () => go(parseInt(d.dataset.index))));
|
||||
|
||||
// Auto-advance
|
||||
let autoTimer = setInterval(() => go(current + 1), 5000);
|
||||
track.parentElement.addEventListener('mouseenter', () => clearInterval(autoTimer));
|
||||
track.parentElement.addEventListener('mouseleave', () => { autoTimer = setInterval(() => go(current + 1), 5000); });
|
||||
|
||||
// Touch support
|
||||
let startX = 0;
|
||||
track.addEventListener('touchstart', e => { startX = e.touches[0].clientX; }, { passive: true });
|
||||
track.addEventListener('touchend', e => {
|
||||
const diff = startX - e.changedTouches[0].clientX;
|
||||
if (Math.abs(diff) > 50) go(diff > 0 ? current + 1 : current - 1);
|
||||
});
|
||||
})();
|
||||
|
||||
// ============================================
|
||||
// SCROLL TO TOP BUTTON
|
||||
// ============================================
|
||||
const scrollTopBtn = document.getElementById('scrollTop');
|
||||
window.addEventListener('scroll', () => {
|
||||
scrollTopBtn.classList.toggle('visible', window.scrollY > 400);
|
||||
});
|
||||
scrollTopBtn.addEventListener('click', () => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// CONTACT FORM SUBMISSION (demo)
|
||||
// ============================================
|
||||
document.getElementById('contactForm').addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
const name = document.getElementById('name').value.trim();
|
||||
const email = document.getElementById('email').value.trim();
|
||||
const message = document.getElementById('message').value.trim();
|
||||
if (!name || !email || !message) {
|
||||
alert('Please fill in all required fields (Name, Email, Message).');
|
||||
return;
|
||||
}
|
||||
this.style.display = 'none';
|
||||
document.getElementById('formSuccess').style.display = 'block';
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// NEWSLETTER (demo)
|
||||
// ============================================
|
||||
document.querySelector('.newsletter-btn').addEventListener('click', function () {
|
||||
const input = this.previousElementSibling;
|
||||
if (input.value && input.value.includes('@')) {
|
||||
this.innerHTML = '<i class="fas fa-check"></i>';
|
||||
this.style.background = '#22c55e';
|
||||
input.value = '';
|
||||
input.placeholder = 'Subscribed!';
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user