{"version":3,"file":"use-live-luminance.cjs","names":[],"sources":["../../src/vision/use-live-luminance.ts"],"sourcesContent":["import { useEffect, useRef, useState, type RefObject } from \"react\";\nimport { computeImageLuminance } from \"./luminance\";\n\n/** Options for {@link useLiveLuminance}. */\nexport interface UseLiveLuminanceOptions {\n    /** When `false` the loop is paused (e.g. while a capture is in flight). Default: `true`. */\n    enabled?: boolean;\n    /** Throttle measurements in milliseconds. Default: `160` (~6 fps), plenty for UX. */\n    intervalMs?: number;\n}\n\n/**\n * Sample mean luminance from a `<video>` source on a `requestAnimationFrame`\n * loop and expose the rolling value. Sampling is throttled by `intervalMs` and\n * paused whenever `enabled` is `false` or the video is not ready yet\n * (`readyState < 2` or `videoWidth === 0`).\n *\n * One offscreen canvas is reused across frames to avoid GC pressure. Designed\n * to feed a live brightness bar / border color on a camera page.\n *\n * @param videoRef - ref to the `<video>` element to sample.\n * @param options - optional configuration (see {@link UseLiveLuminanceOptions}).\n * @returns The rolling mean luminance in `0..255` (`0` until the first sample).\n */\nexport function useLiveLuminance(\n    videoRef: RefObject<HTMLVideoElement | null>,\n    { enabled = true, intervalMs = 160 }: UseLiveLuminanceOptions = {},\n): number {\n    const [luminance, setLuminance] = useState(0);\n    const canvasRef = useRef<HTMLCanvasElement | null>(null);\n\n    useEffect(() => {\n        if (!enabled) return;\n        if (typeof window === \"undefined\") return;\n        if (!canvasRef.current) canvasRef.current = document.createElement(\"canvas\");\n\n        let rafId = 0;\n        let lastSampledAt = 0;\n\n        const tick = (timestamp: number): void => {\n            const video = videoRef.current;\n            if (!video || video.readyState < 2 || video.videoWidth === 0) {\n                rafId = window.requestAnimationFrame(tick);\n                return;\n            }\n            if (timestamp - lastSampledAt >= intervalMs) {\n                lastSampledAt = timestamp;\n                setLuminance(computeImageLuminance(video, canvasRef.current ?? undefined));\n            }\n            rafId = window.requestAnimationFrame(tick);\n        };\n\n        rafId = window.requestAnimationFrame(tick);\n        return () => window.cancelAnimationFrame(rafId);\n    }, [videoRef, enabled, intervalMs]);\n\n    return luminance;\n}\n"],"mappings":"0DAwBA,SAAgB,EACZ,EACA,CAAE,UAAU,GAAM,aAAa,KAAiC,CAAC,EAC3D,CACN,GAAM,CAAC,EAAW,IAAA,EAAgB,EAAA,SAAA,CAAS,CAAC,EACtC,GAAA,EAAY,EAAA,OAAA,CAAiC,IAAI,EA2BvD,OAzBA,EAAA,EAAA,UAAA,KAAgB,CAEZ,GADI,CAAC,GACD,OAAO,OAAW,IAAa,OACnC,AAAwB,EAAU,UAAU,SAAS,cAAc,QAAQ,EAE3E,IAAI,EAAQ,EACR,EAAgB,EAEd,EAAQ,GAA4B,CACtC,IAAM,EAAQ,EAAS,QACvB,GAAI,CAAC,GAAS,EAAM,WAAa,GAAK,EAAM,aAAe,EAAG,CAC1D,EAAQ,OAAO,sBAAsB,CAAI,EACzC,MACJ,CACI,EAAY,GAAiB,IAC7B,EAAgB,EAChB,EAAa,EAAA,sBAAsB,EAAO,EAAU,SAAW,IAAA,EAAS,CAAC,GAE7E,EAAQ,OAAO,sBAAsB,CAAI,CAC7C,EAGA,MADA,GAAQ,OAAO,sBAAsB,CAAI,MAC5B,OAAO,qBAAqB,CAAK,CAClD,EAAG,CAAC,EAAU,EAAS,CAAU,CAAC,EAE3B,CACX"}