Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
- **CSS restructuring**: Moved `styles` folder into `src` for better organization. - **Updated imports**: Adjusted component CSS imports to reflect new paths. - **Component tweaks**: - Increased HoverCard width from `350px` to `400px` for better visual balance. - Adjusted Footer layout: reorganized copyright and added email link. - Modified Drinks circle dimensions (from `6em` to `9em`) for improved design. - **Footer styles**: Changed copyright section's layout with top spacing and border adjustments.
114 lines
3.4 KiB
Plaintext
114 lines
3.4 KiB
Plaintext
---
|
|
// src/components/ImageCarousel.astro
|
|
import "../styles/components/ImageCarousel.css";
|
|
|
|
interface Image {
|
|
src: string;
|
|
alt: string;
|
|
}
|
|
|
|
const { images = [], id } = Astro.props as { images: Image[], id?: string };
|
|
---
|
|
|
|
<section id={id} class="image-carousel-container">
|
|
<h2 class="section-title">Galerie</h2>
|
|
<div class="image-carousel">
|
|
<button class="nav-button prev-button" aria-label="Previous image">
|
|
<span class="arrow">❮</span>
|
|
</button>
|
|
|
|
<div class="carousel-images">
|
|
<div class="carousel-track">
|
|
{images.map((image, index) => (
|
|
<div class="carousel-slide" data-index={index}>
|
|
<img src={image.src} alt={image.alt} class="carousel-image" />
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<button class="nav-button next-button" aria-label="Next image">
|
|
<span class="arrow">❯</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="carousel-indicators">
|
|
{images.map((_, index) => (
|
|
<button
|
|
class="indicator-dot"
|
|
data-index={index}
|
|
aria-label={`Go to slide ${index + 1}`}
|
|
></button>
|
|
))}
|
|
</div>
|
|
</section>
|
|
|
|
<script>
|
|
// Initialize carousel functionality
|
|
function initCarousel() {
|
|
const carousel = document.querySelector('.image-carousel');
|
|
const track = document.querySelector('.carousel-track');
|
|
const slides = document.querySelectorAll('.carousel-slide');
|
|
const prevButton = document.querySelector('.prev-button');
|
|
const nextButton = document.querySelector('.next-button');
|
|
const indicators = document.querySelectorAll('.indicator-dot');
|
|
|
|
if (!carousel || !track || !slides.length || !prevButton || !nextButton) return;
|
|
|
|
let currentIndex = 0;
|
|
const slideCount = slides.length;
|
|
|
|
// Set initial active state
|
|
updateCarousel();
|
|
|
|
// Add event listeners
|
|
prevButton.addEventListener('click', () => {
|
|
currentIndex = (currentIndex - 1 + slideCount) % slideCount;
|
|
updateCarousel();
|
|
});
|
|
|
|
nextButton.addEventListener('click', () => {
|
|
currentIndex = (currentIndex + 1) % slideCount;
|
|
updateCarousel();
|
|
});
|
|
|
|
// Add click events to indicators
|
|
indicators.forEach((dot, index) => {
|
|
dot.addEventListener('click', () => {
|
|
currentIndex = index;
|
|
updateCarousel();
|
|
});
|
|
});
|
|
|
|
// Function to update carousel display
|
|
function updateCarousel() {
|
|
// Update active class on slides
|
|
slides.forEach((slide, index) => {
|
|
const position = index - currentIndex;
|
|
|
|
// Remove all position classes
|
|
slide.classList.remove('prev', 'current', 'next');
|
|
|
|
// Add appropriate position class
|
|
if (position === -1 || (position === slideCount - 1 && currentIndex === 0)) {
|
|
slide.classList.add('prev');
|
|
} else if (position === 0) {
|
|
slide.classList.add('current');
|
|
} else if (position === 1 || (position === -(slideCount - 1) && currentIndex === slideCount - 1)) {
|
|
slide.classList.add('next');
|
|
}
|
|
});
|
|
|
|
// Update indicators
|
|
indicators.forEach((dot, index) => {
|
|
dot.classList.toggle('active', index === currentIndex);
|
|
});
|
|
}
|
|
}
|
|
|
|
// Run initialization when DOM is loaded
|
|
document.addEventListener('DOMContentLoaded', initCarousel);
|
|
|
|
// Re-initialize on astro:page-load for Astro View Transitions
|
|
document.addEventListener('astro:page-load', initCarousel);
|
|
</script> |