1f3af8f7f5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31 lines
968 B
TypeScript
31 lines
968 B
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef } from "react";
|
|
|
|
const FPS = 24;
|
|
const pad = (n: number) => String(n).padStart(2, "0");
|
|
|
|
// A running SMPTE-style timecode, written straight to the DOM to avoid re-renders.
|
|
export default function Timecode({ className = "" }: { className?: string }) {
|
|
const ref = useRef<HTMLSpanElement>(null);
|
|
|
|
useEffect(() => {
|
|
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
|
const start = performance.now() - 1001 * (1000 / FPS);
|
|
const id = window.setInterval(() => {
|
|
const f = Math.floor(((performance.now() - start) / 1000) * FPS);
|
|
const s = Math.floor(f / FPS);
|
|
if (ref.current) {
|
|
ref.current.textContent = `01:${pad(Math.floor(s / 60) % 60)}:${pad(s % 60)}:${pad(f % FPS)}`;
|
|
}
|
|
}, 1000 / FPS);
|
|
return () => window.clearInterval(id);
|
|
}, []);
|
|
|
|
return (
|
|
<span ref={ref} className={`tabular-nums ${className}`}>
|
|
01:00:41:17
|
|
</span>
|
|
);
|
|
}
|