{"version":3,"file":"PixelGridTransition.CitZP9iZ.mjs","names":["useRef","useState"],"sources":["https:/framerusercontent.com/modules/DLlTszSVx1q3gsUsooUH/1OLqVCGFSe7V4hcoY17D/PixelGridTransition.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{addPropertyControls,ControlType,RenderTarget}from\"framer\";import{useEffect,useLayoutEffect,useRef,useState}from\"react\";import{createPortal}from\"react-dom\";import{motion,useAnimation}from\"framer-motion\";const SESSION_KEY=\"pt_pixel_grid_active\";// Module-level flags — shared across all simultaneous page instances so the\n// programmatic .click() that triggers navigation is correctly skipped by the\n// new page's listener (which would otherwise have allowNextClick = false).\nlet _allowNextClick=false;let _navigating=false;/**\n * @framerSupportedLayoutWidth auto\n * @framerSupportedLayoutHeight auto\n */export default function PixelGridTransition({columns=8,blockColor=\"#ff4c24\",leaveStagger=.5,enterStagger=.75}){const isCanvas=RenderTarget.current()===RenderTarget.canvas;const controls=useAnimation();const portalEl=useRef(null);const[portalReady,setPortalReady]=useState(false);const isCovering=useRef(false);// Grid dimensions — recalculated on mount and resize\nconst[grid,setGrid]=useState({cols:columns,rows:1});// Stable random delays — recomputed whenever block count changes.\n// Stored in a ref so they don't shuffle on every render.\nconst delaysRef=useRef([]);const totalBlocks=grid.cols*grid.rows;function computeDelays(total,amount){const delays=[];for(let i=0;i<total;i++){delays.push(Math.random()*amount);}return delays;}function calcGrid(cols){const blockSize=window.innerWidth/cols;const rows=Math.ceil(window.innerHeight/blockSize);return{cols,rows};}const reducedMotion=typeof window!==\"undefined\"?window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches:false;// ── KEY FIX: read sessionStorage synchronously in lazy useState ────────────\nconst[startCovered]=useState(()=>{if(typeof window===\"undefined\"||isCanvas)return false;return sessionStorage.getItem(SESSION_KEY)===\"true\";});const isTransitionRef=useRef(startCovered);// A smooth easing curve for fading the blocks\nconst smoothEase=[.65,0,.35,1];const fadeDuration=.4;// ── PORTAL SETUP ───────────────────────────────────────────────────────────\nuseLayoutEffect(()=>{if(isCanvas)return;if(startCovered)sessionStorage.removeItem(SESSION_KEY);// Calculate initial grid size\nconst g=calcGrid(columns);setGrid(g);delaysRef.current=computeDelays(g.cols*g.rows,leaveStagger);const el=document.createElement(\"div\");el.setAttribute(\"data-pt-pixel-grid-portal\",\"\");document.body.appendChild(el);portalEl.current=el;setPortalReady(true);const handleResize=()=>{const g2=calcGrid(columns);setGrid(g2);delaysRef.current=computeDelays(g2.cols*g2.rows,leaveStagger);};window.addEventListener(\"resize\",handleResize);return()=>{window.removeEventListener(\"resize\",handleResize);document.body.removeChild(el);portalEl.current=null;};},[]);// Recompute delays when stagger values change\nuseEffect(()=>{if(isCanvas)return;delaysRef.current=computeDelays(totalBlocks,enterStagger);},[totalBlocks,enterStagger]);// ── ENTER ANIMATION ────────────────────────────────────────────────────────\nuseEffect(()=>{if(isCanvas||!portalReady||!isTransitionRef.current)return;async function runEnter(){isCovering.current=false;if(reducedMotion){controls.set({opacity:0});return;}await new Promise(r=>setTimeout(r,160));// Fresh random delays for this enter sweep\ndelaysRef.current=computeDelays(totalBlocks,enterStagger);// Blocks fade out smoothly\nawait controls.start(custom=>({opacity:0,transition:{duration:fadeDuration,ease:smoothEase,delay:delaysRef.current[custom]??0}}));}runEnter();},[portalReady]);// ── EXIT ANIMATION — intercept link clicks ─────────────────────────────────\nuseEffect(()=>{if(isCanvas)return;const handleClick=e=>{const anchor=e.target.closest(\"a[href]\");if(!anchor)return;if(_allowNextClick){_allowNextClick=false;return;}if(_navigating){e.preventDefault();return;}const href=anchor.getAttribute(\"href\");if(!href)return;if(href.startsWith(\"#\")||href.startsWith(\"mailto:\")||href.startsWith(\"tel:\")||href.startsWith(\"javascript:\"))return;// Skip links with data-transition-prevent (matching reference behaviour)\nif(anchor.hasAttribute(\"data-transition-prevent\"))return;if(anchor.getAttribute(\"target\")===\"_blank\")return;let parsedUrl;try{parsedUrl=new URL(href,window.location.href);if(parsedUrl.hostname!==window.location.hostname)return;}catch{return;}if(parsedUrl.pathname===window.location.pathname)return;e.preventDefault();e.stopPropagation();_navigating=true;async function runLeave(){if(reducedMotion){sessionStorage.setItem(SESSION_KEY,\"true\");_allowNextClick=true;_navigating=false;anchor.click();return;}// Fresh random delays for this leave sweep\ndelaysRef.current=computeDelays(totalBlocks,leaveStagger);// Blocks fade in smoothly to cover the screen\nawait controls.start(custom=>({opacity:1,transition:{duration:fadeDuration,ease:smoothEase,delay:delaysRef.current[custom]??0}}));sessionStorage.setItem(SESSION_KEY,\"true\");isCovering.current=true;_allowNextClick=true;_navigating=false;anchor.click();// ── Fallback timer ─────────────────────────────────────────────\nconst fallbackMs=(leaveStagger+enterStagger)*1e3+800;setTimeout(async()=>{if(!isCovering.current)return;isCovering.current=false;_navigating=false;sessionStorage.removeItem(SESSION_KEY);delaysRef.current=computeDelays(totalBlocks,enterStagger);await controls.start(custom=>({opacity:0,transition:{duration:fadeDuration,ease:smoothEase,delay:delaysRef.current[custom]??0}}));},fallbackMs);}runLeave();};document.addEventListener(\"click\",handleClick,true);return()=>document.removeEventListener(\"click\",handleClick,true);},[columns,leaveStagger,enterStagger,totalBlocks]);// ── CANVAS — zero size, nothing visible ────────────────────────────────────\nif(isCanvas)return /*#__PURE__*/_jsx(\"div\",{style:{width:0,height:0,overflow:\"hidden\"}});if(!portalReady||!portalEl.current)return null;const blockSize=`${100/grid.cols}vw`;const initialOpacity=startCovered?1:0;return /*#__PURE__*/createPortal(/*#__PURE__*/_jsx(\"div\",{style:{position:\"fixed\",inset:0,zIndex:9999,pointerEvents:\"none\",display:\"grid\",gridTemplateColumns:`repeat(${grid.cols}, 1fr)`,gridTemplateRows:`repeat(${grid.rows}, ${blockSize})`,overflow:\"hidden\"},children:Array.from({length:totalBlocks}).map((_,i)=>/*#__PURE__*/_jsx(motion.div,{custom:i,animate:controls,initial:{opacity:initialOpacity},style:{backgroundColor:blockColor}},i))}),portalEl.current);}// ── PROPERTY CONTROLS ──────────────────────────────────────────────────────────\naddPropertyControls(PixelGridTransition,{columns:{type:ControlType.Number,title:\"Columns\",defaultValue:8,min:2,max:20,step:1,displayStepper:true,description:\"Number of pixel columns. Rows are calculated automatically to fill the viewport. More columns = smaller, denser pixels.\"},blockColor:{type:ControlType.Color,title:\"Color\",defaultValue:\"#ff4c24\"},leaveStagger:{type:ControlType.Number,title:\"Leave Spread\",defaultValue:.5,min:.05,max:3,step:.05,unit:\"s\",displayStepper:true,description:\"Total time over which blocks randomly snap ON to cover the screen.\"},enterStagger:{type:ControlType.Number,title:\"Enter Spread\",defaultValue:.75,min:.05,max:3,step:.05,unit:\"s\",displayStepper:true,description:\"Total time over which blocks randomly fade OFF to reveal the new page. Setup: Add to every page, keep properties identical. Set Page Settings → Transitions to None (Instant). Transitions fire on <a> tags only — set via Accessibility → Tag on link layers. Add data-transition-prevent to any link that should skip the animation.\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"PixelGridTransition\",\"slots\":[],\"annotations\":{\"framerSupportedLayoutWidth\":\"auto\",\"framerSupportedLayoutHeight\":\"auto\",\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./PixelGridTransition.map"],"mappings":"qRAMG,SAAwB,EAAoB,CAAC,UAAQ,EAAE,aAAW,UAAU,eAAa,GAAG,eAAa,KAAK,CAAC,IAAM,EAAS,EAAa,QAAQ,IAAI,EAAa,OAAa,EAAS,EAAa,EAAQ,EAASA,EAAO,IAAI,EAAO,CAAC,EAAY,GAAgBC,EAAS,EAAK,EAAQ,EAAWD,EAAO,EAAK,EAClT,CAAC,EAAK,GAASC,EAAS,CAAC,KAAK,EAAQ,KAAK,CAAC,CAAC,EAE5C,EAAUD,EAAO,CAAC,CAAC,EAAQ,EAAY,EAAK,KAAK,EAAK,KAAK,SAAS,EAAc,EAAM,EAAO,CAAC,IAAM,EAAO,CAAC,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,EAAM,IAAK,EAAO,KAAK,KAAK,OAAO,EAAE,CAAM,EAAG,OAAO,CAAO,CAAC,SAAS,EAAS,EAAK,CAAC,IAAM,EAAU,EAAO,WAAW,EAAwD,MAAM,CAAC,OAAK,KAApD,KAAK,KAAK,EAAO,YAAY,CAA0B,CAAC,CAAE,CAAC,IAAM,EAAqB,IAAS,QAAY,EAAO,WAAW,kCAAkC,CAAC,CAAC,QACva,CAAC,GAAcC,MAAwB,IAAS,QAAa,EAAgB,GAAa,eAAe,QAAQ,CAAW,IAAI,MAAQ,EAAQ,EAAgBD,EAAO,CAAY,EAClL,EAAW,CAAC,IAAI,EAAE,IAAI,CAAC,EAAQ,EAAa,GAYlD,GAXA,MAAoB,CAAC,GAAG,EAAS,OAAU,GAAa,eAAe,WAAW,CAAW,EAC7F,IAAM,EAAE,EAAS,CAAO,EAAE,EAAQ,CAAC,EAAE,EAAU,QAAQ,EAAc,EAAE,KAAK,EAAE,KAAK,CAAY,EAAE,IAAM,EAAG,SAAS,cAAc,KAAK,EAAE,EAAG,aAAa,4BAA4B,EAAE,EAAE,SAAS,KAAK,YAAY,CAAE,EAAE,EAAS,QAAQ,EAAG,EAAe,EAAI,EAAE,IAAM,MAAiB,CAAC,IAAM,EAAG,EAAS,CAAO,EAAE,EAAQ,CAAE,EAAE,EAAU,QAAQ,EAAc,EAAG,KAAK,EAAG,KAAK,CAAY,CAAE,EAAiD,OAA/C,EAAO,iBAAiB,SAAS,CAAY,MAAY,CAAC,EAAO,oBAAoB,SAAS,CAAY,EAAE,SAAS,KAAK,YAAY,CAAE,EAAE,EAAS,QAAQ,IAAK,CAAE,EAAE,CAAC,CAAC,EACpiB,MAAc,CAAI,IAAgB,EAAU,QAAQ,EAAc,EAAY,CAAY,EAAE,EAAE,CAAC,EAAY,CAAY,CAAC,EACxH,MAAc,CAAC,GAAG,GAAU,CAAC,GAAa,CAAC,EAAgB,QAAQ,OAAO,eAAe,GAAU,CAA0B,GAAzB,EAAW,QAAQ,GAAS,EAAc,CAAC,EAAS,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAO,CAAC,MAAM,IAAI,QAAQ,GAAG,WAAW,EAAE,GAAG,CAAC,EACvN,EAAU,QAAQ,EAAc,EAAY,CAAY,EACxD,MAAM,EAAS,MAAM,IAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,SAAS,EAAa,KAAK,EAAW,MAAM,EAAU,QAAQ,IAAS,CAAC,CAAC,EAAE,CAAE,CAAC,EAAS,CAAE,EAAE,CAAC,CAAW,CAAC,EAC7J,MAAc,CAAC,GAAG,EAAS,OAAO,IAAM,EAAY,GAAG,CAAC,IAAM,EAAO,EAAE,OAAO,QAAQ,SAAS,EAAE,GAAG,CAAC,EAAO,OAAO,GAAG,EAAgB,CAAC,EAAgB,GAAM,MAAO,CAAC,GAAG,EAAY,CAAC,EAAE,eAAe,EAAE,MAAO,CAAC,IAAM,EAAK,EAAO,aAAa,MAAM,EAC5L,GADiM,CAAC,GAAe,EAAK,WAAW,GAAG,GAAG,EAAK,WAAW,SAAS,GAAG,EAAK,WAAW,MAAM,GAAG,EAAK,WAAW,aAAa,GAC/W,EAAO,aAAa,yBAAyB,GAAY,EAAO,aAAa,QAAQ,IAAI,SAAS,OAAO,IAAI,EAAU,GAAG,CAA8C,GAA7C,EAAU,IAAI,IAAI,EAAK,EAAO,SAAS,IAAI,EAAK,EAAU,WAAW,EAAO,SAAS,SAAS,MAAO,MAAM,CAAC,MAAO,CAAC,GAAG,EAAU,WAAW,EAAO,SAAS,SAAS,OAAO,EAAE,eAAe,EAAE,EAAE,gBAAgB,EAAE,EAAY,GAAK,eAAe,GAAU,CAAC,GAAG,EAAc,CAAC,eAAe,QAAQ,EAAY,MAAM,EAAE,EAAgB,GAAK,EAAY,GAAM,EAAO,MAAM,EAAE,MAAO,CACtf,EAAU,QAAQ,EAAc,EAAY,CAAY,EACxD,MAAM,EAAS,MAAM,IAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,SAAS,EAAa,KAAK,EAAW,MAAM,EAAU,QAAQ,IAAS,CAAC,CAAC,EAAE,EAAE,eAAe,QAAQ,EAAY,MAAM,EAAE,EAAW,QAAQ,GAAK,EAAgB,GAAK,EAAY,GAAM,EAAO,MAAM,EACzP,IAAM,GAAY,EAAa,GAAc,IAAI,IAAI,WAAW,SAAS,CAAK,EAAW,UAAe,EAAW,QAAQ,GAAM,EAAY,GAAM,eAAe,WAAW,CAAW,EAAE,EAAU,QAAQ,EAAc,EAAY,CAAY,EAAE,MAAM,EAAS,MAAM,IAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,SAAS,EAAa,KAAK,EAAW,MAAM,EAAU,QAAQ,IAAS,CAAC,CAAC,EAAE,EAAE,EAAE,CAAU,CAAE,CAAC,EAAS,CAAE,EAAsD,OAApD,SAAS,iBAAiB,QAAQ,EAAY,EAAI,MAAY,SAAS,oBAAoB,QAAQ,EAAY,EAAI,CAAE,EAAE,CAAC,EAAQ,EAAa,EAAa,CAAW,CAAC,EACrjB,EAAS,OAAoB,EAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAa,CAAC,EAAS,QAAQ,OAAO,KAAK,IAAM,EAAU,GAAG,IAAI,EAAK,KAAK,IAAU,EAAe,KAAiB,OAAoB,EAA0B,EAAK,MAAM,CAAC,MAAM,CAAC,SAAS,QAAQ,MAAM,EAAE,OAAO,KAAK,cAAc,OAAO,QAAQ,OAAO,oBAAoB,UAAU,EAAK,KAAK,QAAQ,iBAAiB,UAAU,EAAK,KAAK,IAAI,EAAU,GAAG,SAAS,QAAQ,EAAE,SAAS,MAAM,KAAK,CAAC,OAAO,CAAW,CAAC,CAAC,CAAC,KAAK,EAAE,IAAiB,EAAK,EAAO,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAS,QAAQ,CAAC,QAAQ,CAAc,EAAE,MAAM,CAAC,gBAAgB,CAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAS,OAAO,CAAE,2BAvBtnB,IAAiE,IAA6D,IAAoC,IAA+C,EAAO,EAAY,uBAG1Q,EAAgB,GAAU,EAAY,GAqB1C,EAAoB,EAAoB,CAAC,QAAQ,CAAC,KAAK,EAAY,OAAO,MAAM,UAAU,aAAa,EAAE,IAAI,EAAE,IAAI,GAAG,KAAK,EAAE,eAAe,GAAK,YAAY,yHAAyH,EAAE,WAAW,CAAC,KAAK,EAAY,MAAM,MAAM,QAAQ,aAAa,SAAS,EAAE,aAAa,CAAC,KAAK,EAAY,OAAO,MAAM,eAAe,aAAa,GAAG,IAAI,IAAI,IAAI,EAAE,KAAK,IAAI,KAAK,IAAI,eAAe,GAAK,YAAY,oEAAoE,EAAE,aAAa,CAAC,KAAK,EAAY,OAAO,MAAM,eAAe,aAAa,IAAI,IAAI,IAAI,IAAI,EAAE,KAAK,IAAI,KAAK,IAAI,eAAe,GAAK,YAAY,wUAAwU,CAAC,CAAC"}