{"version":3,"file":"index.esm.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","_ref","canvas","imgClassname","_ref$imgClassname","canvasClassname","_ref$canvasClassname","canvasAttributes","_ref$canvasAttributes","fileType","_ref$fileType","quality","_ref$quality","interval","_ref$interval","useRef","createImgSrc","requestAnimationFrame","canvasRef","current","imgRef","dataUrl","toDataURL","src","useEffect","_imgRef$current$class","document","querySelector","HTMLCanvasElement","Object","keys","forEach","attr","setAttribute","classList","add","split","style","Image","after","reselectTimeout","setTimeout","setCanvas","clearTimeout","useInterval"],"mappings":"wFAKA,IAiBoBA,EAAG,SAAAC,OAQjBC,EAAAD,EAPJC,OACAC,EAAAA,EAAAA,aAAAA,OAMI,IAAAC,EANW,GACfC,EAAAA,EAAAA,EAAAA,gBAAAA,OAKI,IAAAC,EALc,GAClBC,EAAAA,EAAAA,EAAAA,iBAAAA,OAII,IAAAC,EAJe,GACnBC,EAAAA,EAAAA,EAAAA,SAAAA,OAGI,IAAAC,EAHO,aACXC,EAAAA,EAAAA,EAAAA,QAAAA,OAEI,IAAAC,EAFM,GACVC,EAAAA,EAAAA,EAAAA,SAAAA,OACI,IAAAC,EADO,KAEXA,IAAkBC,MACHA,IA8BTC,EAAe,WACnBC,sBAAsB,WACpB,GAAKC,EAAUC,SAAYC,EAAOD,QAAlC,CAGA,IAAaE,EAAGH,EAAUC,QAAQG,UAAUb,EAAUE,GAGtDS,EAAOD,QAAQI,IAAMF,MA2CzB,OAvCAG,EAAU,WACR,MAwBA,OAtBkB,aAhCC,MAXGC,EA4CE,iBAAXvB,EAETgB,EAAUC,QAAUO,SAASC,cAAczB,IAClCA,eAAAA,EAAQiB,mBAAmBS,kBAEpCV,EAAUC,QAAUjB,EAAOiB,QAClBjB,aAAkB0B,oBAE3BV,EAAUC,QAAUjB,GAGlBgB,EAAUC,SA1ChBU,OAAOC,KAAKvB,GAAkBwB,QAAQ,SAAAC,GACpCd,EAAUC,QAAQc,aAAaD,EAAMzB,EAAiByB,MAIpD3B,IACFa,EAAAA,EAAUC,QAAQe,WAAUC,YAAO9B,EAAgB+B,MAAM,MAE3DlB,EAAUC,QAAQkB,MAjDD,mDA8BjBjB,EAAOD,QAAU,IAAImB,MAGjBnC,IAAcsB,EAAAL,EAAOD,QAAQe,WAAUC,IAAOhC,MAAAA,EAAAA,EAAaiC,MAAM,MAGrEhB,EAAOD,QAAQkB,MArCD,mDAsDdnB,EAAUC,QAAQoB,MAAMnB,EAAOD,UAiC3BqB,EAAkBC,WAAWC,EAAW,KAI5CA,cAIMF,GAAiBG,aAAaH,KAGnC,IAMHI,EAAY5B,EAAcH,GAIN,OAAbA,IAAkC,IAAbA,EAAqBG,EAAe"}