{"version":3,"file":"PixelateImage.DYVJ44x2.mjs","names":["useRef","useState","useCallback"],"sources":["https:/framerusercontent.com/modules/GnADS71uLgE0t74De2Il/qPIEkxpAtINI9xmpImsm/PixelateImage.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{addPropertyControls,ControlType}from\"framer\";import{useEffect,useRef,useState,useCallback}from\"react\";// Extracted helper function – pure and reusable.\nconst calculateDrawDimensions=(img,canvasWidth,canvasHeight)=>{const imgRatio=img.width/img.height;const canvasRatio=canvasWidth/canvasHeight;let drawWidth,drawHeight,offsetX,offsetY;if(imgRatio>canvasRatio){drawHeight=canvasHeight;drawWidth=img.width*(canvasHeight/img.height);offsetX=(canvasWidth-drawWidth)/2;offsetY=0;}else{drawWidth=canvasWidth;drawHeight=img.height*(canvasWidth/img.width);offsetX=0;offsetY=(canvasHeight-drawHeight)/2;}return{drawWidth,drawHeight,offsetX,offsetY};};/**\n * @framerDisableUnlink\n * @framerIntrinsicWidth 400\n * @framerIntrinsicHeight 300\n */export default function PixelateImage({image,maxPixelSize}){const canvasRef=useRef(null);const imgRef=useRef(null);const animationRef=useRef(null);const[pixelSize,setPixelSize]=useState(1);// Memoised drawing function to avoid re-creation on every render.\nconst drawPixelatedImage=useCallback(()=>{const canvas=canvasRef.current;const img=imgRef.current;if(!canvas||!img)return;const ctx=canvas.getContext(\"2d\");if(!ctx)return;const width=canvas.clientWidth||1;const height=canvas.clientHeight||1;canvas.width=width;canvas.height=height;if(!img.width||!img.height)return;const{drawWidth,drawHeight,offsetX,offsetY}=calculateDrawDimensions(img,width,height);const currentPixelSize=Math.max(pixelSize,1);const pixelatedWidth=Math.ceil(drawWidth/currentPixelSize);const pixelatedHeight=Math.ceil(drawHeight/currentPixelSize);// Create an offscreen canvas for pixelation.\nconst pixelCanvas=document.createElement(\"canvas\");const pixelCtx=pixelCanvas.getContext(\"2d\");if(!pixelCtx)return;pixelCanvas.width=pixelatedWidth;pixelCanvas.height=pixelatedHeight;// Disable smoothing for a crisp pixelated effect.\npixelCtx.imageSmoothingEnabled=false;ctx.imageSmoothingEnabled=false;// Draw the image at reduced resolution and scale it up.\npixelCtx.drawImage(img,0,0,pixelatedWidth,pixelatedHeight);ctx.drawImage(pixelCanvas,0,0,pixelatedWidth,pixelatedHeight,offsetX,offsetY,drawWidth,drawHeight);},[pixelSize]);// Load the image once it changes.\nuseEffect(()=>{if(!image)return;const img=new Image;img.crossOrigin=\"Anonymous\";img.src=image;img.onload=()=>{imgRef.current=img;drawPixelatedImage();};},[image,drawPixelatedImage]);// Redraw the canvas whenever the pixel size updates.\nuseEffect(()=>{drawPixelatedImage();},[pixelSize,drawPixelatedImage]);// Animate the pixelation on hover.\nconst animatePixelation=targetPixelSize=>{if(animationRef.current){cancelAnimationFrame(animationRef.current);}const startPixelSize=pixelSize;const duration=400;const startTime=performance.now();const step=currentTime=>{const elapsed=currentTime-startTime;const progress=Math.min(elapsed/duration,1);const newSize=startPixelSize+(targetPixelSize-startPixelSize)*progress;setPixelSize(newSize);if(progress<1){animationRef.current=requestAnimationFrame(step);}};animationRef.current=requestAnimationFrame(step);};// Cleanup any running animations when the component unmounts.\nuseEffect(()=>{return()=>{if(animationRef.current){cancelAnimationFrame(animationRef.current);}};},[]);return /*#__PURE__*/_jsx(\"canvas\",{ref:canvasRef,style:{width:\"100%\",height:\"100%\",imageRendering:\"pixelated\"},onMouseEnter:()=>animatePixelation(maxPixelSize),onMouseLeave:()=>animatePixelation(1)});}PixelateImage.displayName=\"Pixelated Image\";addPropertyControls(PixelateImage,{image:{type:ControlType.Image,title:\"Image\"},maxPixelSize:{type:ControlType.Number,title:\"Max Pixel Size\",defaultValue:12,min:1,max:50,step:1}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"PixelateImage\",\"slots\":[],\"annotations\":{\"framerIntrinsicHeight\":\"300\",\"framerDisableUnlink\":\"* @framerIntrinsicWidth 400\",\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./PixelateImage.map"],"mappings":"+LAKG,SAAwB,EAAc,CAAC,QAAM,gBAAc,CAAC,IAAM,EAAUA,EAAO,KAAK,CAAO,EAAOA,EAAO,KAAK,CAAO,EAAaA,EAAO,KAAK,CAAM,CAAC,EAAU,GAAcC,EAAS,EAAE,CACzL,EAAmBC,MAAgB,CAAC,IAAM,EAAO,EAAU,QAAc,EAAI,EAAO,QAAQ,GAAG,CAAC,GAAQ,CAAC,EAAI,OAAO,IAAM,EAAI,EAAO,WAAW,KAAK,CAAC,GAAG,CAAC,EAAI,OAAO,IAAM,EAAM,EAAO,aAAa,EAAQ,EAAO,EAAO,cAAc,EAA0C,GAAxC,EAAO,MAAM,EAAM,EAAO,OAAO,EAAU,CAAC,EAAI,OAAO,CAAC,EAAI,OAAO,OAAO,GAAK,CAAC,YAAU,aAAW,UAAQ,WAAS,EAAwB,EAAI,EAAM,EAAO,CAAO,EAAiB,KAAK,IAAI,EAAU,EAAE,CAAO,EAAe,KAAK,KAAK,EAAU,EAAiB,CAAO,EAAgB,KAAK,KAAK,EAAW,EAAiB,CAC/iB,EAAY,SAAS,cAAc,SAAS,CAAO,EAAS,EAAY,WAAW,KAAK,CAAK,IAAgB,EAAY,MAAM,EAAe,EAAY,OAAO,EACvK,EAAS,sBAAsB,GAAM,EAAI,sBAAsB,GAC/D,EAAS,UAAU,EAAI,EAAE,EAAE,EAAe,EAAgB,CAAC,EAAI,UAAU,EAAY,EAAE,EAAE,EAAe,EAAgB,EAAQ,EAAQ,EAAU,EAAW,GAAG,CAAC,EAAU,CAAC,CAC5K,MAAc,CAAC,GAAG,CAAC,EAAM,OAAO,IAAM,EAAI,IAAI,MAAM,EAAI,YAAY,YAAY,EAAI,IAAI,EAAM,EAAI,WAAW,CAAC,EAAO,QAAQ,EAAI,GAAoB,GAAK,CAAC,EAAM,EAAmB,CAAC,CACrL,MAAc,CAAC,GAAoB,EAAG,CAAC,EAAU,EAAmB,CAAC,CACrE,IAAM,EAAkB,GAAiB,CAAI,EAAa,SAAS,qBAAqB,EAAa,QAAQ,CAAE,IAAM,EAAe,EAAmC,EAAU,YAAY,KAAK,CAAO,EAAK,GAAa,CAAC,IAAM,EAAQ,EAAY,EAAgB,EAAS,KAAK,IAAI,EAAQ,IAAS,EAAE,CAAwE,EAAzD,GAAgB,EAAgB,GAAgB,EAA8B,CAAI,EAAS,IAAG,EAAa,QAAQ,sBAAsB,EAAK,GAAI,EAAa,QAAQ,sBAAsB,EAAK,EACrZ,OAAvG,UAAyB,CAAI,EAAa,SAAS,qBAAqB,EAAa,QAAQ,EAAM,EAAE,CAAC,CAAqB,EAAK,SAAS,CAAC,IAAI,EAAU,MAAM,CAAC,MAAM,OAAO,OAAO,OAAO,eAAe,YAAY,CAAC,iBAAiB,EAAkB,EAAa,CAAC,iBAAiB,EAAkB,EAAE,CAAC,CAAC,oBAbnQ,IAAoD,IAAyD,CAClJ,GAAyB,EAAI,EAAY,IAAe,CAAC,IAAM,EAAS,EAAI,MAAM,EAAI,OAAa,EAAY,EAAY,EAAiB,EAAU,EAAW,EAAQ,EAA4Q,OAAjQ,EAAS,GAAa,EAAW,EAAa,EAAU,EAAI,OAAO,EAAa,EAAI,QAAQ,GAAS,EAAY,GAAW,EAAE,EAAQ,IAAQ,EAAU,EAAY,EAAW,EAAI,QAAQ,EAAY,EAAI,OAAO,EAAQ,EAAE,GAAS,EAAa,GAAY,GAAS,CAAC,YAAU,aAAW,UAAQ,UAAQ,EAYvL,EAAc,YAAY,kBAAkB,EAAoB,EAAc,CAAC,MAAM,CAAC,KAAK,EAAY,MAAM,MAAM,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAY,OAAO,MAAM,iBAAiB,aAAa,GAAG,IAAI,EAAE,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC"}