openfree commited on
Commit
69a6cde
·
verified ·
1 Parent(s): 3edcd3e

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +170 -248
index.html CHANGED
@@ -3,7 +3,8 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Fun Math Game</title>
 
7
  <style>
8
  * {
9
  margin: 0;
@@ -13,303 +14,224 @@
13
  }
14
 
15
  body {
 
16
  min-height: 100vh;
17
- display: flex;
18
- justify-content: center;
19
- align-items: center;
20
- background: linear-gradient(45deg, #6ab1e7, #4377c4);
21
  padding: 20px;
22
  }
23
 
24
  .container {
 
 
25
  background: white;
26
- padding: 2rem;
27
- border-radius: 20px;
28
- box-shadow: 0 10px 30px rgba(0,0,0,0.2);
29
- max-width: 500px;
30
- width: 90%;
31
- text-align: center;
32
- }
33
-
34
- .header {
35
- margin-bottom: 2rem;
36
- }
37
-
38
- .title {
39
- font-size: 2rem;
40
- color: #4377c4;
41
- margin-bottom: 1rem;
42
- }
43
-
44
- .stats {
45
- display: flex;
46
- justify-content: space-around;
47
- margin-bottom: 1rem;
48
- }
49
-
50
- .stat-item {
51
- background: #f0f8ff;
52
- padding: 0.5rem 1rem;
53
- border-radius: 10px;
54
- font-weight: bold;
55
- }
56
-
57
- .question {
58
- font-size: 2.5rem;
59
- margin: 1.5rem 0;
60
- color: #333;
61
- animation: fadeIn 0.5s ease;
62
  }
63
 
64
- .options {
65
- display: grid;
66
- grid-template-columns: repeat(2, 1fr);
67
- gap: 1rem;
68
- margin: 2rem 0;
69
  }
70
 
71
- .option {
72
- padding: 1rem;
73
- border: 2px solid #4377c4;
74
- border-radius: 15px;
 
 
75
  cursor: pointer;
76
  transition: all 0.3s ease;
77
- font-size: 1.2rem;
78
- background: white;
79
  }
80
 
81
- .option:hover {
82
- background: #4377c4;
83
- color: white;
84
- transform: translateY(-2px);
85
- box-shadow: 0 5px 15px rgba(67, 119, 196, 0.3);
86
  }
87
 
88
- .feedback {
89
- margin: 1rem 0;
90
- font-size: 1.3rem;
91
- min-height: 1.5em;
92
- font-weight: bold;
93
  }
94
 
95
- .correct {
96
- color: #2ecc71;
97
- animation: bounce 0.5s ease;
98
- }
99
-
100
- .wrong {
101
- color: #e74c3c;
102
- animation: shake 0.5s ease;
103
  }
104
 
105
- .next-btn {
106
- background: #4377c4;
107
- color: white;
108
  border: none;
109
- padding: 1rem 2.5rem;
110
- border-radius: 10px;
 
111
  cursor: pointer;
112
- font-size: 1.1rem;
113
  transition: all 0.3s ease;
114
- font-weight: bold;
115
- }
116
-
117
- .next-btn:hover {
118
- transform: scale(1.05);
119
- box-shadow: 0 5px 15px rgba(67, 119, 196, 0.3);
120
- }
121
-
122
- .timer {
123
- width: 100%;
124
- height: 5px;
125
- background: #eee;
126
- margin-bottom: 1rem;
127
- border-radius: 5px;
128
- overflow: hidden;
129
  }
130
 
131
- .timer-bar {
132
- height: 100%;
133
- background: #4377c4;
134
- width: 100%;
135
- transition: width 1s linear;
136
  }
137
 
138
- @keyframes fadeIn {
139
- from { opacity: 0; transform: translateY(-10px); }
140
- to { opacity: 1; transform: translateY(0); }
141
  }
142
 
143
- @keyframes bounce {
144
- 0%, 100% { transform: scale(1); }
145
- 50% { transform: scale(1.1); }
 
 
 
 
 
146
  }
147
 
148
- @keyframes shake {
149
- 0%, 100% { transform: translateX(0); }
150
- 25% { transform: translateX(-5px); }
151
- 75% { transform: translateX(5px); }
152
  }
153
 
154
- @media (max-width: 480px) {
155
  .container {
156
- padding: 1rem;
157
  }
158
-
159
- .question {
160
- font-size: 1.8rem;
161
  }
162
-
163
- .option {
164
- font-size: 1rem;
165
- padding: 0.8rem;
166
  }
167
  }
168
  </style>
169
  </head>
170
  <body>
171
  <div class="container">
172
- <div class="header">
173
- <h1 class="title">Fun Math Game 🎮</h1>
174
- <div class="timer">
175
- <div class="timer-bar" id="timer-bar"></div>
176
- </div>
177
- <div class="stats">
178
- <div class="stat-item">Score: <span id="score">0</span></div>
179
- <div class="stat-item">Level: <span id="level">1</span></div>
180
- <div class="stat-item">Streak: <span id="streak">0</span></div>
181
- </div>
182
  </div>
183
- <div class="question" id="question"></div>
184
- <div class="options" id="options"></div>
185
- <div class="feedback" id="feedback"></div>
186
- <button class="next-btn" onclick="nextQuestion()">Next Question ➡️</button>
187
- </div>
188
-
189
- <script>
190
- let score = 0;
191
- let level = 1;
192
- let streak = 0;
193
- let correctAnswer;
194
- let timerInterval;
195
 
196
- function startTimer() {
197
- clearInterval(timerInterval);
198
- const timerBar = document.getElementById('timer-bar');
199
- timerBar.style.width = '100%';
200
-
201
- let timeLeft = 100;
202
- timerInterval = setInterval(() => {
203
- timeLeft -= 1;
204
- timerBar.style.width = timeLeft + '%';
205
-
206
- if (timeLeft <= 0) {
207
- clearInterval(timerInterval);
208
- checkAnswer(null);
209
- }
210
- }, 100);
211
- }
212
 
213
- function generateQuestion() {
214
- const operations = ['+', '-', '*', '/'];
215
- const operation = operations[Math.floor(Math.random() * operations.length)];
216
- let num1, num2;
217
- const maxNum = 10 + (level * 5); // Increase difficulty with level
218
 
219
- switch(operation) {
220
- case '+':
221
- num1 = Math.floor(Math.random() * maxNum);
222
- num2 = Math.floor(Math.random() * maxNum);
223
- correctAnswer = num1 + num2;
224
- break;
225
- case '-':
226
- num1 = Math.floor(Math.random() * maxNum);
227
- num2 = Math.floor(Math.random() * num1);
228
- correctAnswer = num1 - num2;
229
- break;
230
- case '*':
231
- num1 = Math.floor(Math.random() * (level + 5));
232
- num2 = Math.floor(Math.random() * (level + 5));
233
- correctAnswer = num1 * num2;
234
- break;
235
- case '/':
236
- num2 = Math.floor(Math.random() * (level + 3)) + 1;
237
- correctAnswer = Math.floor(Math.random() * (level + 3));
238
- num1 = correctAnswer * num2;
239
- break;
 
 
 
 
 
 
 
 
240
  }
241
-
242
- document.getElementById('question').textContent = `${num1} ${operation} ${num2} = ?`;
243
- generateOptions(correctAnswer);
244
- startTimer();
245
- }
246
-
247
- function generateOptions(correct) {
248
- const options = [correct];
249
- const range = Math.max(10, correct * 0.5);
250
-
251
- while(options.length < 4) {
252
- const randomOption = correct + Math.floor(Math.random() * range) - (range/2);
253
- if(!options.includes(randomOption) && randomOption >= 0) {
254
- options.push(randomOption);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  }
257
-
258
- options.sort(() => Math.random() - 0.5);
259
-
260
- const optionsContainer = document.getElementById('options');
261
- optionsContainer.innerHTML = '';
262
-
263
- options.forEach(option => {
264
- const button = document.createElement('div');
265
- button.className = 'option';
266
- button.textContent = option;
267
- button.onclick = () => checkAnswer(option);
268
- optionsContainer.appendChild(button);
269
- });
270
- }
271
-
272
- function checkAnswer(selected) {
273
- clearInterval(timerInterval);
274
- const feedback = document.getElementById('feedback');
275
-
276
- if(selected === correctAnswer) {
277
- score += (level * 10);
278
- streak++;
279
- if(streak % 3 === 0) level++;
280
-
281
- document.getElementById('score').textContent = score;
282
- document.getElementById('level').textContent = level;
283
- document.getElementById('streak').textContent = streak;
284
-
285
- feedback.textContent = "Awesome! 🎉";
286
- feedback.className = 'feedback correct';
287
- } else {
288
- streak = 0;
289
- document.getElementById('streak').textContent = streak;
290
- feedback.textContent = selected === null ? "Time's up! ⏰" : "Wrong! Try again! 😢";
291
- feedback.className = 'feedback wrong';
292
  }
293
-
294
- document.querySelectorAll('.option').forEach(option => {
295
- option.style.pointerEvents = 'none';
296
- if(parseInt(option.textContent) === correctAnswer) {
297
- option.style.background = '#2ecc71';
298
- option.style.color = 'white';
299
- } else if(parseInt(option.textContent) === selected && selected !== correctAnswer) {
300
- option.style.background = '#e74c3c';
301
- option.style.color = 'white';
302
- }
303
- });
304
- }
305
-
306
- function nextQuestion() {
307
- document.getElementById('feedback').textContent = '';
308
- generateQuestion();
309
- }
310
-
311
- // Start game
312
- generateQuestion();
313
  </script>
314
  </body>
315
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>PDF Reader with Text-to-Speech</title>
7
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
8
  <style>
9
  * {
10
  margin: 0;
 
14
  }
15
 
16
  body {
17
+ background: #f0f2f5;
18
  min-height: 100vh;
 
 
 
 
19
  padding: 20px;
20
  }
21
 
22
  .container {
23
+ max-width: 800px;
24
+ margin: 0 auto;
25
  background: white;
26
+ padding: 30px;
27
+ border-radius: 12px;
28
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  }
30
 
31
+ h1 {
32
+ text-align: center;
33
+ color: #1a73e8;
34
+ margin-bottom: 30px;
 
35
  }
36
 
37
+ .upload-section {
38
+ border: 2px dashed #1a73e8;
39
+ padding: 30px;
40
+ text-align: center;
41
+ border-radius: 8px;
42
+ margin-bottom: 20px;
43
  cursor: pointer;
44
  transition: all 0.3s ease;
 
 
45
  }
46
 
47
+ .upload-section:hover {
48
+ background: #f8f9fe;
 
 
 
49
  }
50
 
51
+ .upload-section i {
52
+ font-size: 40px;
53
+ color: #1a73e8;
54
+ margin-bottom: 10px;
 
55
  }
56
 
57
+ .controls {
58
+ display: flex;
59
+ gap: 10px;
60
+ margin-bottom: 20px;
61
+ justify-content: center;
 
 
 
62
  }
63
 
64
+ button {
65
+ padding: 10px 20px;
 
66
  border: none;
67
+ border-radius: 5px;
68
+ background: #1a73e8;
69
+ color: white;
70
  cursor: pointer;
 
71
  transition: all 0.3s ease;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  }
73
 
74
+ button:hover {
75
+ background: #1557b0;
 
 
 
76
  }
77
 
78
+ button:disabled {
79
+ background: #ccc;
80
+ cursor: not-allowed;
81
  }
82
 
83
+ #pdf-content {
84
+ background: white;
85
+ padding: 20px;
86
+ border-radius: 8px;
87
+ min-height: 200px;
88
+ max-height: 400px;
89
+ overflow-y: auto;
90
+ line-height: 1.6;
91
  }
92
 
93
+ .status {
94
+ text-align: center;
95
+ margin: 10px 0;
96
+ color: #666;
97
  }
98
 
99
+ @media (max-width: 600px) {
100
  .container {
101
+ padding: 15px;
102
  }
103
+
104
+ .controls {
105
+ flex-direction: column;
106
  }
107
+
108
+ button {
109
+ width: 100%;
 
110
  }
111
  }
112
  </style>
113
  </head>
114
  <body>
115
  <div class="container">
116
+ <h1>PDF Text-to-Speech Reader</h1>
117
+
118
+ <div class="upload-section" id="upload-area">
119
+ <i>📄</i>
120
+ <p>Click or drag PDF file here to upload</p>
121
+ <input type="file" id="file-input" accept=".pdf" style="display: none;">
 
 
 
 
122
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
+ <div class="controls">
125
+ <button id="play-btn" disabled>
126
+ <i>▶️</i> Play
127
+ </button>
128
+ <button id="pause-btn" disabled>
129
+ <i>⏸️</i> Pause
130
+ </button>
131
+ <button id="stop-btn" disabled>
132
+ <i>⏹️</i> Stop
133
+ </button>
134
+ </div>
 
 
 
 
 
135
 
136
+ <div class="status" id="status"></div>
137
+
138
+ <div id="pdf-content"></div>
139
+ </div>
 
140
 
141
+ <script>
142
+ pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.worker.min.js';
143
+
144
+ const fileInput = document.getElementById('file-input');
145
+ const uploadArea = document.getElementById('upload-area');
146
+ const playBtn = document.getElementById('play-btn');
147
+ const pauseBtn = document.getElementById('pause-btn');
148
+ const stopBtn = document.getElementById('stop-btn');
149
+ const status = document.getElementById('status');
150
+ const content = document.getElementById('pdf-content');
151
+
152
+ let pdfText = '';
153
+ let utterance = null;
154
+ let synth = window.speechSynthesis;
155
+
156
+ uploadArea.addEventListener('click', () => fileInput.click());
157
+ uploadArea.addEventListener('dragover', (e) => {
158
+ e.preventDefault();
159
+ uploadArea.style.background = '#f0f8ff';
160
+ });
161
+ uploadArea.addEventListener('dragleave', () => {
162
+ uploadArea.style.background = 'transparent';
163
+ });
164
+ uploadArea.addEventListener('drop', (e) => {
165
+ e.preventDefault();
166
+ uploadArea.style.background = 'transparent';
167
+ const file = e.dataTransfer.files[0];
168
+ if (file && file.type === 'application/pdf') {
169
+ handleFile(file);
170
  }
171
+ });
172
+
173
+ fileInput.addEventListener('change', (e) => {
174
+ const file = e.target.files[0];
175
+ if (file) handleFile(file);
176
+ });
177
+
178
+ function handleFile(file) {
179
+ status.textContent = 'Loading PDF...';
180
+ const reader = new FileReader();
181
+ reader.onload = async function(event) {
182
+ const typedarray = new Uint8Array(event.target.result);
183
+ try {
184
+ const pdf = await pdfjsLib.getDocument(typedarray).promise;
185
+ pdfText = '';
186
+
187
+ for(let i = 1; i <= pdf.numPages; i++) {
188
+ const page = await pdf.getPage(i);
189
+ const textContent = await page.getTextContent();
190
+ pdfText += textContent.items.map(item => item.str).join(' ');
191
+ }
192
+
193
+ content.textContent = pdfText;
194
+ status.textContent = 'PDF loaded successfully!';
195
+ playBtn.disabled = false;
196
+ stopBtn.disabled = false;
197
+
198
+ } catch(error) {
199
+ status.textContent = 'Error loading PDF: ' + error.message;
200
  }
201
+ };
202
+ reader.readAsArrayBuffer(file);
203
+ }
204
+
205
+ playBtn.addEventListener('click', () => {
206
+ if (synth.speaking && synth.paused) {
207
+ synth.resume();
208
+ } else if (!synth.speaking) {
209
+ utterance = new SpeechSynthesisUtterance(pdfText);
210
+ utterance.onend = () => {
211
+ playBtn.disabled = false;
212
+ pauseBtn.disabled = true;
213
+ stopBtn.disabled = true;
214
+ };
215
+ synth.speak(utterance);
216
  }
217
+ playBtn.disabled = true;
218
+ pauseBtn.disabled = false;
219
+ stopBtn.disabled = false;
220
+ });
221
+
222
+ pauseBtn.addEventListener('click', () => {
223
+ if (synth.speaking) {
224
+ synth.pause();
225
+ playBtn.disabled = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  }
227
+ });
228
+
229
+ stopBtn.addEventListener('click', () => {
230
+ synth.cancel();
231
+ playBtn.disabled = false;
232
+ pauseBtn.disabled = true;
233
+ stopBtn.disabled = true;
234
+ });
 
 
 
 
 
 
 
 
 
 
 
 
235
  </script>
236
  </body>
237
  </html>