UNPKG

react-image-pointer

Version:

A React component for creating interactive images with clickable points and information cards connected by lines. Enhanced with improved modal, better performance, and enhanced interactivity.

2 lines (1 loc) 9.01 kB
"use strict";var e=require("react"),t=require("react/jsx-runtime"),r={color:void 0,size:void 0,className:void 0,style:void 0,attr:void 0},i=e.createContext&&e.createContext(r),n=["attr","size","title"];function o(e,t){if(null==e)return{};var r,i,n=function(e,t){if(null==e)return{};var r={};for(var i in e)if(Object.prototype.hasOwnProperty.call(e,i)){if(t.indexOf(i)>=0)continue;r[i]=e[i]}return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)r=o[i],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}function l(){return l=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var i in r)Object.prototype.hasOwnProperty.call(r,i)&&(e[i]=r[i])}return e},l.apply(this,arguments)}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,i)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?s(Object(r),!0).forEach(function(t){c(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function c(e,t,r){var i;return(t="symbol"==typeof(i=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var i=r.call(e,t);if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(t,"string"))?i:i+"")in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(t){return t&&t.map((t,r)=>e.createElement(t.tag,a({key:r},t.attr),d(t.child)))}function u(t){return r=>e.createElement(f,l({attr:a({},t.attr)},r),d(t.child))}function f(t){var s=r=>{var i,{attr:s,size:c,title:d}=t,u=o(t,n),f=c||r.size||"1em";return r.className&&(i=r.className),t.className&&(i=(i?i+" ":"")+t.className),e.createElement("svg",l({stroke:"currentColor",fill:"currentColor",strokeWidth:"0"},r.attr,s,u,{className:i,style:a(a({color:t.color||r.color},r.style),t.style),height:f,width:f,xmlns:"http://www.w3.org/2000/svg"}),d&&e.createElement("title",null,d),t.children)};return void 0!==i?e.createElement(i.Consumer,null,e=>s(e)):s(r)}function h(e){return u({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"m21 21-6-6m6 6v-4.8m0 4.8h-4.8"},child:[]},{tag:"path",attr:{d:"M3 16.2V21m0 0h4.8M3 21l6-6"},child:[]},{tag:"path",attr:{d:"M21 7.8V3m0 0h-4.8M21 3l-6 6"},child:[]},{tag:"path",attr:{d:"M3 7.8V3m0 0h4.8M3 3l6 6"},child:[]}]})(e)}function m(e){return u({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"path",attr:{d:"M15 3h6v6"},child:[]},{tag:"path",attr:{d:"M10 14 21 3"},child:[]},{tag:"path",attr:{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"},child:[]}]})(e)}function p(e){return u({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"},child:[]}]})(e)}const x=({src:r,onClose:i})=>(e.useEffect(()=>{const e=e=>{"Escape"===e.key&&i()};return document.addEventListener("keydown",e),document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",e),document.body.style.overflow="unset"}},[i]),t.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-75 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&i(),children:t.jsxs("div",{className:"relative max-w-[90vw] max-h-[90vh] overflow-hidden rounded-xl bg-black shadow-2xl",children:[t.jsx("button",{className:"absolute top-2 right-2 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-black bg-opacity-50 text-white hover:bg-opacity-75 transition-all duration-200",onClick:i,"aria-label":"Close modal",children:t.jsx(p,{size:20})}),t.jsx("img",{src:r,alt:"Full size",className:"block max-w-full max-h-full object-contain"})]})}));exports.ImagePointer=({src:r,maxHeight:i="600px",itemData:n,isDarkMode:o=!1})=>{const[l,s]=e.useState({width:0,height:0}),[a,c]=e.useState({}),[d,u]=e.useState(!1),[f,p]=e.useState(!1),[g,v]=e.useState(""),b=e.useRef(null),y=e.useRef(null),j=e.useRef({}),w=e.useCallback((e,t,r)=>{if(!t||!y.current||!b.current||0===r.width)return null;const i=t.getBoundingClientRect(),o=y.current.getBoundingClientRect(),l=b.current.getBoundingClientRect(),s=e.x/100*r.width+(l.left-o.left),a=e.y/100*r.height+(l.top-o.top);let c,d;d=i.top+i.height/2-o.top;return c=n.points.indexOf(e)%2==0?i.left-o.left:i.right-o.left,{start:{x:s,y:a},end:{x:c,y:d}}},[n.points]),k=e.useCallback(()=>{if(l.width>0&&l.height>0&&Object.keys(j.current).length===n.points.length){const e={};n.points.forEach(t=>{if(void 0!==t.x&&void 0!==t.y){const r=j.current[t.id],i=w(t,r,l);null!==i&&(e[t.id]=i)}}),c(e)}},[l,n.points,w]);e.useEffect(()=>{const e=b.current;if(e){const t=()=>{s({width:e.offsetWidth,height:e.offsetHeight})};return e.addEventListener("load",t),e.complete&&t(),()=>e.removeEventListener("load",t)}},[r]),e.useEffect(()=>{k()},[k]),e.useEffect(()=>{const e=()=>{if(b.current){const e={width:b.current.offsetWidth,height:b.current.offsetHeight};s(e)}};return window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[]);const O=()=>{v(""),u(!1),p(!1)},N=e=>{v(e),p(!0)},C=(e,r)=>{const i=r%2==0?"rounded-r-md border-l-2 border-[#717171] pl-5":"rounded-l-md border-r-2 border-[#717171] pr-5";return t.jsxs("div",{id:`info-div-${e.id}`,ref:t=>j.current[e.id]=t,className:`relative z-20 w-full md:w-[300px] ${i} p-2 shadow text-gray-400 text-start ${o?"bg-[rgba(255,255,255,0.1)]":"bg-[rgba(94,75,75,0.1)]"}`,children:[t.jsx("h3",{className:"text-lg font-semibold p-1 "+(o?"text-white":"text-gray-800"),children:e.info.title}),t.jsx("p",{className:"text-sm p-1.5 "+(o?"text-gray-400":"text-gray-600"),children:e.info.description}),e.link&&t.jsx("div",{className:"p-1.5 w-full flex justify-end",children:t.jsxs("a",{target:"_blank",rel:"noopener noreferrer",href:e.link.url,className:"hover:text-white flex items-center gap-1 transition-colors duration-200 "+(o?"text-gray-300":"text-black"),children:[t.jsx(m,{size:18,color:"#717171"}),e.link.title]})}),e.image&&t.jsxs("div",{className:"relative p-1.5 w-full flex justify-end items-baseline gap-1",children:[t.jsx(h,{size:18,color:"#717171",className:"cursor-pointer hover:scale-110 transition-transform duration-200",onClick:()=>N(e.image.src)}),t.jsx("img",{src:e.image.src,alt:e.image.alt,className:"rounded-md w-16 h-16 object-cover cursor-pointer hover:scale-105 transition-transform duration-200",onClick:()=>N(e.image.src)})]})]},`info-${e.id}`)};return t.jsxs("div",{className:"relative flex flex-col items-start justify-center gap-5 font-sans",children:[t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsx("p",{className:"w-fit py-2 px-4 rounded-xl font-semibold text-xl text-white "+(o?"dark:bg-gray-700":"bg-gray-700"),children:n.details.title}),n.details.description&&t.jsx("div",{className:"relative z-20 w-full rounded-l-md items-baseline p-2 text-gray-300 flex flex-row",children:t.jsx("p",{className:"px-1 font-light text-1xl "+(o?"text-gray-300":"text-gray-700"),children:n.details.description})})]}),t.jsxs("div",{ref:y,className:"relative flex flex-col md:flex-row items-start justify-center",children:[t.jsx("div",{className:"flex flex-col items-end gap-5 order-2 md:order-1",children:n.points.map((e,t)=>t%2==0?null:C(e,t))}),t.jsxs("div",{className:"relative flex-shrink-0 order-1 md:order-2",children:[t.jsx("img",{ref:b,src:r,alt:"Interactive image",style:{maxHeight:i,cursor:"pointer"},className:"block h-auto w-auto rounded-xl hover:shadow-lg transition-shadow duration-200",onClick:()=>{u(!0)}}),n.points.map(e=>void 0!==e.x&&void 0!==e.y&&t.jsx("div",{id:`point-${e.id}`,style:{left:`${e.x}%`,top:`${e.y}%`},className:"absolute z-30 h-3 w-3 border-2 border-white rounded-full bg-red-500 shadow-lg -translate-x-1/2 -translate-y-1/2 hover:scale-125 transition-transform duration-200"},e.id))]}),t.jsx("div",{className:"flex flex-col gap-5 order-3 mt-5 md:mt-0",children:n.points.map((e,t)=>t%2==0?C(e,t):null)}),n.points.map(e=>{const r=a[e.id];return r?t.jsx("svg",{style:{width:`${y.current?.offsetWidth||"100%"}`,height:`${y.current?.offsetHeight||"100%"}`},className:"pointer-events-none absolute left-0 top-0 z-0",children:t.jsx("line",{x1:`${r.start.x}`,y1:`${r.start.y}`,x2:`${r.end.x}`,y2:`${r.end.y}`,stroke:"#eae8e8",strokeWidth:"1.5"})},`line-${e.id}`):null})]}),d&&t.jsx(x,{src:r,onClose:O}),f&&t.jsx(x,{src:g,onClose:O})]})},exports.Modal=x;