/** * Fallback Swipe Card Component * Simple swipe implementation for compatibility mode */ export default class FallbackSwipeCard { constructor(options = {}) { this.container = options.container || document.querySelector('.swipe-container'); this.onSwipe = options.onSwipe || (() => {}); this.threshold = options.threshold || 100; this.state = { isDragging: false, startX: 0, startY: 0, moveX: 0, moveY: 0, hasMoved: false, currentImageInfo: null }; this.card = null; this.init(); } init() { this.card = this.container.querySelector('.image-card') || this.createCardElement(); this.addEventListeners(); console.log('FallbackSwipeCard initialized'); } createCardElement() { const card = document.createElement('div'); card.className = 'image-card'; card.id = 'current-card'; card.setAttribute('role', 'img'); card.setAttribute('aria-label', 'Image to be swiped'); const img = document.createElement('img'); img.src = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22400%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Crect%20width%3D%22400%22%20height%3D%22400%22%20fill%3D%22%23e0e0e0%22%2F%3E%3Ctext%20x%3D%22200%22%20y%3D%22200%22%20font-size%3D%2220%22%20text-anchor%3D%22middle%22%20alignment-baseline%3D%22middle%22%20fill%3D%22%23999%22%3ELoading...%3C%2Ftext%3E%3C%2Fsvg%3E'; img.alt = 'Image'; const loadingIndicator = document.createElement('div'); loadingIndicator.className = 'loading-indicator'; loadingIndicator.textContent = 'Loading...'; card.appendChild(img); card.appendChild(loadingIndicator); this.container.appendChild(card); return card; } addEventListeners() { // Mouse events this.card.addEventListener('mousedown', (e) => this.handlePointerDown(e.clientX, e.clientY)); document.addEventListener('mousemove', (e) => this.handlePointerMove(e.clientX, e.clientY)); document.addEventListener('mouseup', () => this.handlePointerUp()); // Touch events this.card.addEventListener('touchstart', (e) => { const touch = e.touches[0]; this.handlePointerDown(touch.clientX, touch.clientY); }, { passive: true }); this.card.addEventListener('touchmove', (e) => { const touch = e.touches[0]; this.handlePointerMove(touch.clientX, touch.clientY); }, { passive: true }); this.card.addEventListener('touchend', () => this.handlePointerUp()); } handlePointerDown(x, y) { this.state.isDragging = true; this.state.startX = x; this.state.startY = y; this.state.hasMoved = false; this.card.classList.add('swiping'); } handlePointerMove(x, y) { if (!this.state.isDragging) return; this.state.moveX = x - this.state.startX; this.state.moveY = y - this.state.startY; if (Math.abs(this.state.moveX) > 10 || Math.abs(this.state.moveY) > 10) { this.state.hasMoved = true; } // Simple transform without physics this.card.style.transform = `translate(${this.state.moveX}px, ${this.state.moveY}px) rotate(${this.state.moveX * 0.05}deg)`; } handlePointerUp() { if (!this.state.isDragging) return; this.state.isDragging = false; this.card.classList.remove('swiping'); const absX = Math.abs(this.state.moveX); const absY = Math.abs(this.state.moveY); if (this.state.hasMoved && (absX > this.threshold || absY > this.threshold)) { let direction; if (absX > absY) { direction = this.state.moveX > 0 ? 'right' : 'left'; } else { direction = this.state.moveY > 0 ? 'down' : 'up'; } this.performSwipe(direction); } else { // Reset position this.card.style.transition = 'transform 0.3s ease'; this.card.style.transform = ''; setTimeout(() => { this.card.style.transition = ''; }, 300); } this.state.moveX = 0; this.state.moveY = 0; } performSwipe(direction) { this.card.classList.add(`swipe-${direction}`); this.onSwipe(direction); setTimeout(() => { this.card.classList.remove(`swipe-${direction}`); this.card.style.transform = ''; }, 500); } setImage(imageInfo) { this.state.currentImageInfo = imageInfo; if (!imageInfo) { this.card.innerHTML = '
No more images available.
'; return; } const cardImage = this.card.querySelector('img'); if (cardImage) { cardImage.src = imageInfo.path; } } showLoading() { this.card.classList.add('loading'); } hideLoading() { this.card.classList.remove('loading'); } destroy() { // Remove event listeners this.card.removeEventListener('mousedown', this.handlePointerDown); document.removeEventListener('mousemove', this.handlePointerMove); document.removeEventListener('mouseup', this.handlePointerUp); // Clean up this.card = null; } }