anokimchen's picture
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);