Webbserver - Love Blomberg

Show sourcecode

The following files exists in this folder. Click to view.

public_html/GYA2/js/

common.js
maze.js
reaction.js
simon.js

reaction.js

116 lines UTF-8 Unix (LF)
'use strict';

(function() {
    const pid = getParticipantId();
    const screen = document.getElementById('screen');
    const msgEl = document.getElementById('message');
    const subEl = document.getElementById('sub-message');
    const overlay = document.getElementById('reaction-instructions-overlay');

    let state = 'WAITING';  // WAITING | COUNTDOWN | READY | RESULT
    let currentRound = 1;
    let delayTimer = null;
    let currentDelay = 0;
    let tStart = 0;

    function setScreen(cls, msg, sub) {
        screen.className = 'reaction-screen ' + cls;
        msgEl.textContent = msg;
        subEl.textContent = sub || '';
    }

    function randomDelay() {
        return MIN_DELAY + Math.floor(Math.random() * (MAX_DELAY - MIN_DELAY));
    }

    async function saveRound(roundNum, reactionMs, premature, delay) {
        try {
            await apiPost('../api/save_reaction.php', {
                participant_id: pid,
                round_number: roundNum,
                reaction_ms: reactionMs,
                was_premature: premature ? 1 : 0,
                delay_ms: delay
            });
        } catch (e) {
            console.error('Failed to save reaction round:', e);
        }
    }

    function startCountdown() {
        state = 'COUNTDOWN';
        currentDelay = randomDelay();
        setScreen('countdown', 'Vänta på grönt...', 'Runda ' + currentRound + ' av ' + TOTAL_ROUNDS);

        delayTimer = setTimeout(function() {
            state = 'READY';
            tStart = performance.now();
            setScreen('ready', 'KLICKA NU!', 'Runda ' + currentRound + ' av ' + TOTAL_ROUNDS);
        }, currentDelay);
    }

    async function handleInput() {
        if (state === 'WAITING') {
            startCountdown();
            return;
        }

        if (state === 'COUNTDOWN') {
            clearTimeout(delayTimer);
            setScreen('countdown', 'För tidigt!', 'Vänta på den gröna skärmen...');
            await saveRound(currentRound, 0, true, currentDelay);

            setTimeout(function() {
                state = 'WAITING';
                setScreen('waiting', 'Klicka eller tryck mellanslag för att försöka igen Runda ' + currentRound, 'Runda ' + currentRound + ' av ' + TOTAL_ROUNDS);
            }, 1500);
            return;
        }

        if (state === 'READY') {
            const reactionMs = Math.round(performance.now() - tStart);
            state = 'RESULT';
            setScreen('result', reactionMs + ' ms', 'Runda ' + currentRound + ' av ' + TOTAL_ROUNDS);

            const times = JSON.parse(sessionStorage.getItem('reaction_times') || '[]');
            times.push(reactionMs);
            sessionStorage.setItem('reaction_times', JSON.stringify(times));

            await saveRound(currentRound, reactionMs, false, currentDelay);

            setTimeout(function() {
                currentRound++;
                if (currentRound > TOTAL_ROUNDS) {
                    window.location.href = 'maze.php';
                } else {
                    state = 'WAITING';
                    setScreen('waiting', 'Klicka eller tryck mellanslag för att börja Runda ' + currentRound, 'Runda ' + currentRound + ' av ' + TOTAL_ROUNDS);
                }
            }, 1500);
            return;
        }
    }

    // Click handler
    screen.addEventListener('click', handleInput);

    // Spacebar handler
    document.addEventListener('keydown', function(e) {
        if (e.code === 'Space' && screen.style.display !== 'none') {
            e.preventDefault();
            handleInput();
        }
    });

    // Instruction overlay dismiss
    if (overlay) {
        function dismissOverlay() {
            overlay.style.display = 'none';
            screen.style.display = '';
        }
        document.getElementById('reaction-start-btn').addEventListener('click', dismissOverlay);
    } else {
        screen.style.display = '';
    }
})();