Skip to content

Commit 141c323

Browse files
committed
add time problems, some animation fixes
1 parent e850f1c commit 141c323

13 files changed

+836
-143
lines changed

animations.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ class AnimationSystem {
4848
}
4949

5050
// Export a single instance to be used across all problems
51-
const animationSystem = new AnimationSystem();
51+
export const animationSystem = new AnimationSystem();

customary-units-three-numbers.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ <h1>Fun Math Problems! 🎨</h1>
4242
Customary Units of Length: Using 3 One or Two Digit Numbers
4343
</div>
4444
<div class="stars" id="stars-container"></div>
45-
<script src="animations.js"></script>
46-
<script src="customary-units-three-numbers.js"></script>
45+
<script src="animations.js" type="module" defer></script>
46+
<script src="customary-units-three-numbers.js" type="module" defer></script>
4747
</body>
4848
</html>

customary-units-three-numbers.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { animationSystem } from './animations.js';
2+
13
// Problem generator functions
24
function generateProblem() {
35
// Names array to cycle through

customary-units-up-to-100.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ <h1>Fun Math Problems! 🎨</h1>
4242
Customary Units of Length: Up to 100
4343
</div>
4444
<div class="stars" id="stars-container"></div>
45-
<script src="animations.js"></script>
46-
<script src="customary-units-up-to-100.js"></script>
45+
<script src="animations.js" type="module" defer></script>
46+
<script src="customary-units-up-to-100.js" type="module" defer></script>
4747
</body>
4848
</html>

customary-units-up-to-100.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { animationSystem } from './animations.js';
2+
13
// Problem generator functions
24
function generateProblem() {
35
// Names array to cycle through

index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ <h2 class="topic-title">Word Problems</h2>
3434
</div>
3535
</div>
3636

37+
<div class="topic-section">
38+
<h2 class="topic-title">Time</h2>
39+
<div class="problem-links">
40+
<a href="time-problems.html" class="problem-link">
41+
⏰ Telling Time Problems
42+
</a>
43+
</div>
44+
</div>
45+
3746
<div class="topic-section">
3847
<h2 class="topic-title">More Topics Coming Soon!</h2>
3948
<div class="problem-links">

length-word-problems.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ <h1>Fun Math Problems! 🎨</h1>
4242
Length Word Problems
4343
</div>
4444
<div class="stars" id="stars-container"></div>
45-
<script src="animations.js"></script>
46-
<script src="length-word-problems.js"></script>
45+
<script src="animations.js" type="module" defer></script>
46+
<script src="length-word-problems.js" type="module" defer></script>
4747
</body>
4848
</html>

length-word-problems.js

Lines changed: 111 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { animationSystem } from './animations.js';
2+
13
// Scratchpad functionality
24
class Scratchpad {
35
constructor(canvas) {
@@ -282,149 +284,124 @@ let currentProblemIndex = 0;
282284
const problems = [];
283285
const totalProblems = 50;
284286

285-
// Generate all problems at start
286-
for (let i = 0; i < totalProblems; i++) {
287-
problems.push(generateProblem());
288-
}
287+
// Removed DOM element getters, initialization, problem generation loop, handlers from global scope
288+
289+
// Event listeners
290+
document.addEventListener('DOMContentLoaded', () => {
291+
// Moved initialization code inside DOMContentLoaded
292+
293+
// DOM elements
294+
const problemText = document.getElementById('problem-text');
295+
const optionsContainer = document.getElementById('options-container');
296+
const prevButton = document.getElementById('prev-btn');
297+
const nextButton = document.getElementById('next-btn');
298+
299+
// Scratchpad elements
300+
const scratchpadArea = document.getElementById('scratchpad-area');
301+
const scratchpadCanvas = document.getElementById('scratchpad');
302+
const toggleScratchpadBtn = document.getElementById('toggle-scratchpad');
303+
const closeScratchpadBtn = document.getElementById('close-scratchpad');
304+
const undoBtn = document.getElementById('undo-btn');
305+
const redoBtn = document.getElementById('redo-btn');
306+
const clearBtn = document.getElementById('clear-btn');
307+
308+
// Generate all problems at start
309+
for (let i = 0; i < totalProblems; i++) {
310+
problems.push(generateProblem());
311+
}
289312

290-
// DOM elements
291-
const problemText = document.getElementById('problem-text');
292-
const optionsContainer = document.getElementById('options-container');
293-
const prevButton = document.getElementById('prev-btn');
294-
const nextButton = document.getElementById('next-btn');
295-
296-
// Scratchpad elements
297-
const scratchpadArea = document.getElementById('scratchpad-area');
298-
const scratchpadCanvas = document.getElementById('scratchpad');
299-
const toggleScratchpadBtn = document.getElementById('toggle-scratchpad');
300-
const closeScratchpadBtn = document.getElementById('close-scratchpad');
301-
const undoBtn = document.getElementById('undo-btn');
302-
const redoBtn = document.getElementById('redo-btn');
303-
const clearBtn = document.getElementById('clear-btn');
304-
305-
// Initialize scratchpad
306-
const scratchpad = new Scratchpad(scratchpadCanvas);
307-
308-
// Scratchpad control handlers
309-
toggleScratchpadBtn.onclick = () => {
310-
scratchpadArea.classList.add('open');
311-
toggleScratchpadBtn.style.display = 'none';
312-
requestAnimationFrame(() => {
313-
scratchpad.initialize();
314-
});
315-
};
313+
// Initialize scratchpad
314+
const scratchpad = new Scratchpad(scratchpadCanvas);
315+
scratchpad.initialize(); // Initialize scratchpad dimensions and context
316316

317-
closeScratchpadBtn.onclick = () => {
318-
scratchpadArea.classList.remove('open');
319-
toggleScratchpadBtn.style.display = 'block';
320-
};
317+
// Scratchpad control handlers
318+
toggleScratchpadBtn.onclick = () => {
319+
scratchpadArea.classList.toggle('open');
320+
toggleScratchpadBtn.textContent = scratchpadArea.classList.contains('open') ? '❌ Close Scratchpad' : '📝 Open Scratchpad';
321+
if (scratchpadArea.classList.contains('open')) {
322+
scratchpad.setCanvasSize(); // Ensure canvas size is correct when opened
323+
}
324+
};
321325

322-
undoBtn.onclick = () => scratchpad.undo();
323-
redoBtn.onclick = () => scratchpad.redo();
324-
clearBtn.onclick = () => scratchpad.clear();
326+
closeScratchpadBtn.onclick = () => {
327+
scratchpadArea.classList.remove('open');
328+
toggleScratchpadBtn.textContent = '📝 Open Scratchpad';
329+
};
325330

326-
// Event handlers
327-
function handleOptionClick(option, index) {
328-
const selectedAnswer = parseInt(option.textContent);
329-
330-
if (selectedAnswer === currentProblem.answer) {
331-
animationSystem.handleCorrectAnswer(option, optionsContainer.getElementsByClassName('option'), () => {
332-
if (currentProblemIndex < totalProblems - 1) {
333-
currentProblemIndex++;
334-
displayProblem();
331+
undoBtn.onclick = () => scratchpad.undo();
332+
redoBtn.onclick = () => scratchpad.redo();
333+
clearBtn.onclick = () => scratchpad.clear();
334+
335+
// Event handlers
336+
function handleOptionClick(option, index) {
337+
const selectedAnswer = parseInt(option.textContent);
338+
339+
// Prevent clicking after answer
340+
if(option.disabled) return;
341+
342+
if (selectedAnswer === currentProblem.answer) {
343+
animationSystem.handleCorrectAnswer(option, optionsContainer.getElementsByClassName('option'), () => {
344+
// Don't auto-advance, let user click next
345+
// if (currentProblemIndex < totalProblems - 1) {
346+
// currentProblemIndex++;
347+
// displayProblem();
348+
// }
349+
});
350+
} else {
351+
animationSystem.handleWrongAnswer(option);
352+
}
353+
}
354+
355+
function displayProblem() {
356+
currentProblem = problems[currentProblemIndex];
357+
problemText.textContent = currentProblem.text;
358+
359+
const options = optionsContainer.getElementsByClassName('option');
360+
// Ensure options container is cleared if structure changes (though unlikely here)
361+
// optionsContainer.innerHTML = '';
362+
Array.from(options).forEach((option, index) => {
363+
// Check if currentProblem.options exists and has enough elements
364+
if (currentProblem.options && currentProblem.options.length > index) {
365+
option.textContent = currentProblem.options[index];
366+
option.className = 'option'; // Reset classes
367+
option.disabled = false;
368+
option.onclick = () => handleOptionClick(option, index);
369+
} else {
370+
// Handle cases where there might be fewer options than buttons
371+
option.style.display = 'none'; // Hide unused buttons
335372
}
336373
});
337-
} else {
338-
animationSystem.handleWrongAnswer(option);
374+
375+
// Ensure all buttons are visible initially if needed
376+
Array.from(options).forEach(opt => { if(opt.style.display === 'none') opt.style.display = ''; });
377+
378+
// Update navigation buttons
379+
prevButton.disabled = currentProblemIndex === 0;
380+
// Allow next button even if it's the last generated problem (user might want to re-answer?)
381+
// nextButton.disabled = currentProblemIndex === totalProblems - 1;
382+
nextButton.disabled = false; // Allow clicking next to generate potentially new (if logic changes) or cycle
339383
}
340-
}
341384

342-
function displayProblem() {
343-
currentProblem = problems[currentProblemIndex];
344-
problemText.textContent = currentProblem.text;
345-
346-
const options = optionsContainer.getElementsByClassName('option');
347-
Array.from(options).forEach((option, index) => {
348-
option.textContent = currentProblem.options[index];
349-
option.className = 'option';
350-
option.disabled = false;
351-
option.onclick = () => handleOptionClick(option, index);
352-
});
353-
354-
// Update navigation buttons
355-
prevButton.disabled = currentProblemIndex === 0;
356-
nextButton.disabled = currentProblemIndex === totalProblems - 1;
357-
}
358-
359-
// Navigation handlers
360-
prevButton.onclick = () => {
361-
if (currentProblemIndex > 0) {
362-
currentProblemIndex--;
363-
displayProblem();
364-
}
365-
};
385+
// Navigation handlers
386+
prevButton.onclick = () => {
387+
if (currentProblemIndex > 0) {
388+
currentProblemIndex--;
389+
displayProblem();
390+
}
391+
};
366392

367-
nextButton.onclick = () => {
368-
if (currentProblemIndex < totalProblems - 1) {
369-
currentProblemIndex++;
393+
nextButton.onclick = () => {
394+
// Simple loop back for now, could regenerate problems
395+
currentProblemIndex = (currentProblemIndex + 1) % totalProblems;
370396
displayProblem();
371-
}
372-
};
397+
// if (currentProblemIndex < totalProblems - 1) {
398+
// currentProblemIndex++;
399+
// displayProblem();
400+
// }
401+
};
373402

374-
// Initialize the first problem
375-
displayProblem();
403+
// Initialize the first problem
404+
displayProblem();
376405

377-
// Initialize animation system if it doesn't exist
378-
// This is needed because animations.js creates the animationSystem instance
379-
if (typeof animationSystem === 'undefined') {
380-
class AnimationSystem {
381-
constructor() {
382-
this.starsContainer = document.getElementById('stars-container');
383-
}
384-
385-
// Create a star element with random properties
386-
createStar() {
387-
const star = document.createElement('div');
388-
star.className = 'star';
389-
star.textContent = '⭐';
390-
star.style.left = Math.random() * window.innerWidth + 'px';
391-
star.style.fontSize = `${Math.random() * 20 + 20}px`; // Random size between 20-40px
392-
star.style.animationDuration = `${Math.random() * 1.5 + 0.5}s`; // Random duration between 0.5-2s
393-
return star;
394-
}
395-
396-
// Handle correct answer animation
397-
handleCorrectAnswer(selectedOption, allOptions, callback) {
398-
// Disable all options
399-
Array.from(allOptions).forEach(option => {
400-
option.disabled = true;
401-
option.onclick = null;
402-
});
403-
404-
// Add correct class to the selected option
405-
selectedOption.classList.add('correct');
406-
407-
// Create and animate stars
408-
const numStars = 10; // Consistent number of stars for all problems
409-
for (let i = 0; i < numStars; i++) {
410-
const star = this.createStar();
411-
this.starsContainer.appendChild(star);
412-
setTimeout(() => {
413-
star.remove();
414-
}, 2000);
415-
}
416-
417-
// Wait for animation to complete before moving to next problem
418-
setTimeout(callback, 1000);
419-
}
420-
421-
// Handle wrong answer animation
422-
handleWrongAnswer(option) {
423-
option.classList.add('wrong');
424-
setTimeout(() => option.classList.remove('wrong'), 500);
425-
}
426-
}
427-
428-
// Create a global instance
429-
window.animationSystem = new AnimationSystem();
430-
}
406+
// Removed the redundant AnimationSystem check/definition block
407+
});

metric-units-length.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ <h1>Fun Math Problems! 🎨</h1>
4040
Appropriate Metric Unit of Length
4141
</div>
4242
<div class="stars" id="stars-container"></div>
43-
<script src="animations.js"></script>
44-
<script src="metric-units-length.js"></script>
43+
<script src="animations.js" type="module" defer></script>
44+
<script src="metric-units-length.js" type="module" defer></script>
4545
</body>
4646
</html>

metric-units-length.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { animationSystem } from './animations.js';
2+
13
// Scratchpad functionality
24
class Scratchpad {
35
constructor(canvas) {

0 commit comments

Comments
 (0)