Last active
June 24, 2025 22:23
-
-
Save dabd/bcbdf065e7360717492c3d761ec93aa9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | |
| <title>Big Book of Words</title> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| -webkit-tap-highlight-color: transparent; | |
| user-select: none; | |
| } | |
| body { | |
| font-family: 'Comic Sans MS', 'Arial Rounded MT Bold', Arial, sans-serif; | |
| height: 100vh; | |
| overflow: hidden; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| position: relative; | |
| } | |
| /* Animated background elements */ | |
| .bg-decoration { | |
| position: absolute; | |
| opacity: 0.1; | |
| animation: float 20s infinite ease-in-out; | |
| } | |
| .star { | |
| width: 30px; | |
| height: 30px; | |
| background: white; | |
| clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); | |
| } | |
| @keyframes float { | |
| 0%, 100% { transform: translateY(0) rotate(0deg); } | |
| 50% { transform: translateY(-20px) rotate(180deg); } | |
| } | |
| .main-container { | |
| text-align: center; | |
| width: 90%; | |
| max-width: 400px; | |
| padding: 20px; | |
| } | |
| h1 { | |
| color: white; | |
| font-size: 2.5em; | |
| margin-bottom: 30px; | |
| text-shadow: 3px 3px 6px rgba(0,0,0,0.3); | |
| animation: bounce 2s infinite; | |
| } | |
| @keyframes bounce { | |
| 0%, 100% { transform: translateY(0); } | |
| 50% { transform: translateY(-10px); } | |
| } | |
| .button-container { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 20px; | |
| margin-bottom: 30px; | |
| } | |
| .game-button { | |
| background: #ff4444; | |
| color: white; | |
| border: none; | |
| padding: 25px 40px; | |
| font-size: 1.3em; | |
| font-weight: bold; | |
| border-radius: 50px; | |
| cursor: pointer; | |
| box-shadow: 0 8px 0 #cc0000, 0 10px 20px rgba(0,0,0,0.3); | |
| transition: all 0.1s; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .game-button:active { | |
| transform: translateY(4px); | |
| box-shadow: 0 4px 0 #cc0000, 0 5px 10px rgba(0,0,0,0.3); | |
| } | |
| .game-button:hover { | |
| background: #ff5555; | |
| } | |
| /* Slot machine display */ | |
| .slot-machine { | |
| display: none; | |
| background: white; | |
| border-radius: 20px; | |
| padding: 30px; | |
| box-shadow: 0 10px 30px rgba(0,0,0,0.3); | |
| margin-bottom: 20px; | |
| } | |
| .slot-display { | |
| font-size: 4em; | |
| font-weight: bold; | |
| color: #333; | |
| min-height: 100px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| background: #f0f0f0; | |
| border-radius: 15px; | |
| padding: 20px; | |
| margin: 20px 0; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .slot-number { | |
| animation: slotRoll 0.1s; | |
| } | |
| @keyframes slotRoll { | |
| 0% { transform: translateY(-100%); opacity: 0; } | |
| 100% { transform: translateY(0); opacity: 1; } | |
| } | |
| .rolling { | |
| animation: roll 0.1s infinite; | |
| } | |
| @keyframes roll { | |
| 0% { transform: translateY(0); } | |
| 100% { transform: translateY(-20px); } | |
| } | |
| .back-button { | |
| background: #4CAF50; | |
| color: white; | |
| border: none; | |
| padding: 15px 30px; | |
| font-size: 1.1em; | |
| font-weight: bold; | |
| border-radius: 30px; | |
| cursor: pointer; | |
| box-shadow: 0 5px 0 #388E3C, 0 7px 15px rgba(0,0,0,0.2); | |
| transition: all 0.1s; | |
| } | |
| .back-button:active { | |
| transform: translateY(3px); | |
| box-shadow: 0 2px 0 #388E3C, 0 3px 8px rgba(0,0,0,0.2); | |
| } | |
| /* Image display for game mode 2 */ | |
| .image-display { | |
| width: 200px; | |
| height: 200px; | |
| background: #f0f0f0; | |
| border-radius: 15px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| margin: 0 auto; | |
| font-size: 3em; | |
| } | |
| .image-display img { | |
| max-width: 100%; | |
| max-height: 100%; | |
| border-radius: 10px; | |
| } | |
| /* Confetti animation */ | |
| .confetti { | |
| position: fixed; | |
| width: 10px; | |
| height: 10px; | |
| background: #ff4444; | |
| position: absolute; | |
| animation: confettiFall 3s linear; | |
| } | |
| @keyframes confettiFall { | |
| 0% { | |
| transform: translateY(-100vh) rotate(0deg); | |
| opacity: 1; | |
| } | |
| 100% { | |
| transform: translateY(100vh) rotate(720deg); | |
| opacity: 0; | |
| } | |
| } | |
| /* Audio controls */ | |
| .sound-toggle { | |
| position: absolute; | |
| top: 20px; | |
| right: 20px; | |
| background: rgba(255,255,255,0.3); | |
| border: none; | |
| border-radius: 50%; | |
| width: 50px; | |
| height: 50px; | |
| cursor: pointer; | |
| font-size: 1.5em; | |
| color: white; | |
| transition: all 0.3s; | |
| } | |
| .sound-toggle:hover { | |
| background: rgba(255,255,255,0.5); | |
| transform: scale(1.1); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Background decorations --> | |
| <div class="bg-decoration star" style="top: 10%; left: 10%;"></div> | |
| <div class="bg-decoration star" style="top: 20%; right: 15%; animation-delay: -5s;"></div> | |
| <div class="bg-decoration star" style="bottom: 30%; left: 20%; animation-delay: -10s;"></div> | |
| <div class="bg-decoration star" style="bottom: 20%; right: 10%; animation-delay: -15s;"></div> | |
| <!-- Sound toggle button --> | |
| <button class="sound-toggle" onclick="toggleSound()">๐</button> | |
| <!-- Main menu --> | |
| <div id="mainMenu" class="main-container"> | |
| <h1>Big Book of Words</h1> | |
| <div class="button-container"> | |
| <button class="game-button" onclick="startGame(1)">Find the Page</button> | |
| <button class="game-button" onclick="startGame(2)">Find the Image</button> | |
| </div> | |
| </div> | |
| <!-- Game display --> | |
| <div id="gameDisplay" class="main-container" style="display: none;"> | |
| <div class="slot-machine"> | |
| <h2 id="gameTitle" style="color: #333; margin-bottom: 20px;"></h2> | |
| <div id="slotDisplay" class="slot-display"> | |
| <span id="slotContent"></span> | |
| </div> | |
| </div> | |
| <button class="back-button" onclick="backToMenu()">Back to Menu</button> | |
| </div> | |
| <script> | |
| // Sound effects using Web Audio API | |
| let audioContext; | |
| let soundEnabled = true; | |
| function initAudio() { | |
| if (!audioContext) { | |
| audioContext = new (window.AudioContext || window.webkitAudioContext)(); | |
| } | |
| } | |
| function playSound(type) { | |
| if (!soundEnabled) return; | |
| initAudio(); | |
| const oscillator = audioContext.createOscillator(); | |
| const gainNode = audioContext.createGain(); | |
| oscillator.connect(gainNode); | |
| gainNode.connect(audioContext.destination); | |
| switch(type) { | |
| case 'click': | |
| oscillator.frequency.setValueAtTime(800, audioContext.currentTime); | |
| oscillator.frequency.exponentialRampToValueAtTime(400, audioContext.currentTime + 0.1); | |
| gainNode.gain.setValueAtTime(0.3, audioContext.currentTime); | |
| gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.1); | |
| oscillator.start(audioContext.currentTime); | |
| oscillator.stop(audioContext.currentTime + 0.1); | |
| break; | |
| case 'roll': | |
| oscillator.frequency.setValueAtTime(200 + Math.random() * 200, audioContext.currentTime); | |
| gainNode.gain.setValueAtTime(0.1, audioContext.currentTime); | |
| gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.05); | |
| oscillator.start(audioContext.currentTime); | |
| oscillator.stop(audioContext.currentTime + 0.05); | |
| break; | |
| case 'win': | |
| oscillator.frequency.setValueAtTime(523.25, audioContext.currentTime); // C5 | |
| oscillator.frequency.setValueAtTime(659.25, audioContext.currentTime + 0.1); // E5 | |
| oscillator.frequency.setValueAtTime(783.99, audioContext.currentTime + 0.2); // G5 | |
| gainNode.gain.setValueAtTime(0.3, audioContext.currentTime); | |
| gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.5); | |
| oscillator.start(audioContext.currentTime); | |
| oscillator.stop(audioContext.currentTime + 0.5); | |
| break; | |
| } | |
| } | |
| function toggleSound() { | |
| soundEnabled = !soundEnabled; | |
| document.querySelector('.sound-toggle').textContent = soundEnabled ? '๐' : '๐'; | |
| } | |
| // Excluded pages (example set - you can modify this) | |
| const excludedPages = new Set([100, 150, 200, 250, 300, 350, 400]); | |
| // Sample images for demo (replace with actual images) | |
| const sampleImages = [ | |
| '๐ถ', '๐ฑ', '๐ญ', '๐น', '๐ฐ', '๐ฆ', '๐ป', '๐ผ', '๐จ', '๐ฏ', | |
| '๐ฆ', '๐ฎ', '๐ท', '๐ธ', '๐ต', '๐', '๐ง', '๐ฆ', '๐ค', '๐ฆ', | |
| '๐ฆ ', '๐ฆ', '๐ฆ', '๐บ', '๐', '๐ด', '๐ฆ', '๐', '๐', '๐ฆ', | |
| '๐', '๐', '๐', '๐ฆ', '๐ฆ', '๐ฆ', '๐ข', '๐', '๐ฆ', '๐ฆ', | |
| '๐ฆ', '๐', '๐ฆ', '๐ฆ', '๐ฆ', '๐ฆ', '๐ก', '๐ ', '๐', '๐ฌ' | |
| ]; | |
| let currentGame = 0; | |
| let isRolling = false; | |
| function startGame(gameMode) { | |
| playSound('click'); | |
| currentGame = gameMode; | |
| document.getElementById('mainMenu').style.display = 'none'; | |
| document.getElementById('gameDisplay').style.display = 'block'; | |
| const gameTitle = gameMode === 1 ? 'Find the Page' : 'Find the Image'; | |
| document.getElementById('gameTitle').textContent = gameTitle; | |
| // Reset display | |
| document.getElementById('slotContent').textContent = '?'; | |
| document.querySelector('.slot-machine').style.display = 'block'; | |
| // Start rolling after a short delay | |
| setTimeout(() => rollSlotMachine(), 300); | |
| } | |
| function rollSlotMachine() { | |
| if (isRolling) return; | |
| isRolling = true; | |
| const slotContent = document.getElementById('slotContent'); | |
| const duration = 3000; // 3 seconds of rolling | |
| const interval = 100; // Update every 100ms | |
| let elapsed = 0; | |
| const rollInterval = setInterval(() => { | |
| elapsed += interval; | |
| playSound('roll'); | |
| if (currentGame === 1) { | |
| // Generate random page number | |
| let randomPage; | |
| do { | |
| randomPage = Math.floor(Math.random() * (458 - 7 + 1)) + 7; | |
| } while (excludedPages.has(randomPage)); | |
| slotContent.textContent = randomPage; | |
| slotContent.className = 'slot-number'; | |
| } else { | |
| // Show random image | |
| const randomImage = sampleImages[Math.floor(Math.random() * sampleImages.length)]; | |
| slotContent.innerHTML = `<span style="font-size: 2em;">${randomImage}</span>`; | |
| slotContent.className = 'slot-number'; | |
| } | |
| // Slow down near the end | |
| if (elapsed >= duration - 1000) { | |
| clearInterval(rollInterval); | |
| setTimeout(() => { | |
| finalRoll(); | |
| }, 200); | |
| } | |
| }, interval); | |
| } | |
| function finalRoll() { | |
| const slotContent = document.getElementById('slotContent'); | |
| let finalResult; | |
| if (currentGame === 1) { | |
| // Final page number | |
| do { | |
| finalResult = Math.floor(Math.random() * (458 - 7 + 1)) + 7; | |
| } while (excludedPages.has(finalResult)); | |
| slotContent.textContent = finalResult; | |
| } else { | |
| // Final image | |
| finalResult = sampleImages[Math.floor(Math.random() * sampleImages.length)]; | |
| slotContent.innerHTML = `<span style="font-size: 2em;">${finalResult}</span>`; | |
| } | |
| playSound('win'); | |
| createConfetti(); | |
| isRolling = false; | |
| } | |
| function createConfetti() { | |
| const colors = ['#ff4444', '#44ff44', '#4444ff', '#ffff44', '#ff44ff', '#44ffff']; | |
| for (let i = 0; i < 50; i++) { | |
| setTimeout(() => { | |
| const confetti = document.createElement('div'); | |
| confetti.className = 'confetti'; | |
| confetti.style.left = Math.random() * 100 + '%'; | |
| confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; | |
| confetti.style.transform = `rotate(${Math.random() * 360}deg)`; | |
| document.body.appendChild(confetti); | |
| setTimeout(() => confetti.remove(), 3000); | |
| }, i * 50); | |
| } | |
| } | |
| function backToMenu() { | |
| playSound('click'); | |
| document.getElementById('gameDisplay').style.display = 'none'; | |
| document.getElementById('mainMenu').style.display = 'block'; | |
| currentGame = 0; | |
| } | |
| // Handle orientation change | |
| window.addEventListener('orientationchange', () => { | |
| setTimeout(() => { | |
| window.scrollTo(0, 0); | |
| }, 500); | |
| }); | |
| // Prevent zoom on double tap | |
| let lastTouchEnd = 0; | |
| document.addEventListener('touchend', (event) => { | |
| const now = Date.now(); | |
| if (now - lastTouchEnd <= 300) { | |
| event.preventDefault(); | |
| } | |
| lastTouchEnd = now; | |
| }, false); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment