{"version":3,"file":"ImageSequence.CnuCWCvS.mjs","names":["useRef","useState","useMemo","useCallback"],"sources":["https:/framerusercontent.com/modules/cEEh3PT7yDlYYKVWrUKH/QmRYRlam0hRfsOeNIJuj/ImageSequence.js"],"sourcesContent":["import{jsx as _jsx,jsxs as _jsxs}from\"react/jsx-runtime\";import{useRef,useEffect,useState,useCallback,useMemo}from\"react\";import{addPropertyControls,ControlType}from\"framer\";import{useScroll,useTransform,motion}from\"framer-motion\";// --- S3 Configuration ---\nconst S3_BASE_URL=\"https://d1jsmhnbf1xq2p.cloudfront.net/\";const BREAKPOINT=810;const getDeviceType=()=>{// Handle SSR: default to Desktop when window is not available\nif(typeof window===\"undefined\")return\"Desktop\";return window.innerWidth>=BREAKPOINT?\"Desktop\":\"Mobile\";};const createImageUrls=(folderName,imageCount,deviceType)=>{if(!folderName||imageCount<=0)return[];const prefix=`${folderName}-`;return Array.from({length:imageCount},(_,i)=>`${S3_BASE_URL}${deviceType}/${folderName}/${prefix}${i}.webp`);};const preloadImage=url=>{return new Promise(resolve=>{const img=new Image;img.onload=()=>resolve(img);img.onerror=()=>{console.warn(`Failed to load image: ${url}`);resolve(null);};img.src=url;});};const preloadImages=urls=>{return Promise.allSettled(urls.map(preloadImage)).then(results=>results.filter(res=>res.status===\"fulfilled\"&&res.value).map(res=>res.value));};// --- Loading Bar Component ---\nconst LoadingBar=()=>{return /*#__PURE__*/_jsx(motion.div,{style:styles.loadingBarContainer,children:/*#__PURE__*/_jsx(motion.div,{style:styles.loadingBar,animate:{x:[\"-100%\",\"200%\"],opacity:[.5,1,.5]},transition:{duration:1.5,repeat:Infinity,ease:\"easeInOut\"}})});};// --- Main Component ---\nexport function ScrollSequence(props){const{folderName,imageCount,scrollHeight}=props;const canvasRef=useRef(null);const scrollRef=useRef(null);const[loadedImages,setLoadedImages]=useState([]);const[isFullyLoaded,setIsFullyLoaded]=useState(false);const[deviceType,setDeviceType]=useState(getDeviceType());const imageUrls=useMemo(()=>createImageUrls(folderName,imageCount,deviceType),[folderName,imageCount,deviceType]);// Monitor viewport changes to detect device type switches\nuseEffect(()=>{const handleResize=()=>{const newDeviceType=getDeviceType();if(newDeviceType!==deviceType){setDeviceType(newDeviceType);}};window.addEventListener(\"resize\",handleResize);return()=>window.removeEventListener(\"resize\",handleResize);},[deviceType]);useEffect(()=>{if(imageUrls.length===0)return;// Phase 1: Load only the first image to show as a thumbnail\npreloadImage(imageUrls[0]).then(firstImage=>{if(firstImage){setLoadedImages([firstImage]);}// Phase 2: Load the rest of the images in the background\nif(imageUrls.length>1){preloadImages(imageUrls.slice(1)).then(restOfImages=>{setLoadedImages(prev=>[...prev,...restOfImages]);setIsFullyLoaded(true);});}else{setIsFullyLoaded(true);}});},[imageUrls]);const{scrollYProgress}=useScroll({target:scrollRef});const frameIndex=useTransform(scrollYProgress,[0,1],[0,loadedImages.length>0?loadedImages.length-1:0]);const drawFrame=useCallback(index=>{const canvas=canvasRef.current;if(!canvas||loadedImages.length===0)return;const context=canvas.getContext(\"2d\");if(!context)return;const safeIndex=Math.round(Math.max(0,Math.min(index,loadedImages.length-1)));const image=loadedImages[safeIndex];if(!image)return;const canvasWidth=canvas.width;const canvasHeight=canvas.height;const imageRatio=image.naturalWidth/image.naturalHeight;const canvasRatio=canvasWidth/canvasHeight;let renderWidth,renderHeight,x,y;if(canvasRatio>imageRatio){renderWidth=canvasWidth;renderHeight=canvasWidth/imageRatio;x=0;y=(canvasHeight-renderHeight)/2;}else{renderHeight=canvasHeight;renderWidth=canvasHeight*imageRatio;x=(canvasWidth-renderWidth)/2;y=0;}context.clearRect(0,0,canvasWidth,canvasHeight);context.drawImage(image,x,y,renderWidth,renderHeight);},[loadedImages]);useEffect(()=>{if(loadedImages.length===0)return;const canvas=canvasRef.current;const handleResize=()=>{if(!canvas.parentElement)return;const{width,height}=canvas.parentElement.getBoundingClientRect();canvas.width=width;canvas.height=height;drawFrame(frameIndex.get());};handleResize();window.addEventListener(\"resize\",handleResize);return()=>window.removeEventListener(\"resize\",handleResize);},[loadedImages,drawFrame,frameIndex]);useEffect(()=>{if(!isFullyLoaded||loadedImages.length<=1)return;const unsubscribe=frameIndex.onChange(latest=>{requestAnimationFrame(()=>drawFrame(latest));});return()=>unsubscribe();},[isFullyLoaded,loadedImages,drawFrame,frameIndex]);return /*#__PURE__*/_jsx(\"div\",{ref:scrollRef,style:{width:\"100%\",height:scrollHeight},children:/*#__PURE__*/_jsxs(\"div\",{style:styles.stickyContainer,children:[!isFullyLoaded&&loadedImages.length>0&&/*#__PURE__*/_jsx(LoadingBar,{}),/*#__PURE__*/_jsx(\"canvas\",{ref:canvasRef,style:styles.canvas})]})});}addPropertyControls(ScrollSequence,{folderName:{title:\"Folder Name\",type:ControlType.String,defaultValue:\"Approach\"},imageCount:{title:\"Image Count\",type:ControlType.Number,min:1,defaultValue:151},scrollHeight:{title:\"Scroll Height\",type:ControlType.String,defaultValue:\"400vh\"}});const styles={stickyContainer:{position:\"sticky\",top:0,height:\"100vh\",width:\"100%\",overflow:\"hidden\"},canvas:{width:\"100%\",height:\"100%\"},loadingBarContainer:{position:\"absolute\",left:0,width:\"100%\",bottom:0,height:\"5px\",pointerEvents:\"none\",overflow:\"hidden\",background:\"color-mix(in srgb, var(--sequence-loader-color, #FFD100), transparent 90%)\"},loadingBar:{position:\"absolute\",width:\"40%\",height:\"100%\",background:`linear-gradient(\n            90deg,\n            transparent 0%,\n            color-mix(in srgb, var(--sequence-loader-color, #FFD100), transparent 20%) 30%,\n            var(--sequence-loader-color, #FFD100) 50%,\n            color-mix(in srgb, var(--sequence-loader-color, #FFD100), transparent 20%) 70%,\n            transparent 100%\n        )`,boxShadow:`0 0 20px var(--sequence-loader-color, #FFD100)`,filter:\"blur(2px)\"}};\nexport const __FramerMetadata__ = {\"exports\":{\"ScrollSequence\":{\"type\":\"reactComponent\",\"name\":\"ScrollSequence\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./ImageSequence.map"],"mappings":"2RAIA,SAAgB,EAAe,EAAM,CAAC,GAAK,CAAC,aAAW,aAAW,gBAAc,EAAY,EAAUA,EAAO,KAAK,CAAO,EAAUA,EAAO,KAAK,CAAM,CAAC,EAAa,GAAiBC,EAAS,EAAE,CAAC,CAAM,CAAC,EAAc,GAAkBA,EAAS,GAAM,CAAM,CAAC,EAAW,GAAeA,EAAS,GAAe,CAAC,CAAO,EAAUC,MAAY,EAAgB,EAAW,EAAW,EAAW,CAAC,CAAC,EAAW,EAAW,EAAW,CAAC,CACla,MAAc,CAAC,IAAM,MAAiB,CAAC,IAAM,EAAc,GAAe,CAAI,IAAgB,GAAY,EAAc,EAAc,EAAmD,OAA/C,EAAO,iBAAiB,SAAS,EAAa,KAAW,EAAO,oBAAoB,SAAS,EAAa,EAAG,CAAC,EAAW,CAAC,CAAC,MAAc,CAAI,EAAU,SAAS,GAC1S,EAAa,EAAU,GAAG,CAAC,KAAK,GAAY,CAAI,GAAY,EAAgB,CAAC,EAAW,CAAC,CACtF,EAAU,OAAO,EAAG,EAAc,EAAU,MAAM,EAAE,CAAC,CAAC,KAAK,GAAc,CAAC,EAAgB,GAAM,CAAC,GAAG,EAAK,GAAG,EAAa,CAAC,CAAC,EAAiB,GAAK,EAAG,CAAO,EAAiB,GAAK,EAAI,EAAG,CAAC,EAAU,CAAC,CAAC,GAAK,CAAC,mBAAiB,EAAU,CAAC,OAAO,EAAU,CAAC,CAAO,EAAW,EAAa,EAAgB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAa,OAAO,EAAE,EAAa,OAAO,EAAE,EAAE,CAAC,CAAO,EAAUC,EAAY,GAAO,CAAC,IAAM,EAAO,EAAU,QAAQ,GAAG,CAAC,GAAQ,EAAa,SAAS,EAAE,OAAO,IAAM,EAAQ,EAAO,WAAW,KAAK,CAAC,GAAG,CAAC,EAAQ,OAAqF,IAAM,EAAM,EAA1E,KAAK,MAAM,KAAK,IAAI,EAAE,KAAK,IAAI,EAAM,EAAa,OAAO,EAAE,CAAC,CAAC,EAAqC,GAAG,CAAC,EAAM,OAAO,IAAM,EAAY,EAAO,MAAY,EAAa,EAAO,OAAa,EAAW,EAAM,aAAa,EAAM,cAAoB,EAAY,EAAY,EAAiB,EAAY,EAAa,EAAE,EAAK,EAAY,GAAY,EAAY,EAAY,EAAa,EAAY,EAAW,EAAE,EAAE,GAAG,EAAa,GAAc,IAAQ,EAAa,EAAa,EAAY,EAAa,EAAW,GAAG,EAAY,GAAa,EAAE,EAAE,GAAG,EAAQ,UAAU,EAAE,EAAE,EAAY,EAAa,CAAC,EAAQ,UAAU,EAAM,EAAE,EAAE,EAAY,EAAa,EAAG,CAAC,EAAa,CAAC,CAA6pB,OAA5pB,MAAc,CAAC,GAAG,EAAa,SAAS,EAAE,OAAO,IAAM,EAAO,EAAU,QAAc,MAAiB,CAAC,GAAG,CAAC,EAAO,cAAc,OAAO,GAAK,CAAC,QAAM,UAAQ,EAAO,cAAc,uBAAuB,CAAC,EAAO,MAAM,EAAM,EAAO,OAAO,EAAO,EAAU,EAAW,KAAK,CAAC,EAAiE,OAA9D,GAAc,CAAC,EAAO,iBAAiB,SAAS,EAAa,KAAW,EAAO,oBAAoB,SAAS,EAAa,EAAG,CAAC,EAAa,EAAU,EAAW,CAAC,CAAC,MAAc,CAAC,GAAG,CAAC,GAAe,EAAa,QAAQ,EAAE,OAAO,IAAM,EAAY,EAAW,SAAS,GAAQ,CAAC,0BAA0B,EAAU,EAAO,CAAC,EAAG,CAAC,UAAU,GAAa,EAAG,CAAC,EAAc,EAAa,EAAU,EAAW,CAAC,CAAqB,EAAK,MAAM,CAAC,IAAI,EAAU,MAAM,CAAC,MAAM,OAAO,OAAO,EAAa,CAAC,SAAsB,EAAM,MAAM,CAAC,MAAM,EAAO,gBAAgB,SAAS,CAAC,CAAC,GAAe,EAAa,OAAO,GAAgB,EAAK,EAAW,EAAE,CAAC,CAAc,EAAK,SAAS,CAAC,IAAI,EAAU,MAAM,EAAO,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,sCAP5jE,IAAiE,IAAoD,IAAyD,CACjO,EAAY,yCAA+C,EAAW,IAAU,MAC5E,IAAS,QAAmC,EAAO,YAAY,EAApC,UAAyD,SAAiB,GAAiB,EAAW,EAAW,IAAa,CAAC,GAAG,CAAC,GAAY,GAAY,EAAE,MAAM,EAAE,CAAC,IAAM,EAAO,GAAG,EAAW,GAAG,OAAO,MAAM,KAAK,CAAC,OAAO,EAAW,EAAE,EAAE,IAAI,GAAG,IAAc,EAAW,GAAG,EAAW,GAAG,IAAS,EAAE,OAAO,EAAS,EAAa,GAAa,IAAI,QAAQ,GAAS,CAAC,IAAM,EAAI,IAAI,MAAM,EAAI,WAAW,EAAQ,EAAI,CAAC,EAAI,YAAY,CAAC,QAAQ,KAAK,yBAAyB,IAAM,CAAC,EAAQ,KAAK,EAAG,EAAI,IAAI,GAAM,CAAS,EAAc,GAAc,QAAQ,WAAW,EAAK,IAAI,EAAa,CAAC,CAAC,KAAK,GAAS,EAAQ,OAAO,GAAK,EAAI,SAAS,aAAa,EAAI,MAAM,CAAC,IAAI,GAAK,EAAI,MAAM,CAAC,CAC/rB,MAAoC,EAAK,EAAO,IAAI,CAAC,MAAM,EAAO,oBAAoB,SAAsB,EAAK,EAAO,IAAI,CAAC,MAAM,EAAO,WAAW,QAAQ,CAAC,EAAE,CAAC,QAAQ,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,WAAW,CAAC,SAAS,IAAI,OAAO,IAAS,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAI+2D,EAAoB,EAAe,CAAC,WAAW,CAAC,MAAM,cAAc,KAAK,EAAY,OAAO,aAAa,WAAW,CAAC,WAAW,CAAC,MAAM,cAAc,KAAK,EAAY,OAAO,IAAI,EAAE,aAAa,IAAI,CAAC,aAAa,CAAC,MAAM,gBAAgB,KAAK,EAAY,OAAO,aAAa,QAAQ,CAAC,CAAC,CAAO,EAAO,CAAC,gBAAgB,CAAC,SAAS,SAAS,IAAI,EAAE,OAAO,QAAQ,MAAM,OAAO,SAAS,SAAS,CAAC,OAAO,CAAC,MAAM,OAAO,OAAO,OAAO,CAAC,oBAAoB,CAAC,SAAS,WAAW,KAAK,EAAE,MAAM,OAAO,OAAO,EAAE,OAAO,MAAM,cAAc,OAAO,SAAS,SAAS,WAAW,6EAA6E,CAAC,WAAW,CAAC,SAAS,WAAW,MAAM,MAAM,OAAO,OAAO,WAAW;;;;;;;WAOvyF,UAAU,iDAAiD,OAAO,YAAY,CAAC"}