diff options
Diffstat (limited to 'html/cards/index.html')
-rw-r--r-- | html/cards/index.html | 228 |
1 files changed, 1 insertions, 227 deletions
diff --git a/html/cards/index.html b/html/cards/index.html index 537920b..4e38953 100644 --- a/html/cards/index.html +++ b/html/cards/index.html @@ -17,232 +17,6 @@ </head> <body> <canvas id="cards"></canvas> - <script> - // Constants - const CARD_WIDTH = 100; - const CARD_HEIGHT = 150; - const PADDING = 10; - const SUITS = ['❤️', '♦️', '♣️', '♠️']; - const VALUES = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']; - const CARD_BACK_COLOR = '#0066cc'; - const PATTERN_SIZE = 10; - - // Canvas setup - const canvas = document.getElementById('cards'); - const ctx = canvas.getContext('2d'); - canvas.width = window.innerWidth; - canvas.height = window.innerHeight; - - // Pure functions - const shuffle = array => [...array] - .reduce((acc, _, i) => { - const j = Math.floor(Math.random() * (i + 1)); - [acc[i], acc[j]] = [acc[j], acc[i]]; - return acc; - }, [...array]); - - const createDeck = () => - SUITS.flatMap(suit => VALUES.map(value => ({ suit, value }))); - - const createCard = (x, y, cardData) => ({ - x: x + 20, - y: y + 20, - card: cardData, - isFaceUp: false // Cards start face down - }); - - const isPointInCard = (x, y, card) => - x >= card.x && - x <= card.x + CARD_WIDTH && - y >= card.y && - y <= card.y + CARD_HEIGHT; - - // Rendering functions - const clearCanvas = () => { - ctx.fillStyle = 'beige'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - }; - - const renderCardBack = card => { - // Draw blue background - ctx.fillStyle = CARD_BACK_COLOR; - ctx.fillRect(card.x, card.y, CARD_WIDTH, CARD_HEIGHT); - - // Draw checkered pattern - ctx.strokeStyle = '#003366'; - for (let i = 0; i < CARD_WIDTH; i += PATTERN_SIZE) { - for (let j = 0; j < CARD_HEIGHT; j += PATTERN_SIZE) { - if ((i + j) % (PATTERN_SIZE * 2) === 0) { - ctx.fillStyle = '#0055aa'; - ctx.fillRect(card.x + i, card.y + j, PATTERN_SIZE, PATTERN_SIZE); - } - } - } - - // Draw border - ctx.strokeStyle = 'black'; - ctx.strokeRect(card.x, card.y, CARD_WIDTH, CARD_HEIGHT); - }; - - const renderCardFront = card => { - ctx.fillStyle = 'white'; - ctx.fillRect(card.x, card.y, CARD_WIDTH, CARD_HEIGHT); - ctx.fillStyle = 'black'; - ctx.font = '20px Arial'; - ctx.strokeRect(card.x, card.y, CARD_WIDTH, CARD_HEIGHT); - ctx.fillText(card.card.value, card.x + 10, card.y + 30); - ctx.fillText(card.card.suit, card.x + 10, card.y + 60); - }; - - const renderCard = card => { - if (card.isFaceUp) { - renderCardFront(card); - } else { - renderCardBack(card); - } - }; - - const renderAllCards = cards => { - clearCanvas(); - cards.forEach(renderCard); - }; - - // State management - const gameState = { - cards: [], - draggingCard: null, - deck: shuffle(createDeck()), - stackPosition: { - x: 0, - y: 0 - } - }; - - // Add function to get top card - const getTopStackCard = () => { - return gameState.cards.find(card => - card.x === gameState.stackPosition.x && - card.y === gameState.stackPosition.y - ); - }; - - // Event handlers - const handleMouseMove = e => { - if (!gameState.draggingCard) return; - - const rect = canvas.getBoundingClientRect(); - gameState.draggingCard.x = e.clientX - rect.left; - gameState.draggingCard.y = e.clientY - rect.top; - - renderAllCards(gameState.cards); - }; - - const handleMouseUp = () => { - gameState.draggingCard = null; - document.removeEventListener('mousemove', handleMouseMove); - document.removeEventListener('mouseup', handleMouseUp); - }; - - // Add this function to distribute cards evenly with overlap - const distributeCards = () => { - const totalCards = gameState.cards.length; - const cols = Math.floor((canvas.width - 20) / (CARD_WIDTH / 2)); // Allow overlap by halving the width and accounting for border - const rows = Math.ceil(totalCards / cols); // Calculate number of rows - - const cardWidthWithPadding = CARD_WIDTH / 2; // Allow overlap - const cardHeightWithPadding = CARD_HEIGHT / 2; // Allow overlap - - // Calculate starting positions - const startX = 20 + (canvas.width - (cols * cardWidthWithPadding)) / 2; // Start from 20 pixels from the left - const startY = 20 + (canvas.height - (rows * cardHeightWithPadding)) / 2; // Start from 20 pixels from the top - - // Distribute cards - gameState.cards.forEach((card, index) => { - const row = Math.floor(index / cols); - const col = index % cols; - card.x = startX + col * cardWidthWithPadding + (Math.random() * 20 - 10); // Random offset for overlap - card.y = startY + row * cardHeightWithPadding + (Math.random() * 20 - 10); // Random offset for overlap - card.isFaceUp = true; // Flip cards face up when distributed - }); - - renderAllCards(gameState.cards); - }; - - // Update handleMouseDown to include double-click detection - let lastClickTime = 0; - const handleMouseDown = e => { - const rect = canvas.getBoundingClientRect(); - const x = e.clientX - rect.left; - const y = e.clientY - rect.top; - - // Handle right click for card flipping - if (e.button === 2) { // Right click - e.preventDefault(); - const clickedCard = gameState.cards.find(card => - isPointInCard(x, y, card) && - (card.x !== gameState.stackPosition.x || card.y !== gameState.stackPosition.y) - ); - if (clickedCard) { - clickedCard.isFaceUp = !clickedCard.isFaceUp; - renderAllCards(gameState.cards); - } - return; - } - - // Check for double-click - const currentTime = new Date().getTime(); - if (currentTime - lastClickTime < 300) { // 300 ms for double-click - distributeCards(); // Show all cards when double-clicked - lastClickTime = 0; // Reset last click time - return; - } - lastClickTime = currentTime; - - // Find any clicked card - const clickedCard = gameState.cards.find(card => isPointInCard(x, y, card)); - - if (clickedCard) { - // If it's a card in the stack, handle drawing it - if (clickedCard.x === gameState.stackPosition.x && - clickedCard.y === gameState.stackPosition.y) { - clickedCard.isFaceUp = true; - } - - // Allow dragging regardless of where the card is - gameState.draggingCard = clickedCard; - document.addEventListener('mousemove', handleMouseMove); - document.addEventListener('mouseup', handleMouseUp); - } - }; - - // Initialize game - const initializeGame = () => { - // Create a full deck of cards - gameState.deck = shuffle(createDeck()); // Ensure we have a full deck - gameState.cards = gameState.deck.map(cardData => createCard(0, 0, cardData)); // Create cards with initial position (0, 0) - - // Draw cards in a pile with their reverse side showing - gameState.cards.forEach((card, index) => { - card.x = 20; // Pile at 20 pixels from the left - card.y = 20 + index * 5; // Stack cards with a slight offset for visibility - }); - - clearCanvas(); - renderAllCards(gameState.cards); - - // Add event listeners - canvas.addEventListener('mousedown', handleMouseDown); - canvas.addEventListener('contextmenu', e => e.preventDefault()); - }; - - // Start the game - initializeGame(); - - // Clean up on window unload - window.addEventListener('unload', () => { - canvas.removeEventListener('mousedown', handleMouseDown); - canvas.removeEventListener('contextmenu', e => e.preventDefault()); - }); - </script> + <script src="script.js"></script> </body> </html> \ No newline at end of file |