{"version":3,"file":"InteractiveGrid.ouKhpg8J.mjs","names":["useRef","useState","useCallback"],"sources":["https:/framerusercontent.com/modules/oWbWEAAJIgwk8YOf2AUo/JVncMx76N6Y2lyqgZOjI/InteractiveGrid.js"],"sourcesContent":["// Grid of interactive dots with wavy, fluid distortion effect on mouse move or scroll\nimport{jsx as _jsx}from\"react/jsx-runtime\";import{useRef,useEffect,useState,useCallback,startTransition}from\"react\";import{addPropertyControls,ControlType,useIsStaticRenderer}from\"framer\";/**\n * Interactive Dot Grid\n *\n * @framerSupportedLayoutWidth any-prefer-fixed\n * @framerSupportedLayoutHeight any-prefer-fixed\n */export default function InteractiveGrid(props){const{dotColor,background,useGradient,gradientFrom,gradientTo,gradientDirection,dotRadius,columns,rows,spacing,waveStrength,waveRadius,style}=props;const isStatic=useIsStaticRenderer();const containerRef=useRef(null);const[mouse,setMouse]=useState(null);const[animatedMouse,setAnimatedMouse]=useState(null);const[scrollY,setScrollY]=useState(0);// Animate mouse position for smooth transitions\nuseEffect(()=>{if(mouse===null&&animatedMouse===null)return;let frame;function animate(){if(mouse===null&&animatedMouse!==null){// Animate out to null\nconst dx=-animatedMouse.x*.2;const dy=-animatedMouse.y*.2;const next={x:animatedMouse.x+dx,y:animatedMouse.y+dy};if(Math.abs(next.x)<1&&Math.abs(next.y)<1){startTransition(()=>setAnimatedMouse(null));}else{startTransition(()=>setAnimatedMouse(next));frame=requestAnimationFrame(animate);}}else if(mouse&&animatedMouse){// Animate towards mouse\nconst dx=(mouse.x-animatedMouse.x)*.2;const dy=(mouse.y-animatedMouse.y)*.2;const next={x:animatedMouse.x+dx,y:animatedMouse.y+dy};if(Math.abs(next.x-mouse.x)<1&&Math.abs(next.y-mouse.y)<1){startTransition(()=>setAnimatedMouse(mouse));}else{startTransition(()=>setAnimatedMouse(next));frame=requestAnimationFrame(animate);}}else if(mouse&&!animatedMouse){startTransition(()=>setAnimatedMouse(mouse));}}frame=requestAnimationFrame(animate);return()=>cancelAnimationFrame(frame);},[mouse,animatedMouse]);// Mouse move handler\nconst handleMouseMove=useCallback(e=>{if(!containerRef.current)return;const rect=containerRef.current.getBoundingClientRect();// Use SVG coordinates for the mouse pointer, accounting for scaling\nconst svgWidth=(columns-1)*spacing+dotRadius*2;const svgHeight=(rows-1)*spacing+dotRadius*2;const x=(e.clientX-rect.left)/rect.width*svgWidth;const y=(e.clientY-rect.top)/rect.height*svgHeight;startTransition(()=>setMouse({x,y}));},[columns,rows,spacing,dotRadius]);const handleMouseLeave=useCallback(()=>{// Do not animate out, just keep the last animatedMouse position\nstartTransition(()=>setMouse(null));},[]);// Scroll handler\nuseEffect(()=>{if(typeof window===\"undefined\")return;if(isStatic)return;const onScroll=()=>{startTransition(()=>setScrollY(window.scrollY||0));};window.addEventListener(\"scroll\",onScroll);return()=>window.removeEventListener(\"scroll\",onScroll);},[isStatic]);// Grid size\nconst width=(columns-1)*spacing+dotRadius*2;const height=(rows-1)*spacing+dotRadius*2;// Render dots\nconst dots=[];// Determine effective wave strength\nconst effectiveWaveStrength=animatedMouse?waveStrength:0;for(let row=0;row<rows;row++){for(let col=0;col<columns;col++){let x=col*spacing+dotRadius;let y=row*spacing+dotRadius;let dx=0,dy=0;// Mouse-based wave\nif(animatedMouse){// Use the actual SVG coordinates for the mouse pointer\nconst dist=Math.hypot(animatedMouse.x-x,animatedMouse.y-y);if(dist<waveRadius){const angle=Math.atan2(y-animatedMouse.y,x-animatedMouse.x);const force=(1-dist/waveRadius)*effectiveWaveStrength;dx+=Math.cos(angle)*force;dy+=Math.sin(angle)*force;}}// Scroll-based wave\nif(!animatedMouse&&!isStatic){const t=scrollY/100+(col+row)*.2;dy+=Math.sin(t)*0// No wave when not hovered\n;}dots.push(/*#__PURE__*/_jsx(\"circle\",{cx:x+dx,cy:y+dy,r:dotRadius,fill:dotColor},row+\",\"+col));}}return /*#__PURE__*/_jsx(\"div\",{ref:containerRef,style:{...style,width:\"100%\",height:\"100%\",background:useGradient?`linear-gradient(${gradientDirection}, ${gradientFrom}, ${gradientTo})`:background,overflow:\"hidden\",position:\"relative\",touchAction:\"none\"},onMouseMove:isStatic?undefined:handleMouseMove,onMouseLeave:isStatic?undefined:handleMouseLeave,children:/*#__PURE__*/_jsx(\"svg\",{width:\"100%\",height:\"100%\",viewBox:`0 0 ${width} ${height}`,style:{display:\"block\"},\"aria-hidden\":\"true\",children:dots})});}addPropertyControls(InteractiveGrid,{dotColor:{type:ControlType.Color,title:\"Dot Color\",defaultValue:\"#FFBFBF\"},background:{type:ControlType.Color,title:\"Background\",defaultValue:\"#000000\",hidden:props=>props.useGradient},useGradient:{type:ControlType.Boolean,title:\"Use Gradient\",defaultValue:true},gradientFrom:{type:ControlType.Color,title:\"Gradient From\",defaultValue:\"#000000\",hidden:props=>!props.useGradient},gradientTo:{type:ControlType.Color,title:\"Gradient To\",defaultValue:\"#FF4D4D\",hidden:props=>!props.useGradient},gradientDirection:{type:ControlType.Enum,title:\"Direction\",options:[\"90deg\",\"180deg\",\"270deg\",\"0deg\"],optionTitles:[\"Right\",\"Down\",\"Left\",\"Up\"],defaultValue:\"270deg\",hidden:props=>!props.useGradient},dotRadius:{type:ControlType.Number,title:\"Dot Radius\",defaultValue:1,min:1,max:20,step:1,unit:\"px\"},columns:{type:ControlType.Number,title:\"Columns\",defaultValue:40,min:2,max:40,step:1},rows:{type:ControlType.Number,title:\"Rows\",defaultValue:20,min:2,max:40,step:1},spacing:{type:ControlType.Number,title:\"Spacing\",defaultValue:41,min:10,max:100,step:1,unit:\"px\"},waveStrength:{type:ControlType.Number,title:\"Wave Strength\",defaultValue:60,min:1,max:60,step:1,unit:\"px\"},waveRadius:{type:ControlType.Number,title:\"Wave Radius\",defaultValue:166,min:20,max:400,step:1,unit:\"px\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"InteractiveGrid\",\"slots\":[],\"annotations\":{\"framerSupportedLayoutWidth\":\"any-prefer-fixed\",\"framerContractVersion\":\"1\",\"framerSupportedLayoutHeight\":\"any-prefer-fixed\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./InteractiveGrid.map"],"mappings":"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"}