import { useEffect, useRef, useState } from 'react'; import { useGlobalSettings } from '../../../Hooks/useGlobalSettings'; import { usePlayers } from '../../../Hooks/usePlayers'; type TouchPoint = { x: number; y: number; id: number; }; const getOrientation = () => { return window.matchMedia('(orientation: portrait)').matches ? 'portrait' : 'landscape'; }; const ANIMATION_INTRO_LENGTH = 500; const BEFORE_INTRO_TIMER_LENGTH = 100; export const FingerGame = () => { const { players } = usePlayers(); const aboutToStartTimerRef = useRef(null); const selectingPlayerTimerRef = useRef(null); const [touchPoints, setTouchPoints] = useState([]); const [selectedTouchPoint, setSelectedTouchPoint] = useState< TouchPoint | undefined >(); const [timerStarted, setTimerStarted] = useState(false); const { setPlaying, goToStart } = useGlobalSettings(); useEffect(() => { //Start playing when someone is selected and any touch point is released if (selectedTouchPoint && touchPoints.length !== players.length) { aboutToStartTimerRef.current = setTimeout(() => { setSelectedTouchPoint(undefined); setPlaying(true); }, ANIMATION_INTRO_LENGTH); setTimerStarted(true); return; } // If no touch point is selected, select one with a delay if (touchPoints.length === players.length && !selectedTouchPoint) { selectingPlayerTimerRef.current = setTimeout(() => { const randomIndex = Math.floor(Math.random() * touchPoints.length); const randomTouchPoint = touchPoints[randomIndex]; setSelectedTouchPoint(randomTouchPoint); }, BEFORE_INTRO_TIMER_LENGTH); return; } if (selectingPlayerTimerRef.current) { clearTimeout(selectingPlayerTimerRef.current); } return () => { if (aboutToStartTimerRef.current) { clearTimeout(aboutToStartTimerRef.current); } }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [touchPoints, players.length]); const handleOnTouchStart = (e: React.TouchEvent) => { if (selectedTouchPoint) { return; } //Get the first touch point id that isn't already in the touchPoints array const touch = Array.from(e.changedTouches).find( (t) => !touchPoints.find((p) => p.id === t.identifier) ); if (!touch) { console.error('No touch found'); return; } let { clientX, clientY } = touch; // Adjust coordinates for portrait mode if (getOrientation() === 'portrait') { const tempX = clientX; clientX = clientY; clientY = window.innerWidth - tempX; } const newTouchPoints = { x: clientX, y: clientY, id: touch.identifier, }; setTouchPoints([...touchPoints, newTouchPoints]); }; const handleOnTouchEnd = (e: React.TouchEvent) => { if (selectedTouchPoint) { aboutToStartTimerRef.current = setTimeout(() => { setSelectedTouchPoint(undefined); setPlaying(true); }, ANIMATION_INTRO_LENGTH); setTimerStarted(true); return; } // Get the touch point that was just released const touch = e.changedTouches[e.changedTouches.length - 1]; // Get the index of the touch point that was just released const index = touchPoints.findIndex((p) => p.id === touch.identifier); // Remove the touch point that was just released setTouchPoints([ ...touchPoints.slice(0, index), ...touchPoints.slice(index + 1), ]); }; return (
{ // e.preventDefault(); // // Get the touch point that was just moved // const touch = Array.from(e.changedTouches).find((t) => // touchPoints.find((p) => p.id === t.identifier) // ); // if (!touch) { // console.error('No touch found'); // return; // } // let { clientX, clientY } = touch; // // Adjust coordinates for portrait mode // if (getOrientation() === 'portrait') { // const tempX = clientX; // clientX = clientY; // clientY = window.innerWidth - tempX; // } // // Get the index of the touch point that was just moved // const index = touchPoints.findIndex( // (p) => p.id === touch.identifier // ); // // Update the touch point that was just moved // setTouchPoints([ // ...touchPoints.slice(0, index), // { x: clientX, y: clientY, id: touch.identifier }, // ...touchPoints.slice(index + 1), // ]); // }} > {touchPoints.length !== players.length && (
Waiting for fingers
{touchPoints.length}/{players.length}
)} {touchPoints.map((point, index) => (
))}
); };