UNPKG

use-video-interval

Version:

A React hook for executing a callback at customizable intervals during video playback.

1 lines 4.73 kB
{"version":3,"file":"index.mjs","sources":["../src/hooks/useVideoInterval.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { useVideoIntervalProps } from '../types/use-video-interval';\n\n/**\n * useVideoInterval\n *\n * @example\n * ```tsx\n * import { useRef, useState } from 'react';\n *\n * function App() {\n * \tconst videoRef = useRef<HTMLVideoElement>( null );\n * \tconst [ showOverlay, setShowOverlay ] = useState( false );\n *\n * \tuseVideoInterval( videoRef, {\n * \t\t3: () => setShowOverlay( true ),\n * \t\t8: () => alert( 'This is 8 seconds!' ),\n * \t\t15: () => console.log( 'Reached 15s mark' )\n * \t});\n *\n * \treturn (\n * \t\t<>\n * \t\t\t<video ref={ videoRef } src=\"\" />\n * \t\t\t{ showOverlay && <Overlay /> }\n * \t\t</>\n * \t);\n * }\n * ```\n *\n * @param videoRef - A reference to the video element.\n * @param intervalCallbacks - An object containing interval numbers as keys and callback functions as values.\n * @param options(optional) - An object containing options for the hook.\n * @return {void}\n *\n */\nexport function useVideoInterval(props: useVideoIntervalProps): void {\n\tconst { videoRef, intervalCallbacks, options } = props;\n\tconst { threshold = 0.5, triggerOnce = true } = options || {};\n\tconst previousTriggeredIntervals = useRef<Set<number>>(new Set());\n\n\t/**\n\t * onTimeUpdated\n\t *\n\t * Takes a video element, iterates through the marked times and\n\t * executes the interval callback if the current time lies within the\n\t * specified threshold.\n\t *\n\t * @param video - The video element to check the current time of.\n\t * @returns {void}\n\t */\n\tconst onTimeUpdated = useCallback(\n\t\t(video: HTMLVideoElement) => {\n\t\t\tconst currentTime = video.currentTime;\n\n\t\t\tfor (const [interval, callback] of Object.entries(intervalCallbacks)) {\n\t\t\t\tconst parsedInterval = parseFloat(interval);\n\t\t\t\tconst delta = Math.abs(currentTime - parsedInterval);\n\t\t\t\tconst previouslyTriggered =\n\t\t\t\t\tpreviousTriggeredIntervals.current.has(parsedInterval);\n\t\t\t\tconst shouldTrigger =\n\t\t\t\t\tdelta <= threshold && (!triggerOnce || !previouslyTriggered);\n\n\t\t\t\tif (shouldTrigger) {\n\t\t\t\t\tcallback();\n\n\t\t\t\t\tif (triggerOnce) {\n\t\t\t\t\t\tpreviousTriggeredIntervals.current.add(parsedInterval);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[intervalCallbacks, threshold, triggerOnce],\n\t);\n\n\t/**\n\t * Sets up the `timeupdate` event listener on the video element.\n\t */\n\tuseEffect(() => {\n\t\t// Bail out if the videoRef is not set.\n\t\tconst video = videoRef.current;\n\t\tconst previousTriggeredIntervalsCurrent =\n\t\t\tpreviousTriggeredIntervals.current;\n\n\t\tif (!video) {\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Create an event listener that calls `onTimeUpdated` with the video element.\n\t\t * This is necessary to avoid creating a new function on every render.\n\t\t */\n\t\tconst eventListener = () => onTimeUpdated(video);\n\n\t\tvideo.addEventListener('timeupdate', eventListener);\n\t\treturn () => {\n\t\t\tvideo.removeEventListener('timeupdate', eventListener);\n\t\t\tpreviousTriggeredIntervalsCurrent.clear();\n\t\t};\n\t}, [onTimeUpdated]);\n\n\t/**\n\t * Resets the previous triggered intervals when the intervalCallbacks change.\n\t */\n\tuseEffect(() => {\n\t\tpreviousTriggeredIntervals.current.clear();\n\t}, [intervalCallbacks]);\n}\n"],"names":["useVideoInterval","props","videoRef","intervalCallbacks","_a","_b","threshold","_c","triggerOnce","previousTriggeredIntervals","useRef","Set","onTimeUpdated","useCallback","video","currentTime","_i","Object","entries","length","interval","callback","parsedInterval","parseFloat","delta","Math","abs","previouslyTriggered","current","has","add","useEffect","previousTriggeredIntervalsCurrent","eventListener","addEventListener","removeEventListener","clear"],"mappings":"+DAmCM,SAAUA,EAAiBC,GACxB,IAAAC,EAAyCD,EAAKC,SAApCC,EAA+BF,EAAKE,kBAChDC,EAD2CH,WACU,GAAnDI,EAAAD,EAAAE,UAAAA,OAAS,IAAAD,EAAG,GAAGA,EAAEE,EAAkBH,EAAAI,YAAlBA,OAAc,IAAAD,KACjCE,EAA6BC,EAAoB,IAAIC,KAYrDC,EAAgBC,GACrB,SAACC,GAGA,IAFA,IAAMC,EAAcD,EAAMC,YAE0CC,EAAA,EAAjCZ,EAAAa,OAAOC,QAAQf,GAAfa,EAAAZ,EAAAe,OAAAH,IAAmC,CAA3D,IAAAX,OAACe,EAAQf,EAAA,GAAEgB,EAAQhB,EAAA,GACvBiB,EAAiBC,WAAWH,GAC5BI,EAAQC,KAAKC,IAAIX,EAAcO,GAC/BK,EACLlB,EAA2BmB,QAAQC,IAAIP,GAEvCE,GAASlB,KAAeE,IAAgBmB,KAGxCN,IAEIb,GACHC,EAA2BmB,QAAQE,IAAIR,IAI1C,GACD,CAACnB,EAAmBG,EAAWE,IAMhCuB,GAAU,WAET,IAAMjB,EAAQZ,EAAS0B,QACjBI,EACLvB,EAA2BmB,QAE5B,GAAKd,EAAL,CAQA,IAAMmB,EAAgB,WAAM,OAAArB,EAAcE,EAAM,EAGhD,OADAA,EAAMoB,iBAAiB,aAAcD,GAC9B,WACNnB,EAAMqB,oBAAoB,aAAcF,GACxCD,EAAkCI,OAClC,EACF,GAAG,CAACxB,IAKJmB,GAAU,WACTtB,EAA2BmB,QAAQQ,OACpC,GAAG,CAACjC,GACL"}