1+ import { animationSystem } from './animations.js' ;
2+
13// Scratchpad functionality
24class Scratchpad {
35 constructor ( canvas ) {
@@ -282,149 +284,124 @@ let currentProblemIndex = 0;
282284const problems = [ ] ;
283285const 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+ } ) ;
0 commit comments