ah, i also want text to voice narration and the slides be automatic slides more like a vidoe way on loop. keep like 10 slides on average
59ce6b3 verified | class CustomSlideshow extends HTMLElement { | |
| static get observedAttributes() { | |
| return ['image', 'title', 'text', 'current-index', 'total-slides']; | |
| } | |
| constructor() { | |
| super(); | |
| this.attachShadow({ mode: 'open' }); | |
| } | |
| connectedCallback() { | |
| this.render(); | |
| feather.replace(); | |
| } | |
| attributeChangedCallback(name, oldValue, newValue) { | |
| this.render(); | |
| feather.replace(); | |
| } | |
| render() { | |
| const image = this.getAttribute('image') || 'http://static.photos/pink/1200x630/1'; | |
| const title = this.getAttribute('title') || 'Slide Title'; | |
| const text = this.getAttribute('text') || 'Slide description goes here'; | |
| const currentIndex = this.getAttribute('current-index') || 1; | |
| const totalSlides = this.getAttribute('total-slides') || 10; | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| .slide-container { | |
| position: relative; | |
| height: 500px; | |
| background-size: cover; | |
| background-position: center; | |
| transition: background-image 0.5s ease; | |
| } | |
| .slide-overlay { | |
| position: absolute; | |
| inset: 0; | |
| background: linear-gradient(to bottom, rgba(0,0,0,0.1), rgba(0,0,0,0.3)); | |
| } | |
| .slide-content { | |
| position: relative; | |
| z-index: 10; | |
| height: 100%; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: flex-end; | |
| padding: 2rem; | |
| } | |
| .controls { | |
| position: absolute; | |
| top: 50%; | |
| width: 100%; | |
| display: flex; | |
| justify-content: space-between; | |
| transform: translateY(-50%); | |
| z-index: 20; | |
| } | |
| .control-btn { | |
| background-color: rgba(255, 255, 255, 0.8); | |
| border-radius: 50%; | |
| width: 40px; | |
| height: 40px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| margin: 0 1rem; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
| } | |
| .control-btn:hover { | |
| background-color: white; | |
| transform: scale(1.1); | |
| } | |
| .bottom-controls { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-top: 1rem; | |
| padding: 0 1rem; | |
| } | |
| .slide-counter { | |
| background-color: rgba(255,255,255,0.8); | |
| padding: 0.25rem 0.75rem; | |
| border-radius: 20px; | |
| font-size: 0.875rem; | |
| } | |
| .voice-control { | |
| background-color: rgba(255,255,255,0.8); | |
| border-radius: 50%; | |
| width: 40px; | |
| height: 40px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| } | |
| @media (max-width: 768px) { | |
| .slide-container { | |
| height: 400px; | |
| } | |
| .slide-content { | |
| padding: 1.5rem; | |
| } | |
| } | |
| </style> | |
| <div class="slide-container" style="background-image: url('${image}')"> | |
| <div class="slide-overlay"></div> | |
| <div class="controls"> | |
| <div class="control-btn" onclick="prevSlide()"> | |
| <i data-feather="chevron-left"></i> | |
| </div> | |
| <div class="control-btn" onclick="nextSlide()"> | |
| <i data-feather="chevron-right"></i> | |
| </div> | |
| </div> | |
| <div class="slide-content"> | |
| <div class="slide-text max-w-2xl p-6 rounded-xl"> | |
| <h1 class="text-3xl font-bold text-pink-700 mb-2">${title}</h1> | |
| <p class="text-gray-700">${text}</p> | |
| </div> | |
| <div class="progress-bar w-full mt-4 rounded-full"> | |
| <div class="progress-fill rounded-full"></div> | |
| </div> | |
| <div class="bottom-controls"> | |
| <div class="slide-counter text-pink-700"> | |
| ${currentIndex} / ${totalSlides} | |
| </div> | |
| <div class="voice-control" onclick="toggleVoice()"> | |
| <i data-feather="${speechSynthesis.speaking ? 'volume-2' : 'volume'}"></i> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| } | |
| } | |
| customElements.define('custom-slideshow', CustomSlideshow); |