Spaces:
Running
Running
| document.addEventListener("DOMContentLoaded", function () { | |
| const cardContainer = document.getElementById('cardContainer'); | |
| const shuffleButton = document.getElementById('shuffleButton'); | |
| const cardData = Array.from({ length: 22 }, (_, i) => `images/card-front-${i + 1}.png`); | |
| let cards = []; | |
| let cardAnimations = new Map(); | |
| let enlargedCard = null; | |
| let zIndexCounter = 1; | |
| function createCardElement(cardImage) { | |
| const card = document.createElement('div'); | |
| card.className = 'card'; | |
| card.style.top = `${Math.random() * (cardContainer.clientHeight - 170)}px`; | |
| card.style.left = `${Math.random() * (cardContainer.clientWidth - 100)}px`; | |
| const front = document.createElement('div'); | |
| front.className = 'front'; | |
| front.style.backgroundImage = `url(${cardImage})`; | |
| const back = document.createElement('div'); | |
| back.className = 'back'; | |
| back.style.backgroundImage = `url(images/card-back.png)`; | |
| card.appendChild(front); | |
| card.appendChild(back); | |
| card.classList.add('flipped'); // Start with the back side visible | |
| card.addEventListener('click', () => { | |
| // Stop movement | |
| const animationId = cardAnimations.get(card); | |
| if (animationId) { | |
| cancelAnimationFrame(animationId); | |
| cardAnimations.delete(card); | |
| } | |
| // Bring the clicked card to the front | |
| card.style.zIndex = zIndexCounter++; | |
| // If card is already enlarged, reduce it | |
| if (enlargedCard === card) { | |
| card.style.transition = 'transform 0.6s, width 0.6s, height 0.6s, top 0.6s, left 0.6s'; | |
| card.style.transform = ''; | |
| card.style.width = '100px'; | |
| card.style.height = '170px'; | |
| card.style.top = card.originalTop; | |
| card.style.left = card.originalLeft; | |
| setTimeout(() => { | |
| card.classList.toggle('flipped'); | |
| card.style.transition = ''; | |
| moveCard(card); // Restart movement | |
| }, 600); | |
| enlargedCard = null; | |
| } else { | |
| // Enlarge card | |
| card.originalTop = card.style.top; | |
| card.originalLeft = card.style.left; | |
| card.style.transition = 'transform 0.6s, width 0.6s, height 0.6s, top 0.6s, left 0.6s'; | |
| const newWidth = card.clientWidth * 3; | |
| const newHeight = card.clientHeight * 3; | |
| const newLeft = (cardContainer.clientWidth - newWidth) / 2; | |
| const newTop = (cardContainer.clientHeight - newHeight) / 2; | |
| card.style.width = `${newWidth}px`; | |
| card.style.height = `${newHeight}px`; | |
| card.style.top = `${newTop}px`; | |
| card.style.left = `${newLeft}px`; | |
| setTimeout(() => { | |
| card.classList.toggle('flipped'); | |
| card.style.transform = ''; | |
| card.style.transition = ''; | |
| }, 600); | |
| enlargedCard = card; | |
| } | |
| }); | |
| // Drag functionality | |
| let offsetX, offsetY; | |
| let isDragging = false; | |
| card.addEventListener('mousedown', (e) => { | |
| isDragging = true; | |
| card.style.cursor = 'grabbing'; | |
| const rect = card.getBoundingClientRect(); | |
| offsetX = e.clientX - rect.left; | |
| offsetY = e.clientY - rect.top; | |
| card.classList.add('dragging'); | |
| }); | |
| document.addEventListener('mousemove', (e) => { | |
| if (isDragging) { | |
| card.style.left = `${e.clientX - offsetX}px`; | |
| card.style.top = `${e.clientY - offsetY}px`; | |
| } | |
| }); | |
| document.addEventListener('mouseup', () => { | |
| if (isDragging) { | |
| isDragging = false; | |
| card.classList.remove('dragging'); | |
| card.style.cursor = 'grab'; | |
| } | |
| }); | |
| cardContainer.appendChild(card); | |
| return card; | |
| } | |
| function moveCard(card) { | |
| let xDirection = Math.random() > 0.5 ? 1 : -1; | |
| let yDirection = Math.random() > 0.5 ? 1 : -1; | |
| let xSpeed = Math.random() * 0.5 + 0.1; // Slower speed | |
| let ySpeed = Math.random() * 0.5 + 0.1; // Slower speed | |
| function updatePosition() { | |
| const rect = card.getBoundingClientRect(); | |
| if (rect.left <= 0 || rect.right >= cardContainer.clientWidth) { | |
| xDirection *= -1; | |
| } | |
| if (rect.top <= 0 || rect.bottom >= cardContainer.clientHeight) { | |
| yDirection *= -1; | |
| } | |
| card.style.left = `${card.offsetLeft + xSpeed * xDirection}px`; | |
| card.style.top = `${card.offsetTop + ySpeed * yDirection}px`; | |
| const animationId = requestAnimationFrame(updatePosition); | |
| cardAnimations.set(card, animationId); | |
| } | |
| updatePosition(); | |
| } | |
| function shuffleCards() { | |
| cards.forEach(card => { | |
| // Cancel current animation | |
| const animationId = cardAnimations.get(card); | |
| if (animationId) { | |
| cancelAnimationFrame(animationId); | |
| cardAnimations.delete(card); | |
| } | |
| // Set new random position | |
| card.style.transition = 'left 0.5s, top 0.5s'; | |
| card.style.left = `${Math.random() * (cardContainer.clientWidth - 100)}px`; | |
| card.style.top = `${Math.random() * (cardContainer.clientHeight - 180)}px`; | |
| // Restart animation after position change | |
| setTimeout(() => { | |
| card.style.transition = ''; // Remove transition after moving | |
| moveCard(card); | |
| }, 500); // Wait for the transition to finish before restarting animation | |
| }); | |
| } | |
| function initializeCards() { | |
| while (cardContainer.firstChild) { | |
| cardContainer.removeChild(cardContainer.firstChild); | |
| } | |
| cards = cardData.map(createCardElement); | |
| shuffleCards(); | |
| } | |
| shuffleButton.addEventListener('click', shuffleCards); | |
| initializeCards(); | |
| }); | |