From 0741a8b8e9a2099c82bff6d6b9ebbce9c07cad53 Mon Sep 17 00:00:00 2001 From: soryu Date: Mon, 22 Dec 2025 04:50:25 +0000 Subject: Update makima FE to add initial listening system --- makima/frontend/src/hooks/useTextScramble.ts | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 makima/frontend/src/hooks/useTextScramble.ts (limited to 'makima/frontend/src/hooks/useTextScramble.ts') diff --git a/makima/frontend/src/hooks/useTextScramble.ts b/makima/frontend/src/hooks/useTextScramble.ts new file mode 100644 index 0000000..bb3f365 --- /dev/null +++ b/makima/frontend/src/hooks/useTextScramble.ts @@ -0,0 +1,52 @@ +import { useState, useCallback, useRef } from "react"; + +const GLYPHS = "▒▓░█#@*+:-/[]{}<>_"; + +export function useTextScramble(originalText: string) { + const [displayText, setDisplayText] = useState(originalText); + const timerRef = useRef | null>(null); + const iterationRef = useRef(0); + + const scramble = useCallback(() => { + // Clear any existing animation + if (timerRef.current) { + clearInterval(timerRef.current); + } + + iterationRef.current = 0; + + timerRef.current = setInterval(() => { + const text = originalText; + const iteration = iterationRef.current; + + const display = text + .split("") + .map((char, index) => { + if (index < iteration) return char; + return GLYPHS.charAt(Math.floor(Math.random() * GLYPHS.length)); + }) + .join(""); + + setDisplayText(display); + iterationRef.current += 1; + + if (iteration > text.length + 2) { + if (timerRef.current) { + clearInterval(timerRef.current); + timerRef.current = null; + } + setDisplayText(originalText); + } + }, 26); + }, [originalText]); + + const reset = useCallback(() => { + if (timerRef.current) { + clearInterval(timerRef.current); + timerRef.current = null; + } + setDisplayText(originalText); + }, [originalText]); + + return { displayText, scramble, reset }; +} -- cgit v1.2.3