{"version":3,"file":"InteractiveDotGrid.DxraDS2A.mjs","names":["useRef","useState","useMemo","useCallback"],"sources":["https:/framerusercontent.com/modules/OMZLlkAjKzuNuHgIphsj/mxsQ685naNpCAcNsnsPF/InteractiveDotGrid.js"],"sourcesContent":["// User request: Create a new Framer code component named InteractiveDotGrid for a portfolio hero background with a subtle interactive dot grid overlay, transparent layering, pointer-reactive motion, reduced-motion support, efficient animation, SSR safety, and configurable controls.\nimport{jsx as _jsx}from\"react/jsx-runtime\";import{useCallback,useEffect,useMemo,useRef,useState,startTransition}from\"react\";import{addPropertyControls,ControlType,useIsStaticRenderer}from\"framer\";import{useInView}from\"framer-motion\";/**\n * @framerSupportedLayoutWidth any-prefer-fixed\n * @framerSupportedLayoutHeight any-prefer-fixed\n */export default function InteractiveDotGrid(props){const{style,dotColor,activeColor,spacing,baseSize,interactionRadius,intensity,opacity,motionSpeed}=props;const containerRef=useRef(null);const canvasRef=useRef(null);const frameRef=useRef(null);const isAnimatingRef=useRef(false);const canAnimateRef=useRef(false);const targetPointerRef=useRef({x:0,y:0,inside:false});const smoothPointerRef=useRef({x:0,y:0,strength:0});const staticRenderer=useIsStaticRenderer();const inView=useInView(containerRef,{amount:0});const[{width,height,dpr},setCanvasMetrics]=useState({width:0,height:0,dpr:1});const[reducedMotion,setReducedMotion]=useState(false);const dotPositions=useMemo(()=>{if(width<=0||height<=0||spacing<=0)return[];const cols=Math.ceil(width/spacing)+1;const rows=Math.ceil(height/spacing)+1;const positions=[];for(let row=0;row<rows;row++){for(let col=0;col<cols;col++){positions.push({x:col*spacing,y:row*spacing});}}return positions;},[width,height,spacing]);const drawFrame=useCallback(ctx=>{if(width<=0||height<=0)return;ctx.clearRect(0,0,width,height);const pointer=smoothPointerRef.current;const radius=Math.max(1,interactionRadius);const localIntensity=Math.max(0,intensity);const safeOpacity=Math.max(0,Math.min(1,opacity));const strength=Math.max(0,Math.min(1,pointer.strength));for(let i=0;i<dotPositions.length;i++){const dot=dotPositions[i];const dx=dot.x-pointer.x;const dy=dot.y-pointer.y;const distance=Math.sqrt(dx*dx+dy*dy);const influence=Math.max(0,1-distance/radius)*strength;let renderX=dot.x;let renderY=dot.y;const nudgeAmount=influence*localIntensity*spacing*.12;if(distance>.001){renderX+=dx/distance*nudgeAmount;renderY+=dy/distance*nudgeAmount;}const baseRadius=Math.max(.25,baseSize*.5);const activeRadius=baseRadius*(1+influence*localIntensity*1.2);ctx.beginPath();ctx.globalAlpha=safeOpacity;ctx.fillStyle=dotColor;ctx.arc(renderX,renderY,baseRadius,0,Math.PI*2);ctx.fill();if(influence>.001){ctx.beginPath();ctx.globalAlpha=safeOpacity*influence*1.6;ctx.fillStyle=activeColor;ctx.arc(renderX,renderY,activeRadius,0,Math.PI*2);ctx.fill();}}ctx.globalAlpha=1;},[width,height,interactionRadius,intensity,opacity,dotColor,activeColor,dotPositions,spacing,baseSize]);const cancelAnimation=useCallback(()=>{if(frameRef.current!==null){window.cancelAnimationFrame(frameRef.current);frameRef.current=null;}isAnimatingRef.current=false;},[]);const stepAnimation=useCallback(()=>{const canvas=canvasRef.current;if(!canvas){isAnimatingRef.current=false;return;}const context=canvas.getContext(\"2d\");if(!context){isAnimatingRef.current=false;return;}const target=targetPointerRef.current;const smooth=smoothPointerRef.current;const speed=Math.max(.01,motionSpeed);const ease=.06*speed;smooth.x+=(target.x-smooth.x)*ease;smooth.y+=(target.y-smooth.y)*ease;const targetStrength=target.inside?1:0;smooth.strength+=(targetStrength-smooth.strength)*ease;drawFrame(context);const dx=Math.abs(target.x-smooth.x);const dy=Math.abs(target.y-smooth.y);const ds=Math.abs(targetStrength-smooth.strength);const settled=dx<.05&&dy<.05&&ds<.005;if(!canAnimateRef.current||settled){isAnimatingRef.current=false;frameRef.current=null;return;}frameRef.current=window.requestAnimationFrame(stepAnimation);},[drawFrame,motionSpeed]);const wakeAnimation=useCallback(()=>{if(typeof window===\"undefined\")return;if(!canAnimateRef.current)return;if(isAnimatingRef.current)return;isAnimatingRef.current=true;frameRef.current=window.requestAnimationFrame(stepAnimation);},[stepAnimation]);useEffect(()=>{if(typeof window===\"undefined\")return;const mediaQuery=window.matchMedia(\"(prefers-reduced-motion: reduce)\");startTransition(()=>setReducedMotion(mediaQuery.matches));const handleChange=()=>{startTransition(()=>setReducedMotion(mediaQuery.matches));};mediaQuery.addEventListener(\"change\",handleChange);return()=>mediaQuery.removeEventListener(\"change\",handleChange);},[]);useEffect(()=>{if(typeof window===\"undefined\"||!containerRef.current)return;const updateMetrics=()=>{if(!containerRef.current)return;const rect=containerRef.current.getBoundingClientRect();const nextDpr=Math.min(window.devicePixelRatio||1,2);startTransition(()=>setCanvasMetrics({width:Math.max(0,rect.width),height:Math.max(0,rect.height),dpr:nextDpr}));};updateMetrics();const observer=new ResizeObserver(updateMetrics);observer.observe(containerRef.current);window.addEventListener(\"resize\",updateMetrics);return()=>{observer.disconnect();window.removeEventListener(\"resize\",updateMetrics);};},[]);useEffect(()=>{if(typeof window===\"undefined\"||!containerRef.current)return;const handlePointerMove=event=>{if(!containerRef.current)return;const rect=containerRef.current.getBoundingClientRect();const x=event.clientX-rect.left;const y=event.clientY-rect.top;const inside=x>=0&&y>=0&&x<=rect.width&&y<=rect.height;targetPointerRef.current={x,y,inside};wakeAnimation();};const handleLeaveWindow=()=>{targetPointerRef.current.inside=false;wakeAnimation();};window.addEventListener(\"pointermove\",handlePointerMove,{passive:true});window.addEventListener(\"pointercancel\",handleLeaveWindow);window.addEventListener(\"blur\",handleLeaveWindow);return()=>{window.removeEventListener(\"pointermove\",handlePointerMove);window.removeEventListener(\"pointercancel\",handleLeaveWindow);window.removeEventListener(\"blur\",handleLeaveWindow);};},[wakeAnimation]);useEffect(()=>{const canvas=canvasRef.current;if(!canvas)return;const context=canvas.getContext(\"2d\");if(!context)return;const pixelWidth=Math.max(1,Math.floor(width*dpr));const pixelHeight=Math.max(1,Math.floor(height*dpr));canvas.width=pixelWidth;canvas.height=pixelHeight;canvas.style.width=`${width}px`;canvas.style.height=`${height}px`;context.setTransform(dpr,0,0,dpr,0,0);drawFrame(context);},[width,height,dpr,drawFrame]);useEffect(()=>{const canvas=canvasRef.current;if(!canvas)return;const context=canvas.getContext(\"2d\");if(!context)return;canAnimateRef.current=!staticRenderer&&!reducedMotion&&inView;drawFrame(context);if(!canAnimateRef.current){cancelAnimation();return;}return()=>{cancelAnimation();};},[drawFrame,reducedMotion,staticRenderer,inView,cancelAnimation]);return /*#__PURE__*/_jsx(\"div\",{ref:containerRef,style:{position:\"relative\",width:\"100%\",height:\"100%\",pointerEvents:\"none\",overflow:\"hidden\",background:\"transparent\",...style},\"aria-hidden\":true,children:/*#__PURE__*/_jsx(\"canvas\",{ref:canvasRef,style:{position:\"absolute\",inset:0,width:\"100%\",height:\"100%\",display:\"block\",background:\"transparent\"}})});}addPropertyControls(InteractiveDotGrid,{dotColor:{type:ControlType.Color,title:\"Dot Color\",defaultValue:\"#CCCCCC\"},activeColor:{type:ControlType.Color,title:\"Active Color\",defaultValue:\"#000000\"},spacing:{type:ControlType.Number,title:\"Spacing\",defaultValue:24,min:10,max:64,step:1},baseSize:{type:ControlType.Number,title:\"Base Size\",defaultValue:1.8,min:.5,max:6,step:.1},interactionRadius:{type:ControlType.Number,title:\"Radius\",defaultValue:120,min:40,max:320,step:1},intensity:{type:ControlType.Number,title:\"Intensity\",defaultValue:.55,min:0,max:2,step:.01},opacity:{type:ControlType.Number,title:\"Opacity\",defaultValue:.28,min:0,max:1,step:.01},motionSpeed:{type:ControlType.Number,title:\"Speed\",defaultValue:1,min:.2,max:2,step:.01}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"InteractiveDotGrid\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\",\"framerSupportedLayoutWidth\":\"any-prefer-fixed\",\"framerSupportedLayoutHeight\":\"any-prefer-fixed\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./InteractiveDotGrid.map"],"mappings":"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"}