mlmihjaz commited on
Commit
4796a88
·
verified ·
1 Parent(s): de31d03

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +581 -19
index.html CHANGED
@@ -1,19 +1,581 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Alphabet Pop! Interactive Learning Game</title>
7
+
8
+ <!-- Import Google Fonts for a playful look -->
9
+ <link rel="preconnect" href="https://fonts.googleapis.com">
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
+ <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600;700&family=Nunito:wght@400;700&display=swap" rel="stylesheet">
12
+
13
+ <!-- FontAwesome for Icons -->
14
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
15
+
16
+ <style>
17
+ :root {
18
+ --primary-color: #6C63FF;
19
+ --secondary-color: #FF6584;
20
+ --accent-color: #43D9AD;
21
+ --bg-gradient: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
22
+ --glass-bg: rgba(255, 255, 255, 0.85);
23
+ --glass-border: rgba(255, 255, 255, 0.5);
24
+ --text-dark: #2D3436;
25
+ --shadow-lg: 0 10px 30px rgba(0,0,0,0.15);
26
+ }
27
+
28
+ * {
29
+ box-sizing: border-box;
30
+ margin: 0;
31
+ padding: 0;
32
+ }
33
+
34
+ body {
35
+ font-family: 'Nunito', sans-serif;
36
+ background: var(--bg-gradient);
37
+ height: 100vh;
38
+ display: flex;
39
+ flex-direction: column;
40
+ overflow: hidden; /* Prevent scrolling during animations */
41
+ color: var(--text-dark);
42
+ }
43
+
44
+ /* Header Section */
45
+ header {
46
+ padding: 1rem 2rem;
47
+ display: flex;
48
+ justify-content: space-between;
49
+ align-items: center;
50
+ background: rgba(255, 255, 255, 0.9);
51
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
52
+ z-index: 100;
53
+ }
54
+
55
+ .logo {
56
+ font-family: 'Fredoka', sans-serif;
57
+ font-size: 1.5rem;
58
+ font-weight: 700;
59
+ color: var(--primary-color);
60
+ display: flex;
61
+ align-items: center;
62
+ gap: 10px;
63
+ }
64
+
65
+ .anycoder-link {
66
+ font-size: 0.9rem;
67
+ font-weight: 600;
68
+ color: var(--text-dark);
69
+ text-decoration: none;
70
+ padding: 0.5rem 1rem;
71
+ background: #f0f0f0;
72
+ border-radius: 20px;
73
+ transition: all 0.3s ease;
74
+ }
75
+
76
+ .anycoder-link:hover {
77
+ background: var(--primary-color);
78
+ color: white;
79
+ transform: translateY(-2px);
80
+ }
81
+
82
+ /* Main Game Area */
83
+ main {
84
+ flex: 1;
85
+ display: flex;
86
+ flex-direction: column;
87
+ justify-content: center;
88
+ align-items: center;
89
+ position: relative;
90
+ padding: 1rem;
91
+ }
92
+
93
+ /* Game Container (Glassmorphism) */
94
+ .game-board {
95
+ background: var(--glass-bg);
96
+ backdrop-filter: blur(12px);
97
+ -webkit-backdrop-filter: blur(12px);
98
+ border: 1px solid var(--glass-border);
99
+ border-radius: 30px;
100
+ padding: 2rem;
101
+ width: 90%;
102
+ max-width: 600px;
103
+ box-shadow: var(--shadow-lg);
104
+ text-align: center;
105
+ display: flex;
106
+ flex-direction: column;
107
+ align-items: center;
108
+ min-height: 500px;
109
+ justify-content: space-between;
110
+ transition: transform 0.3s ease;
111
+ }
112
+
113
+ /* Progress Bar */
114
+ .progress-container {
115
+ width: 100%;
116
+ height: 10px;
117
+ background: #e0e0e0;
118
+ border-radius: 10px;
119
+ margin-bottom: 2rem;
120
+ overflow: hidden;
121
+ }
122
+
123
+ .progress-bar {
124
+ height: 100%;
125
+ width: 0%;
126
+ background: linear-gradient(90deg, var(--secondary-color), var(--primary-color));
127
+ border-radius: 10px;
128
+ transition: width 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
129
+ }
130
+
131
+ /* The Big Letter Display */
132
+ .letter-display {
133
+ font-family: 'Fredoka', sans-serif;
134
+ font-size: 12rem; /* Responsive size handled below */
135
+ font-weight: 700;
136
+ color: var(--primary-color);
137
+ text-shadow: 4px 4px 0px rgba(0,0,0,0.1);
138
+ cursor: default;
139
+ user-select: none;
140
+ position: relative;
141
+ z-index: 2;
142
+ transition: color 0.3s;
143
+ }
144
+
145
+ /* Image Container */
146
+ .image-container {
147
+ width: 200px;
148
+ height: 200px;
149
+ border-radius: 20px;
150
+ overflow: hidden;
151
+ background: #fff;
152
+ box-shadow: inset 0 0 20px rgba(0,0,0,0.05);
153
+ border: 4px solid white;
154
+ display: flex;
155
+ justify-content: center;
156
+ align-items: center;
157
+ opacity: 0; /* Hidden by default */
158
+ transform: scale(0.8);
159
+ transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
160
+ margin-top: 1rem;
161
+ }
162
+
163
+ .image-container.visible {
164
+ opacity: 1;
165
+ transform: scale(1);
166
+ }
167
+
168
+ .image-container img {
169
+ width: 100%;
170
+ height: 100%;
171
+ object-fit: cover;
172
+ }
173
+
174
+ /* Instructions / Status */
175
+ .status-text {
176
+ font-size: 1.2rem;
177
+ color: #636e72;
178
+ margin-top: 1rem;
179
+ font-weight: 600;
180
+ }
181
+
182
+ .hint-text {
183
+ font-size: 0.9rem;
184
+ color: #b2bec3;
185
+ margin-top: 0.5rem;
186
+ }
187
+
188
+ /* Controls (Start/Restart) */
189
+ .controls {
190
+ margin-top: 2rem;
191
+ }
192
+
193
+ .btn {
194
+ background: var(--primary-color);
195
+ color: white;
196
+ border: none;
197
+ padding: 1rem 2.5rem;
198
+ font-size: 1.2rem;
199
+ border-radius: 50px;
200
+ cursor: pointer;
201
+ font-family: 'Fredoka', sans-serif;
202
+ box-shadow: 0 5px 15px rgba(108, 99, 255, 0.4);
203
+ transition: all 0.2s ease;
204
+ display: flex;
205
+ align-items: center;
206
+ gap: 10px;
207
+ }
208
+
209
+ .btn:hover {
210
+ transform: translateY(-3px);
211
+ box-shadow: 0 8px 20px rgba(108, 99, 255, 0.5);
212
+ }
213
+
214
+ .btn:active {
215
+ transform: translateY(1px);
216
+ }
217
+
218
+ .btn.secondary {
219
+ background: var(--text-dark);
220
+ box-shadow: 0 5px 15px rgba(0,0,0,0.2);
221
+ }
222
+
223
+ /* Animations */
224
+ @keyframes popIn {
225
+ 0% { transform: scale(0); opacity: 0; }
226
+ 60% { transform: scale(1.2); opacity: 1; }
227
+ 100% { transform: scale(1); opacity: 1; }
228
+ }
229
+
230
+ @keyframes shake {
231
+ 0% { transform: translateX(0); }
232
+ 25% { transform: translateX(-10px) rotate(-5deg); color: var(--secondary-color); }
233
+ 50% { transform: translateX(10px) rotate(5deg); color: var(--secondary-color); }
234
+ 75% { transform: translateX(-10px) rotate(-5deg); }
235
+ 100% { transform: translateX(0); color: var(--primary-color); }
236
+ }
237
+
238
+ @keyframes float {
239
+ 0% { transform: translateY(0px); }
240
+ 50% { transform: translateY(-10px); }
241
+ 100% { transform: translateY(0px); }
242
+ }
243
+
244
+ .anim-pop {
245
+ animation: popIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
246
+ }
247
+
248
+ .anim-shake {
249
+ animation: shake 0.4s ease-in-out;
250
+ }
251
+
252
+ .anim-float {
253
+ animation: float 3s ease-in-out infinite;
254
+ }
255
+
256
+ /* Confetti Overlay */
257
+ #confetti-canvas {
258
+ position: absolute;
259
+ top: 0;
260
+ left: 0;
261
+ width: 100%;
262
+ height: 100%;
263
+ pointer-events: none;
264
+ z-index: 50;
265
+ }
266
+
267
+ /* Responsive Design */
268
+ @media (max-width: 768px) {
269
+ .letter-display {
270
+ font-size: 8rem;
271
+ }
272
+ .game-board {
273
+ width: 95%;
274
+ padding: 1.5rem;
275
+ }
276
+ .image-container {
277
+ width: 150px;
278
+ height: 150px;
279
+ }
280
+ }
281
+
282
+ @media (max-width: 480px) {
283
+ .letter-display {
284
+ font-size: 6rem;
285
+ }
286
+ header {
287
+ padding: 0.8rem 1rem;
288
+ }
289
+ .logo span {
290
+ display: none; /* Hide text logo on very small screens, keep icon */
291
+ }
292
+ .image-container {
293
+ width: 120px;
294
+ height: 120px;
295
+ }
296
+ }
297
+ </style>
298
+ </head>
299
+ <body>
300
+
301
+ <header>
302
+ <div class="logo">
303
+ <i class="fa-solid fa-shapes"></i>
304
+ <span>AlphaPop</span>
305
+ </div>
306
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
307
+ Built with anycoder
308
+ </a>
309
+ </header>
310
+
311
+ <main>
312
+ <canvas id="confetti-canvas"></canvas>
313
+
314
+ <div class="game-board">
315
+ <!-- Progress -->
316
+ <div class="progress-container">
317
+ <div class="progress-bar" id="progressBar"></div>
318
+ </div>
319
+
320
+ <!-- Interactive Area -->
321
+ <div id="gameArea" style="display: none; flex-direction: column; align-items: center; width: 100%;">
322
+ <div class="letter-display anim-pop" id="letterDisplay">A</div>
323
+
324
+ <div class="image-container" id="imageContainer">
325
+ <img id="letterImage" src="" alt="Letter Image">
326
+ </div>
327
+
328
+ <div class="status-text" id="statusText">Press the 'A' key!</div>
329
+ <div class="hint-text"><i class="fa-solid fa-volume-high"></i> Sound On</div>
330
+ </div>
331
+
332
+ <!-- Start Screen -->
333
+ <div id="startScreen" style="text-align: center;">
334
+ <div class="logo" style="justify-content: center; font-size: 3rem; margin-bottom: 1rem; color: var(--primary-color);">
335
+ <i class="fa-solid fa-keyboard"></i>
336
+ </div>
337
+ <h2 style="margin-bottom: 1rem; font-size: 1.8rem;">Are you ready to type?</h2>
338
+ <p style="margin-bottom: 2rem; color: #636e72;">Press the matching key on your keyboard to hear the sound and see the picture!</p>
339
+ <button class="btn" onclick="startGame()">
340
+ Start Game <i class="fa-solid fa-play"></i>
341
+ </button>
342
+ </div>
343
+
344
+ <!-- End Screen -->
345
+ <div id="endScreen" style="display: none; text-align: center;">
346
+ <i class="fa-solid fa-trophy" style="font-size: 4rem; color: #f1c40f; margin-bottom: 1rem; animation: float 2s infinite;"></i>
347
+ <h2 style="margin-bottom: 1rem; font-size: 2rem;">Great Job!</h2>
348
+ <p style="margin-bottom: 2rem; color: #636e72;">You completed the alphabet.</p>
349
+ <button class="btn" onclick="startGame()">
350
+ Play Again <i class="fa-solid fa-rotate-right"></i>
351
+ </button>
352
+ </div>
353
+ </div>
354
+ </main>
355
+
356
+ <script>
357
+ // Game Configuration
358
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split('');
359
+ let currentIndex = 0;
360
+ let isGameActive = false;
361
+
362
+ // DOM Elements
363
+ const startScreen = document.getElementById('startScreen');
364
+ const endScreen = document.getElementById('endScreen');
365
+ const gameArea = document.getElementById('gameArea');
366
+ const letterDisplay = document.getElementById('letterDisplay');
367
+ const statusText = document.getElementById('statusText');
368
+ const imageContainer = document.getElementById('imageContainer');
369
+ const letterImage = document.getElementById('letterImage');
370
+ const progressBar = document.getElementById('progressBar');
371
+
372
+ // --- USER CONFIGURATION FOR IMAGES ---
373
+ // If you have local images, replace the return value of this function
374
+ // with the path to your image file.
375
+ // Example: return `assets/images/${letter}.jpg`;
376
+ function getRandomImageForLetter(letter) {
377
+ // This generates a consistent random seed based on the letter + a random number
378
+ // to simulate having multiple images for the same letter.
379
+ const randomId = Math.floor(Math.random() * 1000);
380
+
381
+ // Using picsum.photos as a placeholder service.
382
+ // The seed ensures that 'A' always looks somewhat different but consistent per session.
383
+ return `https://picsum.photos/seed/${letter}${randomId}/300/300`;
384
+
385
+ // YOUR CODE (Uncomment below and adjust path if you have local files):
386
+ // const images = {
387
+ // 'A': ['apple.jpg', 'ant.jpg', 'axe.jpg'],
388
+ // 'B': ['ball.jpg', 'bear.jpg', 'boat.jpg'],
389
+ // // ... add all letters
390
+ // };
391
+ // const list = images[letter] || ['default.jpg'];
392
+ // return 'path/to/folder/' + list[Math.floor(Math.random() * list.length)];
393
+ }
394
+
395
+ // Sound Functionality (Web Speech API)
396
+ function speakLetter(letter) {
397
+ if ('speechSynthesis' in window) {
398
+ // Cancel any currently playing speech
399
+ window.speechSynthesis.cancel();
400
+
401
+ const utterance = new SpeechSynthesisUtterance(letter);
402
+ utterance.lang = 'en-US';
403
+ utterance.rate = 0.8; // Slightly slower for kids
404
+ utterance.pitch = 1.1; // Slightly higher/friendly
405
+ window.speechSynthesis.speak(utterance);
406
+ }
407
+ }
408
+
409
+ // Game Logic
410
+ function startGame() {
411
+ currentIndex = 0;
412
+ isGameActive = true;
413
+
414
+ // UI Transitions
415
+ startScreen.style.display = 'none';
416
+ endScreen.style.display = 'none';
417
+ gameArea.style.display = 'flex';
418
+
419
+ updateLevel();
420
+ }
421
+
422
+ function updateLevel() {
423
+ if (currentIndex >= alphabet.length) {
424
+ endGame();
425
+ return;
426
+ }
427
+
428
+ const currentLetter = alphabet[currentIndex];
429
+
430
+ // Reset Animations
431
+ letterDisplay.classList.remove('anim-pop', 'anim-shake');
432
+ void letterDisplay.offsetWidth; // Trigger reflow to restart animation
433
+ letterDisplay.classList.add('anim-pop');
434
+
435
+ // Update Text
436
+ letterDisplay.textContent = currentLetter;
437
+ statusText.textContent = `Press the '${currentLetter}' key!`;
438
+
439
+ // Hide Image initially
440
+ imageContainer.classList.remove('visible');
441
+
442
+ // Update Progress
443
+ const progress = (currentIndex / alphabet.length) * 100;
444
+ progressBar.style.width = `${progress}%`;
445
+
446
+ // Speak the letter immediately when level starts
447
+ speakLetter(currentLetter);
448
+ }
449
+
450
+ function handleInput(e) {
451
+ if (!isGameActive) return;
452
+
453
+ const key = e.key.toUpperCase();
454
+ const targetLetter = alphabet[currentIndex];
455
+
456
+ // Check if the key pressed is a letter
457
+ if (!/^[A-Z]$/.test(key)) return;
458
+
459
+ if (key === targetLetter) {
460
+ // Correct Answer
461
+ onCorrectPress(targetLetter);
462
+ } else {
463
+ // Wrong Answer
464
+ onWrongPress();
465
+ }
466
+ }
467
+
468
+ function onCorrectPress(letter) {
469
+ // Play sound again for confirmation
470
+ speakLetter(letter);
471
+
472
+ // Show Image
473
+ const imgUrl = getRandomImageForLetter(letter);
474
+ letterImage.src = imgUrl;
475
+
476
+ // Wait for image to load slightly before showing to prevent flicker
477
+ letterImage.onload = () => {
478
+ imageContainer.classList.add('visible');
479
+ };
480
+ if(letterImage.complete) imageContainer.classList.add('visible');
481
+
482
+ // Visual feedback on text
483
+ letterDisplay.style.color = "var(--accent-color)";
484
+ statusText.textContent = "Great!";
485
+ statusText.style.color = "var(--accent-color)";
486
+
487
+ // Trigger small confetti
488
+ fireConfetti(0.5); // 50% screen width
489
+
490
+ // Wait 1.5 seconds then go to next letter
491
+ setTimeout(() => {
492
+ currentIndex++;
493
+ letterDisplay.style.color = "var(--primary-color)";
494
+ statusText.style.color = "#636e72";
495
+ updateLevel();
496
+ }, 1500);
497
+ }
498
+
499
+ function onWrongPress() {
500
+ // Shake animation
501
+ letterDisplay.classList.remove('anim-shake');
502
+ void letterDisplay.offsetWidth;
503
+ letterDisplay.classList.add('anim-shake');
504
+
505
+ statusText.textContent = "Oops, try again!";
506
+ statusText.style.color = "var(--secondary-color)";
507
+
508
+ // Play error sound (using speech synthesis for a low 'uh-oh' or just re-prompting target)
509
+ // For simplicity, we just re-speak the target letter
510
+ speakLetter(alphabet[currentIndex]);
511
+ }
512
+
513
+ function endGame() {
514
+ isGameActive = false;
515
+ gameArea.style.display = 'none';
516
+ endScreen.style.display = 'block';
517
+ progressBar.style.width = '100%';
518
+ fireConfetti(1.0); // Full screen confetti
519
+ }
520
+
521
+ // Event Listeners
522
+ window.addEventListener('keydown', handleInput);
523
+
524
+ // --- Simple Confetti Implementation (No external library) ---
525
+ const canvas = document.getElementById('confetti-canvas');
526
+ const ctx = canvas.getContext('2d');
527
+ let particles = [];
528
+
529
+ function resizeCanvas() {
530
+ canvas.width = window.innerWidth;
531
+ canvas.height = window.innerHeight;
532
+ }
533
+ window.addEventListener('resize', resizeCanvas);
534
+ resizeCanvas();
535
+
536
+ function fireConfetti(intensity = 1.0) {
537
+ const particleCount = 100 * intensity;
538
+ const colors = ['#FF6584', '#6C63FF', '#43D9AD', '#FFD93D', '#FF8C00'];
539
+
540
+ for (let i = 0; i < particleCount; i++) {
541
+ particles.push({
542
+ x: canvas.width / 2,
543
+ y: canvas.height / 2 + 50, // Start from middle-ish
544
+ vx: (Math.random() - 0.5) * 20 * intensity,
545
+ vy: (Math.random() - 1) * 20 * intensity,
546
+ size: Math.random() * 8 + 4,
547
+ color: colors[Math.floor(Math.random() * colors.length)],
548
+ life: 100,
549
+ gravity: 0.5
550
+ });
551
+ }
552
+ requestAnimationFrame(updateConfetti);
553
+ }
554
+
555
+ function updateConfetti() {
556
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
557
+
558
+ for (let i = 0; i < particles.length; i++) {
559
+ let p = particles[i];
560
+ p.x += p.vx;
561
+ p.y += p.vy;
562
+ p.vy += p.gravity;
563
+ p.life--;
564
+
565
+ ctx.fillStyle = p.color;
566
+ ctx.beginPath();
567
+ ctx.rect(p.x, p.y, p.size, p.size);
568
+ ctx.fill();
569
+ }
570
+
571
+ // Remove dead particles
572
+ particles = particles.filter(p => p.life > 0);
573
+
574
+ if (particles.length > 0) {
575
+ requestAnimationFrame(updateConfetti);
576
+ }
577
+ }
578
+
579
+ </script>
580
+ </body>
581
+ </html>