/** * Pure, frame-driven binary effects. Remotion renders frame by frame, so nothing here * uses timers or randomness: the same inputs always give the same output. */ const HASH_MULTIPLIER = 2654435761; const TICK_MULTIPLIER = 40503; const LETTER_OR_DIGIT = /[A-Za-z0-9]/; const clamp01 = (n: number): number => Math.min(1, Math.max(0, n)); /** A stable pseudo-random bit for a position at a given tick. */ const bitAt = (index: number, tick: number): "0" | "1" => { const hash = Math.imul(index + 1, HASH_MULTIPLIER) ^ Math.imul(tick + 1, TICK_MULTIPLIER); return ((hash >>> 7) & 1) === 0 ? "0" : "1"; }; /** * Text resolving from digits, left to right. Letters and numbers not yet reached show * as 0 or 1; spaces and punctuation stay put so the shape of the text is readable. */ export const decodeText = (text: string, progress: number, tick: number): string => { const chars = Array.from(text); const revealed = Math.floor(clamp01(progress) * chars.length); return chars .map((char, index) => index < revealed || !LETTER_OR_DIGIT.test(char) ? char : bitAt(index, tick), ) .join(""); }; /** A string of `length` binary digits for a given tick. */ export const bitString = (length: number, tick: number): string => Array.from({ length }, (_, index) => bitAt(index, tick)).join("");