alexdatamed's picture
Upload 3 files
b7d30d9 verified
class PresentationController {
constructor() {
this.currentSlide = 1;
this.totalSlides = 12;
this.slides = document.querySelectorAll('.slide');
this.prevBtn = document.getElementById('prevBtn');
this.nextBtn = document.getElementById('nextBtn');
this.currentSlideSpan = document.getElementById('currentSlide');
this.totalSlidesSpan = document.getElementById('totalSlides');
this.isTransitioning = false;
this.init();
}
init() {
// Set total slides
this.totalSlidesSpan.textContent = this.totalSlides;
// Add event listeners
this.prevBtn.addEventListener('click', () => this.previousSlide());
this.nextBtn.addEventListener('click', () => this.nextSlide());
// Keyboard navigation
document.addEventListener('keydown', (e) => this.handleKeyboard(e));
// Initialize first slide
this.showSlide(1);
// Initialize progress bar
this.initProgressBar();
console.log('Presentation initialized with', this.totalSlides, 'slides');
}
initProgressBar() {
// Create and add progress bar
const progressBar = document.createElement('div');
progressBar.className = 'progress-bar';
progressBar.innerHTML = '<div class="progress-fill"></div>';
document.body.insertBefore(progressBar, document.body.firstChild);
this.progressBar = progressBar;
this.updateProgress();
}
showSlide(slideNumber) {
if (slideNumber < 1 || slideNumber > this.totalSlides || this.isTransitioning) {
return;
}
this.isTransitioning = true;
// Hide all slides
this.slides.forEach(slide => {
slide.classList.remove('active', 'exiting');
slide.style.opacity = '0';
slide.style.visibility = 'hidden';
slide.style.transform = 'translateX(50px)';
});
// Update current slide
this.currentSlide = slideNumber;
// Show target slide with a small delay to ensure clean transition
setTimeout(() => {
const targetSlide = document.querySelector(`[data-slide="${slideNumber}"]`);
if (targetSlide) {
targetSlide.style.visibility = 'visible';
targetSlide.classList.add('active');
// Force a repaint
targetSlide.offsetHeight;
targetSlide.style.opacity = '1';
targetSlide.style.transform = 'translateX(0)';
}
// Update UI elements
this.updateButtonStates();
this.updateSlideCounter();
this.updateProgress();
// Allow next transition after animation completes
setTimeout(() => {
this.isTransitioning = false;
}, 450);
}, 50);
}
nextSlide() {
if (this.currentSlide < this.totalSlides && !this.isTransitioning) {
this.showSlide(this.currentSlide + 1);
}
}
previousSlide() {
if (this.currentSlide > 1 && !this.isTransitioning) {
this.showSlide(this.currentSlide - 1);
}
}
updateButtonStates() {
// Update previous button
this.prevBtn.disabled = (this.currentSlide === 1);
// Update next button
this.nextBtn.disabled = (this.currentSlide === this.totalSlides);
}
updateSlideCounter() {
this.currentSlideSpan.textContent = this.currentSlide;
}
updateProgress() {
if (this.progressBar) {
const progressFill = this.progressBar.querySelector('.progress-fill');
const percentage = (this.currentSlide / this.totalSlides) * 100;
progressFill.style.width = `${percentage}%`;
}
}
handleKeyboard(e) {
// Prevent default behavior for navigation keys
if (['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(e.key)) {
e.preventDefault();
}
switch(e.key) {
case 'ArrowLeft':
this.previousSlide();
break;
case 'ArrowRight':
this.nextSlide();
break;
case 'Home':
this.showSlide(1);
break;
case 'End':
this.showSlide(this.totalSlides);
break;
case 'f':
case 'F':
this.toggleFullscreen();
break;
case 'Escape':
this.exitFullscreen();
break;
}
}
toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(err => {
console.log(`Error attempting to enable fullscreen: ${err.message}`);
});
} else {
document.exitFullscreen();
}
}
exitFullscreen() {
if (document.fullscreenElement) {
document.exitFullscreen();
}
}
}
// Touch/swipe support for mobile
class TouchHandler {
constructor(controller) {
this.controller = controller;
this.touchStartX = 0;
this.touchEndX = 0;
this.minSwipeDistance = 50;
this.init();
}
init() {
const slidesContainer = document.getElementById('slidesContainer');
slidesContainer.addEventListener('touchstart', (e) => {
this.touchStartX = e.changedTouches[0].screenX;
}, { passive: true });
slidesContainer.addEventListener('touchend', (e) => {
this.touchEndX = e.changedTouches[0].screenX;
this.handleSwipe();
}, { passive: true });
}
handleSwipe() {
const diffX = this.touchStartX - this.touchEndX;
if (Math.abs(diffX) > this.minSwipeDistance) {
if (diffX > 0) {
// Swipe left - next slide
this.controller.nextSlide();
} else {
// Swipe right - previous slide
this.controller.previousSlide();
}
}
}
}
// Simple hover effects without problematic animations
function addHoverEffects() {
const style = document.createElement('style');
style.textContent = `
.tech-card:hover,
.company-card:hover,
.use-case-card:hover,
.challenge-card:hover,
.trend-item:hover,
.takeaway-card:hover {
background: rgba(255, 255, 255, 0.15) !important;
cursor: pointer;
}
`;
document.head.appendChild(style);
}
// Initialize presentation when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
// Prevent scrolling and ensure proper viewport
document.body.style.overflow = 'hidden';
document.body.style.margin = '0';
document.body.style.padding = '0';
document.documentElement.style.overflow = 'hidden';
// Initialize the presentation controller
const presentation = new PresentationController();
// Add touch support
new TouchHandler(presentation);
// Add simple hover effects
addHoverEffects();
// Prevent default scrolling behavior
document.addEventListener('wheel', (e) => {
e.preventDefault();
}, { passive: false });
// Prevent arrow key scrolling
document.addEventListener('keydown', (e) => {
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Space'].includes(e.key)) {
e.preventDefault();
}
});
// Handle window resize
window.addEventListener('resize', () => {
// Force a repaint to handle responsive changes
const activeSlide = document.querySelector('.slide.active');
if (activeSlide) {
activeSlide.style.height = '100%';
}
});
console.log('Presentation ready');
});
// Export controller for debugging
window.PresentationController = PresentationController;