react-snow-overlay
Version:
A performant snowfall effect for your website using canvas and web workers
3 lines (2 loc) • 5.6 kB
JavaScript
(function(n,s){typeof exports=="object"&&typeof module<"u"?s(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],s):(n=typeof globalThis<"u"?globalThis:n||self,s(n["react-snow-overlay"]={},n.jsxRuntime,n.React))})(this,function(n,s,r){"use strict";"use client";var I=n=>{throw TypeError(n)};var S=(n,s,r)=>s.has(n)||I("Cannot "+r);var A=(n,s,r)=>(S(n,s,"read from private field"),r?r.call(n):s.get(n)),R=(n,s,r)=>s.has(n)?I("Cannot add the same private member more than once"):s instanceof WeakSet?s.add(n):s.set(n,r),b=(n,s,r,w)=>(S(n,s,"write to private field"),w?w.call(n,r):s.set(n,r),r),h=(n,s,r)=>(S(n,s,"access private method"),r);var d,a,m;const w=Object.freeze({color:"rgba(255, 255, 255, 0.8)",maxParticles:50,speed:"DEFAULT"}),L={DEFAULT:33,FAST:20,FASTER:10},_=2**31-1,g=50,U=`(function(){"use strict";const g=Object.freeze({color:"rgba(255, 255, 255, 0.8)",maxParticles:50,speed:"DEFAULT"}),u={DEFAULT:33,FAST:20,FASTER:10},x=t=>t.type===0,w=t=>t.type===1,P=t=>t.type===2,A=t=>t.type===3,F=t=>t.type===4,O=t=>typeof t=="object"?t.msBetweenUpdates:u[t];let r={...g},o,d=0,y=-1/0,l=null,c,i,h=!1;self.onmessage=t=>{const{data:a}=t;if(x(a))c=a.canvas,i=c.getContext("2d"),c.width=a.width,c.height=a.height,r={...g,...a.options},o=Array.from({length:r.maxParticles},M);else if(w(a))c.width=a.width,c.height=a.height;else if(A(a)){const{type:m,...s}=a;r={...r,...s.options},T(r.maxParticles)}else if(P(a)){h=!0;const{width:m,height:s}=i.canvas;i.clearRect(0,0,m,s),l&&cancelAnimationFrame(l);return}else F(a)&&(h=!1);const p=()=>{const m=O(r.speed);if(performance.now()-y<m){l=requestAnimationFrame(p);return}const{width:s,height:f}=i.canvas;i.clearRect(0,0,s,f),i.fillStyle=r.color,i.beginPath();for(let n=0;n<r.maxParticles;n++){const e=o[n];i.moveTo(e.x,e.y),i.arc(e.x,e.y,e.r,0,Math.PI*2,!0)}i.fill(),d=(d+.01)%360;for(let n=0;n<r.maxParticles;n++){const e=o[n];if(e.y+=Math.cos(d+e.d)+1+e.r/2,e.x+=Math.sin(d)*2,e.x>s+5||e.x<-5||e.y>f)if(n%3>0)o[n]={x:Math.random()*s,y:-10,r:e.r,d:e.d};else{const S=Math.random()*s;Math.sin(d)>0?o[n]={x:-5-S,y:Math.random()*f,r:e.r,d:e.d}:o[n]={x:s+5+S,y:Math.random()*f,r:e.r,d:e.d}}}y=performance.now(),h||(l=requestAnimationFrame(p))};l&&cancelAnimationFrame(l),h||requestAnimationFrame(p)};const T=t=>{const a=o.length;if(t!==a){if(t<a)return o.splice(t,a-t);o.push(...Array.from({length:t-a},M))}},M=()=>({x:Math.random()*c.width,y:Math.random()*-c.height,r:Math.random()*4+1,d:Math.random()*r.maxParticles})})();
`,v=typeof self<"u"&&self.Blob&&new Blob([U],{type:"text/javascript;charset=utf-8"});function F(e){let t;try{if(t=v&&(self.URL||self.webkitURL).createObjectURL(v),!t)throw"";const i=new Worker(t,{name:e==null?void 0:e.name});return i.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),i}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(U),{name:e==null?void 0:e.name})}finally{t&&(self.URL||self.webkitURL).revokeObjectURL(t)}}var f=(e=>(e[e.INIT=0]="INIT",e[e.UPDATE_SIZE=1]="UPDATE_SIZE",e[e.STOP=2]="STOP",e[e.UPDATE_OPTIONS=3]="UPDATE_OPTIONS",e[e.RESUME=4]="RESUME",e))(f||{});class M{constructor(t){R(this,a);R(this,d);b(this,d,t)}init(t){h(this,a,m).call(this,{...t,type:f.INIT},[t.canvas])}updateSize(t){h(this,a,m).call(this,{...t,type:f.UPDATE_SIZE})}stop(){h(this,a,m).call(this,{type:f.STOP})}resume(){h(this,a,m).call(this,{type:f.RESUME})}updateOptions(t){h(this,a,m).call(this,{...t,type:f.UPDATE_OPTIONS})}terminate(){A(this,d).terminate()}}d=new WeakMap,a=new WeakSet,m=function(t,i){A(this,d).postMessage(t,{transfer:i})};const N=(e,t)=>{const i=r.useRef(null),l=r.useCallback((...u)=>{i.current!==null&&clearTimeout(i.current),i.current=window.setTimeout(()=>{e(...u)},t)},[e,t]);return r.useEffect(()=>()=>void(i.current!==null&&clearTimeout(i.current))),l},j=(e,t)=>{const i=r.useRef(null);return(!i.current||!x(t,i.current.key))&&(i.current={key:t,value:e()}),i.current.value},x=(e,t)=>{if(e===t)return!0;if(e===null||t===null||typeof e!="object"||typeof t!="object")return!1;const i=Object.keys(e),l=Object.keys(t);return!(i.length!==l.length||i.some(u=>!l.includes(u)||!x(e[u],t[u])))},C=r.memo(function({zIndex:t=_,disabled:i,disabledOnSingleCpuDevices:l,...u}){const y=r.useRef(null),p=r.useRef(null),c=r.useRef(null),[D,k]=r.useReducer(()=>!0,!1),T=j(()=>u,[u]),O=N(()=>{var o;if(!(typeof window>"u"||!((o=y.current)!=null&&o.transferControlToOffscreen))){if(p.current??(p.current=y.current.transferControlToOffscreen()),!c.current){c.current=new M(new F),k();const P=p.current;return c.current.init({canvas:P,width:window.innerWidth,height:window.innerHeight,options:T})}c.current.updateSize({width:window.innerWidth,height:window.innerHeight})}},g);r.useEffect(()=>(O(),window.addEventListener("resize",O),()=>window.removeEventListener("resize",O)),[O]);const E=r.useMemo(()=>{const o=!!i,P=l&&typeof navigator<"u"&&navigator.hardwareConcurrency===1;return o||P},[l,i]);return r.useEffect(()=>{if(!(!D||!p.current||!c.current)){if(E)return c.current.stop();c.current.updateOptions({options:T})}},[E,T,D]),r.useEffect(()=>{var o;(o=c.current)==null||o[E?"stop":"resume"]()},[E]),r.useEffect(()=>{var o;return(o=c.current)==null?void 0:o.terminate},[]),s.jsx("canvas",{"aria-hidden":"true",ref:y,style:{zIndex:t,pointerEvents:"none",userSelect:"none",position:"fixed",top:0,right:0,bottom:0,left:0,...E&&{display:"none"}}})});n.DEFAULT_SNOW_OPTIONS=w,n.SNOW_OPTIONS_SPEED_MAP=L,n.SnowOverlay=C,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})});