{"version":3,"file":"index.modern.mjs","sources":["../src/index.js"],"sourcesContent":["import { useEffect, useRef } from 'react'\nimport { useInterval } from 'usehooks-ts'\n\n// by default, expect a positioned parent for the canvas\n// img will render behind it\nconst IMG_STYLE = 'position: absolute; top: 0; left: 0; z-index: 0;'\nconst CANVAS_STYLE = 'position: absolute; top: 0; left: 0; z-index: 1;'\n\n/**\n * Outputs an image from a canvas.\n * By default, the image renders behind the canvas on the z axis.\n * This behavior can be overridden with custom styles.\n *\n * @param {HTMLCanvasElement|String} canvas React ref/HTML element or string selector. If string, must be unique in dom and formatted as selector (#id, .class, [attr=\"val\"], etc)\n * @param {String} imgClassname for styling output image, space separated.\n * @param {String} canvasClassName for adding .fs-exclude, etc., and styling, space separated.\n * @param {Object} canvasAttributes for adding data-private, etc\n * @param {String} fileType what img format to output. default, recommended: image/jpeg\n * @param {Number} quality 0-1. the compression quality. only applies to image/jpeg or image/webp. default: 0.5\n * @param {Number} interval ms. how often to update the image. default: 100\n * @returns {Function} function to be called any time the canvas is drawn on\n */\nconst useCanvasImage = ({\n  canvas,\n  imgClassname = '',\n  canvasClassname = '',\n  canvasAttributes = {},\n  fileType = 'image/jpeg', // fullstory doesn't like png\n  quality = 0.7,\n  interval = null,\n}) => {\n  const canvasRef = useRef()\n  const imgRef = useRef()\n\n  const createImg = () => {\n    // create image\n    imgRef.current = new Image()\n\n    // add classes to img\n    if (imgClassname) imgRef.current.classList.add(...imgClassname.split(' '))\n\n    // by default, img will be same size as canvas\n    imgRef.current.style = IMG_STYLE\n  }\n\n  const updateCanvas = () => {\n    // add attributes to canvas\n    Object.keys(canvasAttributes).forEach(attr => {\n      canvasRef.current.setAttribute(attr, canvasAttributes[attr])\n    })\n\n    // add classes to canvas\n    if (canvasClassname)\n      canvasRef.current.classList.add(...canvasClassname.split(' '))\n\n    canvasRef.current.style = CANVAS_STYLE\n\n    createImg()\n    // insert img after canvas\n    canvasRef.current.after(imgRef.current)\n  }\n\n  const createImgSrc = () => {\n    requestAnimationFrame(() => {\n      if (!canvasRef.current || !imgRef.current) return\n\n      // generate new img src\n      const dataUrl = canvasRef.current.toDataURL(fileType, quality)\n\n      // set src on img\n      imgRef.current.src = dataUrl\n    })\n  }\n\n  useEffect(() => {\n    let reselectTimeout\n\n    const setCanvas = () => {\n      if (typeof canvas === 'string') {\n        // selector\n        canvasRef.current = document.querySelector(canvas)\n      } else if (canvas?.current instanceof HTMLCanvasElement) {\n        // ref\n        canvasRef.current = canvas.current\n      } else if (canvas instanceof HTMLCanvasElement) {\n        // canvas element\n        canvasRef.current = canvas\n      }\n\n      if (canvasRef.current) {\n        updateCanvas()\n      } else {\n        reselectTimeout = setTimeout(setCanvas, 100)\n      }\n    }\n\n    setCanvas()\n\n    // eslint-disable-next-line consistent-return\n    return () => {\n      if (reselectTimeout) clearTimeout(reselectTimeout)\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [])\n\n  // for interval-based update\n  // passing `interval: null` disables\n  // requires `preserveDrawingBuffer: true` on webgl context\n  // don't use return function in this case\n  useInterval(createImgSrc, interval)\n\n  // function returned for explicit updates from component\n  // ensure the return function isn't used in conjunction with intervals\n  return interval === null || interval === false ? createImgSrc : null\n}\n\nexport default useCanvasImage\n"],"names":["useCanvasImage","canvas","imgClassname","canvasClassname","canvasAttributes","fileType","quality","interval","canvasRef","useRef","imgRef","createImgSrc","requestAnimationFrame","current","dataUrl","toDataURL","src","useEffect","reselectTimeout","setCanvas","document","querySelector","Object","keys","forEach","attr","setAttribute","classList","add","split","style","Image","after","setTimeout","clearTimeout","useInterval"],"mappings":"wFAKA,MAiBMA,EAAiB,EACrBC,SACAC,aAAAA,EAAe,GACfC,gBAAAA,EAAkB,GAClBC,iBAAAA,EAAmB,GACnBC,SAAAA,EAAW,aACXC,QAAAA,EAAU,GACVC,SAAAA,EAAW,SAEX,MAAeC,EAAGC,IACNC,EAAGD,IA8BGE,EAAG,KACnBC,sBAAsB,KACpB,IAAKJ,EAAUK,UAAYH,EAAOG,QAAS,OAG3C,MAAMC,EAAUN,EAAUK,QAAQE,UAAUV,EAAUC,GAGtDI,EAAOG,QAAQG,IAAMF,KA2CzB,OAvCAG,EAAU,KACR,IAAIC,EAEJ,MAAMC,EAAY,KACM,iBAAXlB,EAETO,EAAUK,QAAUO,SAASC,cAAcpB,IAClCA,aAAAA,EAAAA,EAAQY,qCAEjBL,EAAUK,QAAUZ,EAAOY,QAClBZ,iCAETO,EAAUK,QAAUZ,GAGlBO,EAAUK,SA1ChBS,OAAOC,KAAKnB,GAAkBoB,QAAQC,IACpCjB,EAAUK,QAAQa,aAAaD,EAAMrB,EAAiBqB,MAIpDtB,GACFK,EAAUK,QAAQc,UAAUC,OAAOzB,EAAgB0B,MAAM,MAE3DrB,EAAUK,QAAQiB,MAjDD,mDA8BjBpB,EAAOG,QAAU,IAAjBkB,MAGI7B,GAAcQ,EAAOG,QAAQc,UAAUC,OAAO1B,EAAa2B,MAAM,MAGrEnB,EAAOG,QAAQiB,MArCD,mDAsDdtB,EAAUK,QAAQmB,MAAMtB,EAAOG,UAiC3BK,EAAkBe,WAAWd,EAAW,MAO5C,OAHAA,IAGO,KACDD,GAAiBgB,aAAahB,KAGnC,IAMHiB,EAAYxB,EAAcJ,GAIN,OAAbA,IAAkC,IAAbA,EAAqBI,EAAe"}