{"version":3,"file":"Image_zoom.B3oZAXl5.mjs","names":["React.useRef","React.useState","React.useMemo"],"sources":["https:/framerusercontent.com/modules/W03ORNEvSalaYAE0vLi0/iR3v5eU3w7GmAB4xlb1c/Image_zoom.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import*as React from\"react\";import{addPropertyControls,ControlType}from\"framer\";export default function ScrollScaleImage(props){const{image,minScale=2,maxScale=1,height=\"100vh\",smoothness=.12,curveStrength=2}=props;const ref=React.useRef(null);const imgRef=React.useRef(null)// <-- added\n;const rafRef=React.useRef(null);const scaleRef=React.useRef(minScale);const[,setTick]=React.useState(0);// Handle Framer image objects\nconst imageSrc=React.useMemo(()=>{if(!image)return\"\";if(typeof image===\"string\")return image;return image.src||image.url||image.imageUrl||image.fileUrl||image.data||\"\";},[image]);// --- INITIAL MEASURE BEFORE FIRST PAINT to prevent initial jitter ---\nReact.useLayoutEffect(()=>{const el=ref.current;if(!el)return;const getScrollParent=node=>{let parent=node?.parentElement;while(parent){const style=getComputedStyle(parent);if(/(auto|scroll)/.test(style.overflowY))return parent;parent=parent.parentElement;}return window;};const scrollRoot=getScrollParent(el);const doInitialCompute=()=>{// run the same compute logic once synchronously to set initial scaleRef\nconst rect=ref.current?.getBoundingClientRect();if(!rect)return;const vpHeight=scrollRoot instanceof Window?window.innerHeight:scrollRoot.clientHeight;const rootTop=scrollRoot instanceof Window?0:scrollRoot.getBoundingClientRect().top;const elCenter=rect.top+rect.height/2;const viewportCenter=rootTop+vpHeight/2;const distance=Math.abs(elCenter-viewportCenter);const maxDistance=vpHeight/2+rect.height/2;let t=Math.min(1,Math.max(0,distance/maxDistance))// 0=center, 1=out\n;t=Math.pow(t,curveStrength);const targetScale=maxScale+(minScale-maxScale)*t;// set without animation so first paint uses correct scale\nscaleRef.current=targetScale;// force one render so React applies the transform inline style\nsetTick(n=>(n+1)%1e6);};const imgEl=imgRef.current;if(imgEl){if(imgEl.complete){doInitialCompute();}else{imgEl.addEventListener(\"load\",doInitialCompute,{once:true});}}else{// no image element available — still attempt initial compute\ndoInitialCompute();}return()=>{if(imgEl)imgEl.removeEventListener(\"load\",doInitialCompute);};// intentionally only depends on imageSrc and curve params\n},[imageSrc,minScale,maxScale,curveStrength]);React.useEffect(()=>{const el=ref.current;if(!el)return;const getScrollParent=node=>{let parent=node?.parentElement;while(parent){const style=getComputedStyle(parent);if(/(auto|scroll)/.test(style.overflowY))return parent;parent=parent.parentElement;}return window;};const scrollRoot=getScrollParent(el);const compute=()=>{if(!ref.current)return;const rect=ref.current.getBoundingClientRect();const vpHeight=scrollRoot instanceof Window?window.innerHeight:scrollRoot.clientHeight;const rootTop=scrollRoot instanceof Window?0:scrollRoot.getBoundingClientRect().top;const elCenter=rect.top+rect.height/2;const viewportCenter=rootTop+vpHeight/2;const distance=Math.abs(elCenter-viewportCenter);const maxDistance=vpHeight/2+rect.height/2;let t=Math.min(1,Math.max(0,distance/maxDistance))// 0=center, 1=out\n;// Apply curve — exponential ease (higher curveStrength = more easing)\n// 0 stays 0, 1 stays 1, middle flattens\nt=Math.pow(t,curveStrength);const targetScale=maxScale+(minScale-maxScale)*t;const prev=scaleRef.current;const smoothed=prev+(targetScale-prev)*Math.min(1,smoothness*60);scaleRef.current=smoothed;setTick(n=>(n+1)%1e6);};const onScroll=()=>{if(rafRef.current)cancelAnimationFrame(rafRef.current);rafRef.current=requestAnimationFrame(compute);};compute();const root=scrollRoot===window?window:scrollRoot;root.addEventListener(\"scroll\",onScroll,{passive:true});window.addEventListener(\"resize\",onScroll,{passive:true});return()=>{if(rafRef.current)cancelAnimationFrame(rafRef.current);root.removeEventListener(\"scroll\",onScroll);window.removeEventListener(\"resize\",onScroll);};},[minScale,maxScale,smoothness,curveStrength,imageSrc]);const currentScale=scaleRef.current;return /*#__PURE__*/_jsx(\"div\",{ref:ref,style:{width:\"100%\",height,overflow:\"hidden\",position:\"relative\",background:imageSrc?undefined:\"#eee\"},children:imageSrc?/*#__PURE__*/_jsx(\"img\",{ref:imgRef,src:imageSrc,alt:\"\",style:{position:\"absolute\",inset:0,width:\"100%\",height:\"100%\",objectFit:\"cover\",transform:`scale(${currentScale})`,transformOrigin:\"center\",willChange:\"transform\",transition:\"transform 0.06s linear\"}}):/*#__PURE__*/_jsx(\"div\",{style:{width:\"100%\",height:\"100%\",display:\"flex\",alignItems:\"center\",justifyContent:\"center\",color:\"#999\"},children:\"Drop an image\"})});}addPropertyControls(ScrollScaleImage,{image:{type:ControlType.Image,title:\"Image\"},minScale:{type:ControlType.Number,title:\"Out Scale\",defaultValue:2,min:.5,max:5,step:.1},maxScale:{type:ControlType.Number,title:\"Center Scale\",defaultValue:1,min:.1,max:3,step:.05},height:{type:ControlType.String,title:\"Height\",defaultValue:\"100vh\"},smoothness:{type:ControlType.Number,title:\"Smoothness\",defaultValue:.12,min:.01,max:1,step:.01},curveStrength:{type:ControlType.Number,title:\"Curve\",defaultValue:2,min:1,max:5,step:.1}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"ScrollScaleImage\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./Image_zoom.map"],"mappings":"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"}