| class CustomSlider extends HTMLElement { |
| connectedCallback() { |
| this.attachShadow({ mode: 'open' }); |
| this.shadowRoot.innerHTML = ` |
| <style> |
| .slider-container { |
| height: 100vh; |
| overflow: hidden; |
| position: relative; |
| } |
| .slide { |
| position: absolute; |
| width: 100%; |
| height: 100%; |
| background-size: cover; |
| background-position: center; |
| transition: opacity 1s ease-in-out; |
| opacity: 0; |
| } |
| .slide.active { |
| opacity: 1; |
| } |
| .overlay { |
| position: absolute; |
| bottom: 0; |
| left: 0; |
| right: 0; |
| background: linear-gradient(transparent, rgba(0,0,0,0.8)); |
| padding: 120px 5% 60px; |
| color: white; |
| } |
| .controls { |
| position: absolute; |
| bottom: 30px; |
| right: 30px; |
| display: flex; |
| gap: 10px; |
| z-index: 10; |
| } |
| .control-btn { |
| background: rgba(255,255,255,0.2); |
| backdrop-filter: blur(5px); |
| border: 1px solid rgba(255,255,255,0.3); |
| width: 50px; |
| height: 50px; |
| border-radius: 50%; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| cursor: pointer; |
| transition: all 0.3s ease; |
| } |
| .control-btn:hover { |
| background: rgba(255,255,255,0.3); |
| } |
| </style> |
| <div class="slider-container"> |
| ${window.appData.sliderImages.map((img, index) => ` |
| <div class="slide ${index === 0 ? 'active' : ''}" style="background-image: url('${img}')"></div> |
| `).join('')} |
| <div class="overlay"> |
| <h1 class="text-4xl md:text-6xl font-bold mb-4">${window.appData.propertyData.title}</h1> |
| <p class="text-xl md:text-2xl mb-6">${window.appData.propertyData.price}</p> |
| <div class="flex flex-wrap gap-4"> |
| <div class="flex items-center bg-white/20 px-4 py-2 rounded-full"> |
| <i data-feather="home" class="mr-2"></i> |
| <span>${window.appData.propertyData.specs.bedrooms} Beds</span> |
| </div> |
| <div class="flex items-center bg-white/20 px-4 py-2 rounded-full"> |
| <i data-feather="droplet" class="mr-2"></i> |
| <span>${window.appData.propertyData.specs.bathrooms} Baths</span> |
| </div> |
| <div class="flex items-center bg-white/20 px-4 py-2 rounded-full"> |
| <i data-feather="maximize" class="mr-2"></i> |
| <span>${window.appData.propertyData.specs.area}</span> |
| </div> |
| </div> |
| </div> |
| <div class="controls"> |
| <div class="control-btn prev"> |
| <i data-feather="chevron-left"></i> |
| </div> |
| <div class="control-btn next"> |
| <i data-feather="chevron-right"></i> |
| </div> |
| </div> |
| </div> |
| `; |
|
|
| |
| const slides = this.shadowRoot.querySelectorAll('.slide'); |
| let currentSlide = 0; |
| |
| const showSlide = (index) => { |
| slides.forEach(slide => slide.classList.remove('active')); |
| slides[index].classList.add('active'); |
| }; |
| |
| this.shadowRoot.querySelector('.next').addEventListener('click', () => { |
| currentSlide = (currentSlide + 1) % slides.length; |
| showSlide(currentSlide); |
| }); |
| |
| this.shadowRoot.querySelector('.prev').addEventListener('click', () => { |
| currentSlide = (currentSlide - 1 + slides.length) % slides.length; |
| showSlide(currentSlide); |
| }); |
| |
| |
| setInterval(() => { |
| currentSlide = (currentSlide + 1) % slides.length; |
| showSlide(currentSlide); |
| }, 5000); |
| } |
| } |
| customElements.define('custom-slider', CustomSlider); |