react-image-map-resizer
Version:
This is a simple library that makes HTML Image Maps responsive, so that they automatically stay scaled to the size of the image they are attached to using a React hook and native html img and map elements.
1 lines • 6.78 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/hooks/useImageMapResize.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\r\n\r\nconst useImageMapResize = (mapName: string) => {\r\n const mapRef = useRef<HTMLMapElement>(null);\r\n const originalCoordsRef = useRef<string[]>([]);\r\n const resizeTimeoutRef = useRef<number>(100);\r\n\r\n useEffect(() => {\r\n const resizeMap = () => {\r\n if (!mapRef.current) return;\r\n\r\n const map = mapRef.current;\r\n const areas = map.getElementsByTagName(\r\n \"area\"\r\n ) as HTMLCollectionOf<HTMLAreaElement>;\r\n const img = document.querySelector(\r\n `img[usemap=\"#${mapName}\"]`\r\n ) as HTMLImageElement;\r\n\r\n if (!img || !img.complete) {\r\n // If image is not loaded yet, wait for it\r\n img?.addEventListener(\"load\", resizeMap, { once: true });\r\n return;\r\n }\r\n\r\n // Store original coordinates on first run\r\n if (originalCoordsRef.current.length === 0 && areas.length > 0) {\r\n originalCoordsRef.current = Array.from(areas).map(\r\n (area: HTMLAreaElement) => area.getAttribute(\"coords\") || \"\"\r\n );\r\n }\r\n\r\n const ratio = {\r\n width: img.width / img.naturalWidth,\r\n height: img.height / img.naturalHeight,\r\n };\r\n\r\n // Get computed styles for padding\r\n const computedStyle = window.getComputedStyle(img);\r\n const padding = {\r\n width:\r\n parseInt(computedStyle.getPropertyValue(\"padding-left\"), 10) || 0,\r\n height:\r\n parseInt(computedStyle.getPropertyValue(\"padding-top\"), 10) || 0,\r\n };\r\n\r\n // Apply resize to each area using original coordinates\r\n Array.from(areas).forEach((area: HTMLAreaElement, index) => {\r\n // Use original coordinates to prevent cumulative errors\r\n const originalCoords =\r\n originalCoordsRef.current[index]?.split(\",\") || [];\r\n\r\n if (originalCoords.length === 0) return;\r\n\r\n const newCoords = originalCoords\r\n .map((coord, i) => {\r\n const dimension = i % 2 === 0 ? \"width\" : \"height\";\r\n return (\r\n padding[dimension] + Math.floor(Number(coord) * ratio[dimension])\r\n );\r\n })\r\n .join(\",\");\r\n\r\n area.setAttribute(\"coords\", newCoords);\r\n });\r\n };\r\n\r\n const debouncedResize = () => {\r\n clearTimeout(resizeTimeoutRef.current);\r\n resizeTimeoutRef.current = window.setTimeout(resizeMap, 100); // Reduced timeout for more responsive feel\r\n };\r\n\r\n // Create a ResizeObserver to watch for image size changes\r\n if (typeof ResizeObserver !== \"undefined\") {\r\n const img = document.querySelector(\r\n `img[usemap=\"#${mapName}\"]`\r\n ) as HTMLImageElement;\r\n\r\n if (img) {\r\n const resizeObserver = new ResizeObserver(debouncedResize);\r\n resizeObserver.observe(img);\r\n\r\n // Cleanup ResizeObserver\r\n return () => {\r\n resizeObserver.disconnect();\r\n window.removeEventListener(\"resize\", debouncedResize);\r\n window.removeEventListener(\"focus\", resizeMap);\r\n window.removeEventListener(\"readystatechange\", resizeMap);\r\n document.removeEventListener(\"fullscreenchange\", resizeMap);\r\n };\r\n }\r\n }\r\n\r\n // Initial resize\r\n resizeMap();\r\n\r\n // Add event listeners as fallback\r\n window.addEventListener(\"resize\", debouncedResize);\r\n window.addEventListener(\"focus\", resizeMap);\r\n window.addEventListener(\"readystatechange\", resizeMap);\r\n document.addEventListener(\"fullscreenchange\", resizeMap);\r\n\r\n // Run resize after a short delay to ensure image is loaded\r\n setTimeout(resizeMap, 100);\r\n\r\n // Cleanup\r\n return () => {\r\n clearTimeout(resizeTimeoutRef.current);\r\n window.removeEventListener(\"resize\", debouncedResize);\r\n window.removeEventListener(\"focus\", resizeMap);\r\n window.removeEventListener(\"readystatechange\", resizeMap);\r\n document.removeEventListener(\"fullscreenchange\", resizeMap);\r\n };\r\n }, [mapName]);\r\n\r\n return mapRef;\r\n};\r\n\r\nexport default useImageMapResize;\r\n"],"names":["useImageMapResize","mapName","mapRef","useRef","originalCoordsRef","resizeTimeoutRef","useEffect","resizeMap","current","areas","getElementsByTagName","img","document","querySelector","concat","complete","length","Array","from","map","area","getAttribute","ratio","width","naturalWidth","height","naturalHeight","computedStyle","window","getComputedStyle","padding","parseInt","getPropertyValue","forEach","index","originalCoords","_a","split","newCoords","coord","i","dimension","Math","floor","Number","join","setAttribute","addEventListener","once","debouncedResize","clearTimeout","setTimeout","ResizeObserver","resizeObserver_1","observe","disconnect","removeEventListener"],"mappings":"8CAEM,IAAAA,EAAoB,SAACC,GACzB,IAAMC,EAASC,EAAuB,MAChCC,EAAoBD,EAAiB,IACrCE,EAAmBF,EAAe,KA8GxC,OA5GAG,GAAU,WACR,IAAMC,EAAY,WAChB,GAAKL,EAAOM,QAAZ,CAEA,IACMC,EADMP,EAAOM,QACDE,qBAChB,QAEIC,EAAMC,SAASC,cACnB,gBAAgBC,OAAAb,EAAW,OAG7B,GAAKU,GAAQA,EAAII,SAAjB,CAOyC,IAArCX,EAAkBI,QAAQQ,QAAgBP,EAAMO,OAAS,IAC3DZ,EAAkBI,QAAUS,MAAMC,KAAKT,GAAOU,KAC5C,SAACC,GAA0B,OAAAA,EAAKC,aAAa,WAAa,EAAE,KAIhE,IAAMC,EAAQ,CACZC,MAAOZ,EAAIY,MAAQZ,EAAIa,aACvBC,OAAQd,EAAIc,OAASd,EAAIe,eAIrBC,EAAgBC,OAAOC,iBAAiBlB,GACxCmB,EAAU,CACdP,MACEQ,SAASJ,EAAcK,iBAAiB,gBAAiB,KAAO,EAClEP,OACEM,SAASJ,EAAcK,iBAAiB,eAAgB,KAAO,GAInEf,MAAMC,KAAKT,GAAOwB,SAAQ,SAACb,EAAuBc,SAE1CC,WACJC,EAAAhC,EAAkBI,QAAQ0B,yBAAQG,MAAM,OAAQ,GAElD,GAA8B,IAA1BF,EAAenB,OAAnB,CAEA,IAAMsB,EAAYH,EACfhB,KAAI,SAACoB,EAAOC,GACX,IAAMC,EAAYD,EAAI,GAAM,EAAI,QAAU,SAC1C,OACEV,EAAQW,GAAaC,KAAKC,MAAMC,OAAOL,GAASjB,EAAMmB,GAEzD,IACAI,KAAK,KAERzB,EAAK0B,aAAa,SAAUR,EAXK,CAYnC,SA3CE3B,SAAAA,EAAKoC,iBAAiB,OAAQxC,EAAW,CAAEyC,MAAM,GAZ9B,CAwDtB,EAEKC,EAAkB,WACtBC,aAAa7C,EAAiBG,SAC9BH,EAAiBG,QAAUoB,OAAOuB,WAAW5C,EAAW,IACzD,EAGD,GAA8B,oBAAnB6C,eAAgC,CACzC,IAAMzC,EAAMC,SAASC,cACnB,gBAAgBC,OAAAb,EAAW,OAG7B,GAAIU,EAAK,CACP,IAAM0C,EAAiB,IAAID,eAAeH,GAI1C,OAHAI,EAAeC,QAAQ3C,GAGhB,WACL0C,EAAeE,aACf3B,OAAO4B,oBAAoB,SAAUP,GACrCrB,OAAO4B,oBAAoB,QAASjD,GACpCqB,OAAO4B,oBAAoB,mBAAoBjD,GAC/CK,SAAS4C,oBAAoB,mBAAoBjD,EAClD,GAiBL,OAZAA,IAGAqB,OAAOmB,iBAAiB,SAAUE,GAClCrB,OAAOmB,iBAAiB,QAASxC,GACjCqB,OAAOmB,iBAAiB,mBAAoBxC,GAC5CK,SAASmC,iBAAiB,mBAAoBxC,GAG9C4C,WAAW5C,EAAW,KAGf,WACL2C,aAAa7C,EAAiBG,SAC9BoB,OAAO4B,oBAAoB,SAAUP,GACrCrB,OAAO4B,oBAAoB,QAASjD,GACpCqB,OAAO4B,oBAAoB,mBAAoBjD,GAC/CK,SAAS4C,oBAAoB,mBAAoBjD,EAClD,CACH,GAAG,CAACN,IAEGC,CACT"}