{"version":3,"file":"Snowfall.DPGNA09Z.mjs","names":["useRef","useState"],"sources":["https:/framerusercontent.com/modules/2MBTAbBshn8m8yhggIiY/iIxdYH5GSuxkpk2YLPvX/Snowfall.js"],"sourcesContent":["// Snowfall Effect for Xmas Theme Page\n// @framerSupportedLayoutWidth any-prefer-fixed\n// @framerSupportedLayoutHeight any-prefer-fixed\nimport{jsx as _jsx}from\"react/jsx-runtime\";import{useEffect,useRef,useState}from\"react\";import{addPropertyControls,ControlType,useIsStaticRenderer}from\"framer\";/**\n * Snowfall Effect\n *\n * @framerIntrinsicWidth 400\n * @framerIntrinsicHeight 400\n *\n * @framerSupportedLayoutWidth any-prefer-fixed\n * @framerSupportedLayoutHeight any-prefer-fixed\n */function randomBetween(min,max){return Math.random()*(max-min)+min;}function createSnowflakes(count,width,height){let flakes=[];for(let i=0;i<count;i++){// Each flake gets a depth 0..1: depth = 0 is up-close/big, depth = 1 is far/small\nconst depth=randomBetween(0,1);// Flake radius: interpolate between min and max size based on depth inverted (so closer = bigger)\n// See note: need to pass minR/maxR later\nflakes.push({x:randomBetween(0,width),y:randomBetween(0,height),r:undefined,speed:randomBetween(.5+1.5*(1-depth),2.2+2*(1-depth)),drift:randomBetween(-1,1)*(1-depth*.7),opacity:.3+.7*(1-depth),blur:0+2.5*depth,depth:depth});}return flakes;}function updateSnowflakes(snowflakes,width,height){// Build the snow pile array - track the height of snow at each x position\nlet pile=new Array(Math.ceil(width)).fill(0);// First pass: record all settled flakes to build the pile\nsnowflakes.forEach(flake=>{if(flake.speed===0){const xIndex=Math.max(0,Math.min(Math.floor(flake.x),pile.length-1));const flakeTop=flake.y+flake.r*2// Height of snow is flake position + diameter\n;pile[xIndex]=Math.max(pile[xIndex],flakeTop);}});// Filter out flakes that are way off canvas\nconst liveFlakes=snowflakes.filter(flake=>flake.y<height+100&&flake.x>=-100&&flake.x<=width+100);let rePopCount=snowflakes.length-liveFlakes.length;// Spawn new flakes at the top to maintain count\nfor(let i=0;i<rePopCount;i++){const depth=randomBetween(0,1);liveFlakes.push({x:randomBetween(0,width),y:randomBetween(-50,-10),r:undefined,speed:randomBetween(.5+1.5*(1-depth),2.2+2*(1-depth)),drift:randomBetween(-1,1)*(1-depth*.7),opacity:.3+.7*(1-depth),blur:0+2.5*depth,depth:depth});}return liveFlakes.map(flake=>{// Skip settled flakes\nif(flake.speed===0){return flake;}let y=flake.y+flake.speed;let x=flake.x+flake.drift;let speed=flake.speed;let drift=flake.drift;// Check collision with pile or bottom\nconst xIndex=Math.max(0,Math.min(Math.floor(x),pile.length-1));const pileHeight=pile[xIndex];// If flake reaches the pile or bottom\nif(y+flake.r>=height-pileHeight){y=height-pileHeight-flake.r;speed=0;drift=0;}return{...flake,y,x,speed,drift};});}export default function Snowfall(props){const{snowColor,snowflakeCount,snowflakeMinSize,snowflakeMaxSize,backgroundColor,style}=props;const containerRef=useRef(null);const animationRef=useRef(null);const[dimensions,setDimensions]=useState({width:400,height:400});const[snowflakes,setSnowflakes]=useState(()=>createSnowflakes(snowflakeCount,400,400));const isStatic=useIsStaticRenderer();// Sync snowflake count and bounds\nuseEffect(()=>{const{width,height}=containerRef.current?.getBoundingClientRect?.()||dimensions;setSnowflakes(createSnowflakes(snowflakeCount,width,height));},[snowflakeCount,snowflakeMinSize,snowflakeMaxSize]);// Watch resizing\nuseEffect(()=>{function onResize(){if(containerRef.current){const rect=containerRef.current.getBoundingClientRect();setDimensions({width:rect.width,height:rect.height});}}onResize();window.addEventListener(\"resize\",onResize);return()=>window.removeEventListener(\"resize\",onResize);},[]);// Animate\nuseEffect(()=>{if(isStatic)return;function animate(){setSnowflakes(sf=>updateSnowflakes(sf,dimensions.width,dimensions.height));animationRef.current=requestAnimationFrame(animate);}animationRef.current=requestAnimationFrame(animate);return()=>cancelAnimationFrame(animationRef.current);},[dimensions,isStatic]);// Static renderer: render snowflakes once and don't animate\nuseEffect(()=>{if(!isStatic)return;setSnowflakes(createSnowflakes(snowflakeCount,dimensions.width,dimensions.height));},[isStatic,dimensions,snowflakeCount]);// Responsive mins\nconst minR=Math.max(1,snowflakeMinSize);const maxR=Math.max(minR,snowflakeMaxSize);// Patch: set r for each flake based on its depth\nconst flakesWithR=snowflakes.map(f=>({...f,r:minR+(maxR-minR)*(1-f.depth)}));return /*#__PURE__*/_jsx(\"div\",{ref:containerRef,style:{...style,minWidth:5,minHeight:5,width:\"100%\",height:\"100%\",position:\"relative\",background:backgroundColor,overflow:\"hidden\",pointerEvents:\"none\"},\"aria-label\":\"Snowfall animation\",role:\"img\",children:/*#__PURE__*/_jsx(\"svg\",{width:\"100%\",height:\"100%\",style:{position:\"absolute\",left:0,top:0,width:\"100%\",height:\"100%\"},children:flakesWithR.map((flake,i)=>/*#__PURE__*/_jsx(\"circle\",{cx:flake.x,cy:flake.y,r:flake.r,fill:snowColor,fillOpacity:flake.opacity,style:flake.blur>0?{filter:`blur(${flake.blur}px)`}:undefined},i))})});}addPropertyControls(Snowfall,{snowColor:{type:ControlType.Color,title:\"Snow Color\",defaultValue:\"#FFF\"},snowflakeCount:{type:ControlType.Number,title:\"Flake Count\",min:10,max:200,defaultValue:60,step:1},snowflakeMinSize:{type:ControlType.Number,title:\"Min Size\",min:1,max:10,defaultValue:2,step:1},snowflakeMaxSize:{type:ControlType.Number,title:\"Max Size\",min:2,max:24,defaultValue:4,step:1},backgroundColor:{type:ControlType.Color,title:\"Background\",defaultValue:\"#001b30\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"Snowfall\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./Snowfall.map"],"mappings":"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"}