{"version":3,"file":"LiquidImage.CJ4G9Val.mjs","names":["useRef","useState","useCallback","p","vs","fs"],"sources":["https:/framerusercontent.com/modules/L2g2etirT4tdjBaE4xrO/BzHG0pe3fwejvzhuvfLr/LiquidImage.js"],"sourcesContent":["// Liquid Image/Video Hover Effect with Color Reveal and Hotspots (Optimized)\n// Real-time water-like displacement, grayscale-to-color reveal, persistent hotspots.\n// Supports either an image or a video as the source.\nimport{jsx as _jsx}from\"react/jsx-runtime\";import{useRef,useEffect,useState,useCallback}from\"react\";import{addPropertyControls,ControlType,useIsStaticRenderer}from\"framer\";const defaultImage={src:\"https://framerusercontent.com/images/GfGkADagM4KEibNcIiRUWlfrR0.jpg\",alt:\"Gradient 1 - Blue\"};/**\n * @framerSupportedLayoutWidth any-prefer-fixed\n * @framerSupportedLayoutHeight any-prefer-fixed\n *\n * @framerDisableUnlink\n */export default function LiquidImage(props){const{sourceType=\"image\",image=defaultImage,video=\"https://framerusercontent.com/assets/MLWPbW1dUQawJLhhun3dBwpgJak.mp4\",strength=.15,speed=.18,fit=\"cover\",style,hotspots=[],borderRadius=8}=props;const isVideo=sourceType===\"video\"&&!!video;const wrapperRef=useRef(null);const canvasRef=useRef(null);const videoElRef=useRef(null);const offCanvasRef=useRef(null)// reused offscreen canvas (perf)\n;const[size,setSize]=useState({width:400,height:300});// Mirror of `size` the render loop can read every frame without\n// re-running the WebGL effect (avoids context-rebuild flash on resize).\nconst sizeRef=useRef({width:400,height:300});const dprRef=useRef(1);// Live ref so fit changes apply on the next frame without tearing\n// down and rebuilding the WebGL context (same pattern as size).\nconst fitRef=useRef(fit);fitRef.current=fit;const isStatic=useIsStaticRenderer();// Animation and interaction refs\nconst mouseRef=useRef({x:-10,y:-10,active:false});const maskRadiusRef=useRef(0);const wakeRef=useRef([]);const hotspotsRef=useRef(hotspots);const hoveredRef=useRef(false);// Only update hotspotsRef when hotspots prop changes\nuseEffect(()=>{hotspotsRef.current=hotspots;},[hotspots]);// Size tracking: observe the WRAPPER (not the canvas), and use a\n// ResizeObserver so container/layout changes (e.g. Framer \"Fill\")\n// are caught — a window resize listener misses those.\nuseEffect(()=>{const el=wrapperRef.current;if(!el)return;const measure=()=>{let dpr=1;if(typeof window!==\"undefined\"){dpr=window.devicePixelRatio||1;}dprRef.current=dpr;const rect=el.getBoundingClientRect();const w=Math.max(1,Math.round(rect.width*dpr));const h=Math.max(1,Math.round(rect.height*dpr));// Update the ref synchronously so the render loop sees the new\n// size on its very next frame, independent of React's re-render.\nsizeRef.current={width:w,height:h};setSize(prev=>prev.width===w&&prev.height===h?prev:{width:w,height:h});};measure();if(typeof window!==\"undefined\"&&typeof window.ResizeObserver!==\"undefined\"){const ro=new window.ResizeObserver(measure);ro.observe(el);// devicePixelRatio can change (zoom / monitor move) without a\n// resize of the element — keep the window listener as a backstop.\nwindow.addEventListener(\"resize\",measure);return()=>{ro.disconnect();window.removeEventListener(\"resize\",measure);};}// Fallback for environments without ResizeObserver\nif(typeof window!==\"undefined\"){window.addEventListener(\"resize\",measure);return()=>window.removeEventListener(\"resize\",measure);}return()=>{};},[]);// Mouse events (no state updates on move)\nconst handleMove=useCallback(e=>{if(!canvasRef.current)return;const rect=canvasRef.current.getBoundingClientRect();let x,y;if(e.touches&&e.touches.length>0){x=(e.touches[0].clientX-rect.left)/rect.width;y=(e.touches[0].clientY-rect.top)/rect.height;}else{x=(e.clientX-rect.left)/rect.width;y=(e.clientY-rect.top)/rect.height;}x=Math.max(0,Math.min(1,x));y=Math.max(0,Math.min(1,y));mouseRef.current={x,y,active:true};hoveredRef.current=true;// Add a wake point (limit to 8 recent)\nconst now=Date.now();wakeRef.current=[...wakeRef.current.filter(w=>now-w.t<1200),{x,y,t:now}].slice(-8);},[]);const handleLeave=useCallback(()=>{mouseRef.current={...mouseRef.current,active:false};hoveredRef.current=false;},[]);// Animate mask radius on hover in/out (single animation loop, easeInOut cubic)\nuseEffect(()=>{let animId;let lastHovered=false;let start=null;let from=0;let to=0;let duration=650// ms, slower for smoother effect\n;function easeInOutCubic(t){return t<.5?4*t*t*t:1-Math.pow(-2*t+2,3)/2;}function animate(ts){const hovered=hoveredRef.current;if(hovered!==lastHovered){lastHovered=hovered;start=ts;from=maskRadiusRef.current;to=hovered?1.5:0;}if(start===null)start=ts;const elapsed=Math.min((ts-start)/duration,1);const eased=easeInOutCubic(elapsed);maskRadiusRef.current=from+(to-from)*eased;if(elapsed<1){animId=requestAnimationFrame(animate);}else{maskRadiusRef.current=to;animId=requestAnimationFrame(animate);}}animId=requestAnimationFrame(animate);return()=>animId&&cancelAnimationFrame(animId);},[]);// WebGL shader effect (single stable render loop)\nuseEffect(()=>{if(!canvasRef.current||isStatic)return;// Initial canvas size from the ref (high-DPI). Subsequent resizes\n// are applied inside the render loop without rebuilding the context.\nconst initialDpr=dprRef.current||1;const initialSize=sizeRef.current;canvasRef.current.width=initialSize.width;canvasRef.current.height=initialSize.height;canvasRef.current.style.width=initialSize.width/initialDpr+\"px\";canvasRef.current.style.height=initialSize.height/initialDpr+\"px\";// Track the size the canvas/viewport are currently configured for,\n// so the loop only reconfigures when it actually changes.\nlet appliedW=initialSize.width;let appliedH=initialSize.height;let gl=canvasRef.current.getContext(\"webgl\");if(!gl)return;let animationId;// --- Source setup: image OR video ---\nlet img=null;let videoEl=null;let mediaReady=false;if(isVideo){videoEl=document.createElement(\"video\");videoEl.crossOrigin=\"anonymous\";videoEl.src=video;videoEl.muted=true;videoEl.loop=true;videoEl.playsInline=true;videoEl.autoplay=true;videoEl.setAttribute(\"playsinline\",\"\");videoElRef.current=videoEl;}else{img=new window.Image;img.crossOrigin=\"anonymous\";img.src=image.src;}let tex,program,uTime,uMouse,uStrength,uSpeed,uResolution,uWake,uWakeCount,uMaskRadius;let startTime=Date.now();let loaded=false;// Vertex shader\nconst vs=`\n            attribute vec2 a_position;\n            varying vec2 v_uv;\n            void main() {\n                v_uv = a_position * 0.5 + 0.5;\n                gl_Position = vec4(a_position, 0, 1);\n            }\n        `;// Fragment shader with wake effect and grayscale/color reveal\nconst fs=`\n            precision highp float;\n            varying vec2 v_uv;\n            uniform sampler2D u_image;\n            uniform vec2 u_mouse;\n            uniform float u_time;\n            uniform float u_strength;\n            uniform float u_speed;\n            uniform vec2 u_resolution;\n            #define MAX_WAKE 16\n            uniform int u_wakeCount;\n            uniform vec3 u_wake[MAX_WAKE]; // x, y, t (t = seconds since start)\n            uniform float u_maskRadius; // in [0,1], relative to min(width, height)\n            void main() {\n                vec2 uv = v_uv;\n                float total = 0.0;\n                // Wake ripples\n                for (int i = 0; i < MAX_WAKE; ++i) {\n                    if (i >= u_wakeCount) break;\n                    vec2 w = u_wake[i].xy;\n                    float t = u_time - u_wake[i].z;\n                    float dist = distance(uv, w);\n                    float amp = exp(-dist * 16.0) * exp(-t * 1.2);\n                    float ripple = sin(32.0 * dist - t * 8.0 * u_speed) * 0.04;\n                    uv += normalize(uv - w) * ripple * u_strength * amp * 2.0;\n                }\n                // Live mouse ripple\n                if (u_mouse.x >= 0.0 && u_mouse.x <= 1.0 && u_mouse.y >= 0.0 && u_mouse.y <= 1.0) {\n                    float dist = distance(uv, u_mouse);\n                    float ripple = sin(32.0 * dist - u_time * 8.0 * u_speed) * 0.04;\n                    float effect = exp(-dist * 12.0);\n                    uv += normalize(uv - u_mouse) * ripple * u_strength * effect * 2.0;\n                }\n                uv = clamp(uv, 0.0, 1.0);\n                vec4 color = texture2D(u_image, uv);\n                // Grayscale\n                float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));\n                vec3 grayColor = vec3(gray);\n                // Color reveal mask: union of all active hotspots and mouse\n                float mask = 0.0;\n                float maskRadius = u_maskRadius; // in [0,1], relative to min(width, height)\n                // Mouse mask\n                if (u_mouse.x >= 0.0 && u_mouse.x <= 1.0 && u_mouse.y >= 0.0 && u_mouse.y <= 1.0 && maskRadius > 0.0) {\n                    float d = distance(uv, u_mouse);\n                    mask = max(mask, smoothstep(maskRadius, maskRadius * 0.8, d));\n                }\n                // Hotspot masks\n                for (int i = 0; i < MAX_WAKE; ++i) {\n                    if (i >= u_wakeCount) break;\n                    vec2 w = u_wake[i].xy;\n                    float d = distance(uv, w);\n                    mask = max(mask, smoothstep(maskRadius, maskRadius * 0.8, d));\n                }\n                // Blend\n                vec3 finalColor = mix(grayColor, color.rgb, mask);\n                gl_FragColor = vec4(finalColor, color.a);\n            }\n        `;function createShader(type,src){let s=gl.createShader(type);gl.shaderSource(s,src);gl.compileShader(s);return s;}function createProgram(vs,fs){let p=gl.createProgram();gl.attachShader(p,vs);gl.attachShader(p,fs);gl.linkProgram(p);return p;}function setup(){// Create shaders\nlet vshader=createShader(gl.VERTEX_SHADER,vs);let fshader=createShader(gl.FRAGMENT_SHADER,fs);program=createProgram(vshader,fshader);gl.useProgram(program);// Quad\nlet pos=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,pos);gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),gl.STATIC_DRAW);let loc=gl.getAttribLocation(program,\"a_position\");gl.enableVertexAttribArray(loc);gl.vertexAttribPointer(loc,2,gl.FLOAT,false,0,0);// Uniforms\nuTime=gl.getUniformLocation(program,\"u_time\");uMouse=gl.getUniformLocation(program,\"u_mouse\");uStrength=gl.getUniformLocation(program,\"u_strength\");uSpeed=gl.getUniformLocation(program,\"u_speed\");uResolution=gl.getUniformLocation(program,\"u_resolution\");uWake=gl.getUniformLocation(program,\"u_wake\");uWakeCount=gl.getUniformLocation(program,\"u_wakeCount\");uMaskRadius=gl.getUniformLocation(program,\"u_maskRadius\");// Texture\ntex=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,tex);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);gl.activeTexture(gl.TEXTURE0);gl.uniform1i(gl.getUniformLocation(program,\"u_image\"),0);loaded=true;mediaReady=true;}// Get (or lazily create) the single reused offscreen canvas\nfunction getOffscreen(w,h){let off=offCanvasRef.current;if(!off){off=document.createElement(\"canvas\");offCanvasRef.current=off;}if(off.width!==w||off.height!==h){off.width=w;off.height=h;}return off;}if(isVideo){const startPlayback=()=>{setup();// Best-effort autoplay; browsers require muted (set above)\nconst p=videoEl.play();if(p&&typeof p.catch===\"function\"){p.catch(()=>{});}render();};// loadeddata fires once enough frame data exists to draw\nvideoEl.addEventListener(\"loadeddata\",startPlayback,{once:true});// In case it's already buffered (cached)\nif(videoEl.readyState>=2)startPlayback();}else{img.onload=()=>{setup();render();};}function updateTexture(){if(!tex)return;gl.bindTexture(gl.TEXTURE_2D,tex);gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);let offW=sizeRef.current.width;let offH=sizeRef.current.height;let off=getOffscreen(offW,offH);let ctx=off.getContext(\"2d\");// Source dimensions differ between image and video\nlet sourceEl,iw,ih;if(isVideo){sourceEl=videoEl;iw=videoEl.videoWidth;ih=videoEl.videoHeight;// Video not ready yet this frame — skip upload\nif(!iw||!ih)return;}else{sourceEl=img;iw=img.width;ih=img.height;}// Fit math: cover (crop), contain (letterbox), or fill (stretch)\nconst fitMode=fitRef.current;let sx,sy,sw,sh;if(fitMode===\"fill\"){// Stretch source across the whole frame, ignoring aspect ratio\nsx=0;sy=0;sw=offW;sh=offH;}else if(fitMode===\"contain\"){// Fit entire source inside the frame, letterbox the rest\nlet scale=Math.min(offW/iw,offH/ih);sw=iw*scale;sh=ih*scale;sx=(offW-sw)/2;sy=(offH-sh)/2;}else{// \"cover\" (default): fill frame, crop overflow\nlet scale=Math.max(offW/iw,offH/ih);sw=iw*scale;sh=ih*scale;sx=(offW-sw)/2;sy=(offH-sh)/2;}// Transparent clear — in Contain mode the letterbox stays\n// transparent so whatever is placed behind the component\n// (e.g. a colored Frame) shows through.\nctx.clearRect(0,0,offW,offH);ctx.drawImage(sourceEl,sx,sy,sw,sh);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,off);}function render(){if(!loaded)return;// Pick up the current size once per frame. If it changed,\n// reconfigure the canvas backing store + viewport in this same\n// frame, before updateTexture() (which reads the same ref),\n// so there's no one-frame stretch during a drag.\nconst curW=sizeRef.current.width;const curH=sizeRef.current.height;if(curW!==appliedW||curH!==appliedH){const d=dprRef.current||1;if(canvasRef.current){canvasRef.current.width=curW;canvasRef.current.height=curH;canvasRef.current.style.width=curW/d+\"px\";canvasRef.current.style.height=curH/d+\"px\";}appliedW=curW;appliedH=curH;}updateTexture();gl.viewport(0,0,curW,curH);gl.clear(gl.COLOR_BUFFER_BIT);const now=(Date.now()-startTime)/1e3;gl.uniform1f(uTime,now);// Clamp mouse to [0,1] and invert y for WebGL\nlet mx=mouseRef.current.active?Math.max(0,Math.min(1,mouseRef.current.x)):-10;let my=mouseRef.current.active?Math.max(0,Math.min(1,mouseRef.current.y)):-10;my=1-my;gl.uniform2f(uMouse,mx,my);gl.uniform1f(uStrength,strength*2.5);gl.uniform1f(uSpeed,speed);gl.uniform2f(uResolution,curW,curH);// Wake effect (user + hotspots)\nlet nowMs=Date.now();let wakeArr=wakeRef.current.slice(-8);// Add persistent hotspots\nlet hotspotArr=(hotspotsRef.current||[]).slice(0,8).map(h=>({x:h.x,y:h.y,t:nowMs-1e5}));let allWake=[...wakeArr,...hotspotArr].slice(-16);let wakeData=new Float32Array(16*3);let count=0;for(let i=0;i<allWake.length;++i){let w=allWake[i];// Invert y for WebGL\nwakeData[i*3+0]=w.x;wakeData[i*3+1]=1-w.y;wakeData[i*3+2]=(w.t-startTime)/1e3;count++;}gl.uniform1i(uWakeCount,count);gl.uniform3fv(uWake,wakeData);// Mask radius\ngl.uniform1f(uMaskRadius,maskRadiusRef.current);gl.drawArrays(gl.TRIANGLE_STRIP,0,4);animationId=requestAnimationFrame(render);}return()=>{if(animationId)cancelAnimationFrame(animationId);if(videoEl){try{videoEl.pause();}catch(e){}videoEl.removeAttribute(\"src\");videoEl.load();}videoElRef.current=null;gl=null;};},[isVideo,image.src,video,// size.width / size.height intentionally excluded: resizing is\n// handled live inside the render loop via sizeRef, so the WebGL\n// context is no longer torn down and rebuilt on every resize.\nstrength,speed,isStatic]);// Static fallback\nif(isStatic){return /*#__PURE__*/_jsx(\"div\",{style:{width:\"100%\",height:\"100%\",position:\"relative\",overflow:\"hidden\",borderRadius,...style},children:isVideo?/*#__PURE__*/_jsx(\"video\",{src:video,muted:true,loop:true,playsInline:true,autoPlay:true,style:{width:\"100%\",height:\"100%\",objectFit:fit,display:\"block\",borderRadius}}):/*#__PURE__*/_jsx(\"img\",{src:image.src,alt:image.alt,style:{width:\"100%\",height:\"100%\",objectFit:fit,display:\"block\",borderRadius}})});}return /*#__PURE__*/_jsx(\"div\",{ref:wrapperRef,style:{width:\"100%\",height:\"100%\",position:\"relative\",overflow:\"hidden\",borderRadius,...style},onMouseMove:handleMove,onMouseLeave:handleLeave,onTouchMove:handleMove,onTouchEnd:handleLeave,children:/*#__PURE__*/_jsx(\"canvas\",{ref:canvasRef,width:size.width,height:size.height,style:{width:\"100%\",height:\"100%\",display:\"block\",borderRadius},\"aria-label\":isVideo?\"Video\":image.alt})});}addPropertyControls(LiquidImage,{sourceType:{type:ControlType.Enum,title:\"Source\",options:[\"image\",\"video\"],optionTitles:[\"Image\",\"Video\"],defaultValue:\"image\",displaySegmentedControl:true},image:{type:ControlType.ResponsiveImage,title:\"Image\",description:\"Add your image here.\",hidden:props=>props.sourceType===\"video\"},video:{type:ControlType.File,title:\"Video\",allowedFileTypes:[\"mp4\",\"webm\",\"mov\"],description:\"Add your video here.\",hidden:props=>props.sourceType!==\"video\"},fit:{type:ControlType.Enum,title:\"Fit\",options:[\"cover\",\"contain\",\"fill\"],optionTitles:[\"Cover\",\"Contain\",\"Fill\"],defaultValue:\"cover\",description:\"Cover crops to fill, Contain fits the whole source, Fill stretches.\"},strength:{type:ControlType.Number,title:\"Strength\",description:\"Amount of displacement.\",defaultValue:.03,min:.01,max:.5,step:.01},speed:{type:ControlType.Number,title:\"Speed\",description:\"Speed of animation.\",defaultValue:.14,min:.01,max:1,step:.01},borderRadius:{type:ControlType.Number,title:\"Radius\",description:\"Radius of displacement.\\n\\nMore components at [gustavwf.supply](https://gustavwf.supply/)\",defaultValue:8,min:0,max:64}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"LiquidImage\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\",\"framerDisableUnlink\":\"\",\"framerSupportedLayoutWidth\":\"any-prefer-fixed\",\"framerSupportedLayoutHeight\":\"any-prefer-fixed\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./LiquidImage.map"],"mappings":"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"}