{"version":3,"file":"PixelImageReveal_Prod.CBVCGLDo.mjs","names":["useRef"],"sources":["https:/framerusercontent.com/modules/fWrPkQmi5yYl70FuRZwX/snGTBrPIqB0yD2CXZdrZ/PixelImageReveal_Prod.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{useEffect,useRef}from\"react\";import{ControlType,addPropertyControls,RenderTarget}from\"framer\";import{useInView}from\"framer-motion\";import{ComponentMessage}from\"https://framer.com/m/Utils-FINc.js\";var AnimationTrigger;// import { ComponentMessage } from \"../../utils/ComponentMessage\";\n// ------------------------------------------------------------ //\n// INTERFACES\n// ------------------------------------------------------------ //\n(function(AnimationTrigger){AnimationTrigger[\"LayerInView\"]=\"layerInView\";})(AnimationTrigger||(AnimationTrigger={}));// ------------------------------------------------------------ //\n// PROPERTY CONTROLS\n// ------------------------------------------------------------ //\naddPropertyControls(PixelImageReveal,{image:{type:ControlType.ResponsiveImage},borderRadius:{// @ts-expect-error - BorderRadius is not a valid control type\ntype:ControlType.BorderRadius,title:\"Border\",defaultValue:\"0px\"},duration:{type:ControlType.Number,title:\"Duration\",defaultValue:2,unit:\"s\"},steps:{type:ControlType.Number,title:\"Steps\",defaultValue:5,min:1,max:100,step:1},pixelation:{type:ControlType.Object,title:\"Pixelation\",controls:{start:{type:ControlType.Number,title:\"Start\",defaultValue:200,min:1,max:300,step:1},end:{type:ControlType.Number,title:\"End\",defaultValue:1,min:1,max:300,step:1}}},animation:{type:ControlType.Object,icon:\"effect\",controls:{trigger:{type:ControlType.Enum,defaultValue:\"layerInView\",options:[\"layerInView\"],optionTitles:[\"Layer in View\"],displaySegmentedControl:true,segmentedControlDirection:\"vertical\"},replay:{type:ControlType.Boolean,defaultValue:false,hidden:props=>props.trigger!==\"layerInView\"},delay:{type:ControlType.Number,defaultValue:0,min:0,max:5,step:.1}},description:\"More components at [Framer University](https://frameruni.link/cc).\"}});// ------------------------------------------------------------ //\n// DEFAULT PROPS\n// ------------------------------------------------------------ //\nPixelImageReveal.defaultProps={borderRadius:\"0px\",duration:2,steps:5,pixelation:{start:200,end:1},animation:{trigger:\"layerInView\",replay:false,delay:0}};// ------------------------------------------------------------ //\n// MAIN COMPONENT\n// ------------------------------------------------------------ //\n/**\n * @framerSupportedLayoutWidth any-prefer-fixed\n * @framerSupportedLayoutHeight any-prefer-fixed\n * @framerIntrinsicWidth 400\n * @framerIntrinsicHeight 200\n * @framerDisableUnlink\n */export default function PixelImageReveal(props){const isOnFramerCanvas=RenderTarget.hasRestrictions();const canvasRef=useRef(null);const isInView=useInView(canvasRef,{once:!props.animation.replay,amount:\"some\"});useEffect(()=>{const canvas=canvasRef.current;if(!canvas||isOnFramerCanvas||!(\"image\"in props)||!props.image)return;// Add willReadFrequently hint for performance\nconst ctx=canvas.getContext(\"2d\",{willReadFrequently:true});if(!ctx)return;const img=new Image;img.crossOrigin=\"anonymous\"// Keep this for potential CORS issues\n;img.src=props.image.src;// Helper function to draw pixelated image\nconst drawPixelatedImage=pixelSize=>{if(!ctx||!img.complete||img.naturalWidth===0||!isInView)return;// Ensure img is loaded\n// Use naturalWidth/Height for original dimensions\ncanvas.width=img.naturalWidth;canvas.height=img.naturalHeight;// --- Optimization: If pixelSize is 1 (or less), draw original image directly ---\nif(pixelSize<=1){ctx.drawImage(img,0,0,canvas.width,canvas.height);return;// Skip pixelation logic\n}// --- End Optimization ---\n// Clear canvas before drawing pixelated version\nctx.clearRect(0,0,canvas.width,canvas.height);// Draw image temporarily to get data (necessary for pixelation > 1)\nctx.drawImage(img,0,0,canvas.width,canvas.height);let imageData;try{imageData=ctx.getImageData(0,0,canvas.width,canvas.height);}catch(e){console.error(\"Could not get image data:\",e);// Draw a placeholder or clear if failed (e.g., due to CORS)\nctx.clearRect(0,0,canvas.width,canvas.height);ctx.fillStyle=\"lightgray\";ctx.fillRect(0,0,canvas.width,canvas.height);ctx.fillStyle=\"black\";ctx.fillText(\"Error loading image data\",10,20);return;// Stop further processing\n}const data=imageData.data;// Clear again before drawing pixelated version\nctx.clearRect(0,0,canvas.width,canvas.height);const clampedPixelSize=Math.max(1,Math.round(pixelSize))// Ensure integer >= 1\n;for(let y=0;y<canvas.height;y+=clampedPixelSize){for(let x=0;x<canvas.width;x+=clampedPixelSize){// Get the color of the top-left pixel in the block\n// Adjust index calculation to avoid going out of bounds\nconst offsetY=Math.min(y,canvas.height-1);const offsetX=Math.min(x,canvas.width-1);const pixelIndex=(offsetY*canvas.width+offsetX)*4;const red=data[pixelIndex];const green=data[pixelIndex+1];const blue=data[pixelIndex+2];const alpha=data[pixelIndex+3];// Fill the entire block with this color\nctx.fillStyle=`rgba(${red}, ${green}, ${blue}, ${alpha/255})`;// Ensure drawn rect doesn't exceed canvas bounds\nctx.fillRect(x,y,Math.min(clampedPixelSize,canvas.width-x),Math.min(clampedPixelSize,canvas.height-y));}}};// Keep track of timeout IDs for cleanup IN THIS EFFECT RUN\nconst timeoutIds=[];img.onload=()=>{// Animation logic\nconst{delay}=props.animation;const{steps,duration,pixelation}=props;if(steps<=0||pixelation.start<=pixelation.end||duration<=0){// If no steps/animation needed, draw final state immediately\ndrawPixelatedImage(pixelation.end)// Use end pixelation instead of 1\n;return;// No animation needed\n}// Duration per step/interval\nconst stepDuration=duration*1e3/steps;// Decrement needed to go from startPixelSize to endPixelSize in exactly `steps` intervals\nconst pixelSizeDecrement=steps>0?(pixelation.start-pixelation.end)/steps:0;// --- Draw initial state immediately ---\ndrawPixelatedImage(pixelation.start);// --- End Initial Draw ---\n// Function to perform a single animation step\nconst animateStep=stepIndex=>{// Calculate pixel size for the current step (start to end)\nconst currentPixelSize=Math.max(pixelation.end,pixelation.start-stepIndex*pixelSizeDecrement);drawPixelatedImage(currentPixelSize);};// Schedule all steps using setTimeout, adding the initial delay\nfor(let i=1;i<=steps;i++){const stepDelay=delay*1e3+i*stepDuration;const id=window.setTimeout(()=>animateStep(i),stepDelay);timeoutIds.push(id)// Add to the array specific to this effect run\n;}};img.onerror=()=>{console.error(\"Failed to load image:\",props.image.src);if(ctx){ctx.clearRect(0,0,canvas.width,canvas.height)// Clear canvas\n;}};// Cleanup function to clear all scheduled timeouts FOR THIS EFFECT RUN\nreturn()=>{timeoutIds.forEach(id=>{clearTimeout(id);});};},[props.steps,props.duration,props.pixelation,isInView]);if(!(\"image\"in props)||!props.image){return /*#__PURE__*/_jsx(\"div\",{style:{width:\"100%\",height:\"100%\"},children:/*#__PURE__*/_jsx(ComponentMessage,{title:\"Pixel Image Reveal\",subtitle:\"Set up the component by adding image to the component properties.\"})});}return /*#__PURE__*/_jsx(\"div\",{style:{width:\"100%\",height:\"100%\",borderRadius:props.borderRadius,overflow:\"hidden\"},children:isOnFramerCanvas?/*#__PURE__*/_jsx(\"img\",{src:props.image.src,alt:props.image.alt,style:{width:\"100%\",height:\"100%\",objectFit:\"cover\"}}):/*#__PURE__*/_jsx(\"canvas\",{ref:canvasRef,style:{width:\"100%\",height:\"100%\",objectFit:\"cover\",imageRendering:\"pixelated\"}})});}PixelImageReveal.displayName=\"Pixel Image Reveal\";\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"PixelImageReveal\",\"slots\":[],\"annotations\":{\"framerSupportedLayoutHeight\":\"any-prefer-fixed\",\"framerContractVersion\":\"1\",\"framerIntrinsicHeight\":\"200\",\"framerDisableUnlink\":\"\",\"framerIntrinsicWidth\":\"400\",\"framerSupportedLayoutWidth\":\"any-prefer-fixed\"}},\"PixelImageRevealProps\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./PixelImageReveal_Prod.map"],"mappings":"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"}