160 lines
5.0 KiB
JavaScript
160 lines
5.0 KiB
JavaScript
|
|
// Modern Image Slider with Portrait/Landscape Support
|
||
|
|
|
||
|
|
document.addEventListener('DOMContentLoaded', function() {
|
||
|
|
// Slider elements
|
||
|
|
const slider = document.querySelector('.slider');
|
||
|
|
const slides = document.querySelectorAll('.slide');
|
||
|
|
const prevBtn = document.querySelector('.prev');
|
||
|
|
const nextBtn = document.querySelector('.next');
|
||
|
|
const indicatorsContainer = document.querySelector('.slider-indicators');
|
||
|
|
|
||
|
|
// Slider state
|
||
|
|
let currentSlide = 0;
|
||
|
|
let slideInterval;
|
||
|
|
const slideCount = slides.length;
|
||
|
|
|
||
|
|
// Initialize slider
|
||
|
|
function initSlider() {
|
||
|
|
// Create indicators
|
||
|
|
slides.forEach((_, index) => {
|
||
|
|
const indicator = document.createElement('div');
|
||
|
|
indicator.classList.add('indicator');
|
||
|
|
if (index === 0) indicator.classList.add('active');
|
||
|
|
indicator.addEventListener('click', () => goToSlide(index));
|
||
|
|
indicatorsContainer.appendChild(indicator);
|
||
|
|
});
|
||
|
|
|
||
|
|
// Start auto-sliding
|
||
|
|
startSlideInterval();
|
||
|
|
|
||
|
|
// Add event listeners
|
||
|
|
prevBtn.addEventListener('click', prevSlide);
|
||
|
|
nextBtn.addEventListener('click', nextSlide);
|
||
|
|
|
||
|
|
// Handle keyboard navigation
|
||
|
|
document.addEventListener('keydown', (e) => {
|
||
|
|
if (e.key === 'ArrowLeft') prevSlide();
|
||
|
|
if (e.key === 'ArrowRight') nextSlide();
|
||
|
|
});
|
||
|
|
|
||
|
|
// Pause on hover
|
||
|
|
slider.addEventListener('mouseenter', pauseSlideInterval);
|
||
|
|
slider.addEventListener('mouseleave', startSlideInterval);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Go to specific slide
|
||
|
|
function goToSlide(index) {
|
||
|
|
currentSlide = index;
|
||
|
|
updateSlider();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Previous slide
|
||
|
|
function prevSlide() {
|
||
|
|
currentSlide = (currentSlide - 1 + slideCount) % slideCount;
|
||
|
|
updateSlider();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Next slide
|
||
|
|
function nextSlide() {
|
||
|
|
currentSlide = (currentSlide + 1) % slideCount;
|
||
|
|
updateSlider();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Update slider display
|
||
|
|
function updateSlider() {
|
||
|
|
// Update active slide
|
||
|
|
slides.forEach((slide, index) => {
|
||
|
|
slide.classList.toggle('active', index === currentSlide);
|
||
|
|
});
|
||
|
|
|
||
|
|
// Update indicators
|
||
|
|
const indicators = document.querySelectorAll('.indicator');
|
||
|
|
indicators.forEach((indicator, index) => {
|
||
|
|
indicator.classList.toggle('active', index === currentSlide);
|
||
|
|
});
|
||
|
|
|
||
|
|
// Reset auto-slide timer
|
||
|
|
pauseSlideInterval();
|
||
|
|
startSlideInterval();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Start auto-sliding
|
||
|
|
function startSlideInterval() {
|
||
|
|
clearInterval(slideInterval);
|
||
|
|
slideInterval = setInterval(nextSlide, 5000);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Pause auto-sliding
|
||
|
|
function pauseSlideInterval() {
|
||
|
|
clearInterval(slideInterval);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Handle responsive behavior
|
||
|
|
function handleResponsive() {
|
||
|
|
const windowWidth = window.innerWidth;
|
||
|
|
|
||
|
|
if (windowWidth < 768) {
|
||
|
|
// Mobile view - show slide content below image
|
||
|
|
slides.forEach(slide => {
|
||
|
|
const img = slide.querySelector('img');
|
||
|
|
const content = slide.querySelector('.slide-content');
|
||
|
|
|
||
|
|
if (img && content) {
|
||
|
|
img.style.maxHeight = '60vh';
|
||
|
|
content.style.position = 'static';
|
||
|
|
content.style.marginTop = '1rem';
|
||
|
|
}
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
// Desktop view - show content overlay
|
||
|
|
slides.forEach(slide => {
|
||
|
|
const img = slide.querySelector('img');
|
||
|
|
const content = slide.querySelector('.slide-content');
|
||
|
|
|
||
|
|
if (img && content) {
|
||
|
|
img.style.maxHeight = '80vh';
|
||
|
|
content.style.position = 'absolute';
|
||
|
|
content.style.marginTop = '0';
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Initialize on load
|
||
|
|
initSlider();
|
||
|
|
handleResponsive();
|
||
|
|
|
||
|
|
// Handle window resize
|
||
|
|
window.addEventListener('resize', handleResponsive);
|
||
|
|
|
||
|
|
// Contact form submission
|
||
|
|
const contactForm = document.getElementById('contactForm');
|
||
|
|
if (contactForm) {
|
||
|
|
contactForm.addEventListener('submit', function(e) {
|
||
|
|
e.preventDefault();
|
||
|
|
alert('Thank you for your message! We will get back to you soon.');
|
||
|
|
this.reset();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Project filtering
|
||
|
|
const filterBtns = document.querySelectorAll('.filter-btn');
|
||
|
|
const projects = document.querySelectorAll('.project');
|
||
|
|
|
||
|
|
filterBtns.forEach(btn => {
|
||
|
|
btn.addEventListener('click', () => {
|
||
|
|
filterBtns.forEach(b => b.classList.remove('active'));
|
||
|
|
btn.classList.add('active');
|
||
|
|
|
||
|
|
const filter = btn.dataset.filter;
|
||
|
|
projects.forEach(project => {
|
||
|
|
if (filter === 'all' || project.classList.contains(filter)) {
|
||
|
|
project.style.display = 'block';
|
||
|
|
} else {
|
||
|
|
project.style.display = 'none';
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|