slides.jsā¢7.59 kB
// Minimalistic Slide Presentation System
class Presentation {
constructor() {
this.slides = document.querySelectorAll('.slide');
this.currentSlide = 0;
this.totalSlides = this.slides.length;
this.init();
}
init() {
// Show first slide
this.showSlide(0);
// Keyboard navigation
document.addEventListener('keydown', (e) => this.handleKeyPress(e));
// Touch/swipe support
this.setupTouchEvents();
// Navigation buttons
this.setupButtons();
// Update counter
this.updateCounter();
// Update progress bar
this.updateProgress();
// Help overlay
this.setupHelp();
}
showSlide(n) {
// Wrap around
if (n >= this.totalSlides) {
this.currentSlide = 0;
} else if (n < 0) {
this.currentSlide = this.totalSlides - 1;
} else {
this.currentSlide = n;
}
// Fade out current slides
this.slides.forEach(slide => {
if (slide.classList.contains('active')) {
slide.style.opacity = '0';
setTimeout(() => {
slide.classList.remove('active');
}, 300);
}
});
// Fade in new slide
setTimeout(() => {
this.slides[this.currentSlide].classList.add('active');
setTimeout(() => {
this.slides[this.currentSlide].style.opacity = '1';
}, 50);
}, 300);
// Update UI
this.updateCounter();
this.updateProgress();
this.updateButtons();
}
nextSlide() {
this.showSlide(this.currentSlide + 1);
}
prevSlide() {
this.showSlide(this.currentSlide - 1);
}
handleKeyPress(e) {
switch(e.key) {
case 'ArrowRight':
case ' ':
case 'PageDown':
e.preventDefault();
this.nextSlide();
break;
case 'ArrowLeft':
case 'PageUp':
e.preventDefault();
this.prevSlide();
break;
case 'Home':
e.preventDefault();
this.showSlide(0);
break;
case 'End':
e.preventDefault();
this.showSlide(this.totalSlides - 1);
break;
case '?':
case 'h':
e.preventDefault();
this.toggleHelp();
break;
case 'Escape':
if (document.fullscreenElement) {
this.exitFullscreen();
} else {
this.closeHelp();
}
break;
case 'F':
case 'f':
if (e.shiftKey) {
e.preventDefault();
this.toggleFullscreen();
}
break;
}
}
setupTouchEvents() {
let touchStartX = 0;
let touchEndX = 0;
document.addEventListener('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
});
document.addEventListener('touchend', (e) => {
touchEndX = e.changedTouches[0].screenX;
this.handleSwipe(touchStartX, touchEndX);
});
}
handleSwipe(startX, endX) {
const threshold = 50;
const diff = startX - endX;
if (Math.abs(diff) > threshold) {
if (diff > 0) {
// Swipe left - next slide
this.nextSlide();
} else {
// Swipe right - previous slide
this.prevSlide();
}
}
}
setupButtons() {
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
if (prevBtn) {
prevBtn.addEventListener('click', () => this.prevSlide());
}
if (nextBtn) {
nextBtn.addEventListener('click', () => this.nextSlide());
}
}
updateCounter() {
const counter = document.getElementById('slide-counter');
if (counter) {
counter.textContent = `${this.currentSlide + 1} / ${this.totalSlides}`;
}
}
updateProgress() {
const progressBar = document.getElementById('progress-bar');
if (progressBar) {
const progress = ((this.currentSlide + 1) / this.totalSlides) * 100;
progressBar.style.width = `${progress}%`;
}
}
updateButtons() {
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
if (prevBtn) {
prevBtn.disabled = this.currentSlide === 0;
}
if (nextBtn) {
nextBtn.disabled = this.currentSlide === this.totalSlides - 1;
}
}
setupHelp() {
const helpBtn = document.getElementById('help-btn');
const helpOverlay = document.getElementById('help-overlay');
const closeHelp = document.getElementById('close-help');
if (helpBtn) {
helpBtn.addEventListener('click', () => this.toggleHelp());
}
if (closeHelp) {
closeHelp.addEventListener('click', () => this.closeHelp());
}
if (helpOverlay) {
helpOverlay.addEventListener('click', (e) => {
if (e.target === helpOverlay) {
this.closeHelp();
}
});
}
}
toggleHelp() {
const helpOverlay = document.getElementById('help-overlay');
if (helpOverlay) {
helpOverlay.classList.toggle('active');
}
}
closeHelp() {
const helpOverlay = document.getElementById('help-overlay');
if (helpOverlay) {
helpOverlay.classList.remove('active');
}
}
toggleFullscreen() {
if (!document.fullscreenElement) {
this.enterFullscreen();
} else {
this.exitFullscreen();
}
}
enterFullscreen() {
const elem = document.documentElement;
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.webkitRequestFullscreen) { /* Safari */
elem.webkitRequestFullscreen();
} else if (elem.msRequestFullscreen) { /* IE11 */
elem.msRequestFullscreen();
}
}
exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) { /* Safari */
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) { /* IE11 */
document.msExitFullscreen();
}
}
}
// Initialize presentation when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
window.presentation = new Presentation();
});
// Prevent default scroll behavior
document.addEventListener('wheel', (e) => {
if (Math.abs(e.deltaY) > 50) {
e.preventDefault();
if (e.deltaY > 0) {
window.presentation.nextSlide();
} else {
window.presentation.prevSlide();
}
}
}, { passive: false });