@persian-caesar/liquid-glass 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{useCallback as b,useEffect as T,useId as rt,useRef as d,useState as U}from"react";import{Fragment as it,jsx as l,jsxs as _}from"react/jsx-runtime";var at=({borderRadius:k=20,blur:A=.25,contrast:O=1.2,brightness:z=1.05,saturation:W=1.1,shadowIntensity:S=.25,displacementScale:w=1,elasticity:R=.6,className:B="",style:J={},children:K,as:Q="div",filterId:X})=>{let y=d(null),Y=d(null),v=d(null),G=d(null),$=d(null),Z=rt(),f=X||`liquid-glass-${Z.replace(/:/g,"-")}`,[u,j]=U(300),[h,tt]=U(200),m=1,x=b((t,n,s)=>(s=Math.max(0,Math.min(1,(s-t)/(n-t))),s*s*(3-2*s)),[]),q=b((t,n)=>Math.sqrt(t*t+n*n),[]),E=b((t,n,s,i,e)=>{let r=Math.abs(t)-s+e,o=Math.abs(n)-i+e;return Math.min(Math.max(r,o),0)+q(Math.max(r,0),Math.max(o,0))-e},[q]),I=b(()=>{let t=v.current,n=G.current,s=$.current;if(!t||!n||!s)return;let i=t.getContext("2d");if(!i)return;let e=Math.max(1,Math.floor(u*m)),r=Math.max(1,Math.floor(h*m));if(e<=0||r<=0)return;(t.width!==e||t.height!==r)&&(t.width=e,t.height=r);let o=new Uint8ClampedArray(e*r*4),c=0,M=[];for(let a=0;a<o.length;a+=4){let p=a/4%e,g=Math.floor(a/4/e),D={x:p/e,y:g/r},L=D.x-.5,F=D.y-.5,nt=E(L,F,.3,.2,R),st=x(.8,0,nt-.15),P=x(0,1,st),V={x:L*P+.5,y:F*P+.5},H=V.x*e-p,N=V.y*r-g;c=Math.max(c,Math.abs(H),Math.abs(N)),M.push(H,N)}c*=.5*w;let C=0;for(let a=0;a<o.length;a+=4){let p=M[C++]/c+.5,g=M[C++]/c+.5;o[a]=p*255,o[a+1]=g*255,o[a+2]=0,o[a+3]=255}i.putImageData(new ImageData(o,e,r),0,0),n.setAttributeNS("http://www.w3.org/1999/xlink","href",t.toDataURL()),s.setAttribute("scale",(c/m).toString())},[u,h,w,R,E,x]);T(()=>{let t=y.current;if(!t)return;let n=new ResizeObserver(s=>{for(let i of s){let{width:e,height:r}=i.contentRect;j(Math.max(e,100)),tt(Math.max(r,100))}});return n.observe(t),()=>n.disconnect()},[]),T(()=>{I()},[I]);let et={borderRadius:`${k}px`,backdropFilter:`url(#${f}_filter) blur(${A}px) contrast(${O}) brightness(${z}) saturate(${W})`,boxShadow:S>0?`0 4px 8px rgba(0, 0, 0, ${S}), 0 -10px 25px inset rgba(0, 0, 0, 0.15)`:void 0};return _(it,{children:[l("svg",{ref:Y,xmlns:"http://www.w3.org/2000/svg",width:"0",height:"0",style:{position:"fixed",top:0,left:0,pointerEvents:"none"},children:l("defs",{children:_("filter",{id:`${f}_filter`,filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",x:"0",y:"0",width:u.toString(),height:h.toString(),children:[l("feImage",{ref:G,id:`${f}_map`,width:u.toString(),height:h.toString()}),l("feDisplacementMap",{ref:$,in:"SourceGraphic",in2:`${f}_map`,xChannelSelector:"R",yChannelSelector:"G"})]})})}),l("canvas",{ref:v,width:u*m,height:h*m,style:{display:"none"}}),l(Q,{ref:y,className:`liquid-glass ${B}`,style:{...et,...J},children:K})]})},ot=at;export{ot as LiquidGlass};
1
+ import{useCallback as b,useEffect as _,useId as rt,useRef as d,useState as k}from"react";import{Fragment as it,jsx as l,jsxs as A}from"react/jsx-runtime";var at=({borderRadius:S=void 0,blur:O=.25,contrast:z=1.2,brightness:W=1.05,saturation:B=1.1,shadowIntensity:w=.25,displacementScale:y=1,elasticity:R=.6,className:J="",style:K={},children:Q,as:X="div",filterId:Y})=>{let v=d(null),Z=d(null),G=d(null),$=d(null),q=d(null),j=rt(),f=Y||`liquid-glass-${j.replace(/:/g,"-")}`,[u,tt]=k(300),[h,et]=k(200),m=1,x=b((t,n,s)=>(s=Math.max(0,Math.min(1,(s-t)/(n-t))),s*s*(3-2*s)),[]),E=b((t,n)=>Math.sqrt(t*t+n*n),[]),I=b((t,n,s,i,e)=>{let r=Math.abs(t)-s+e,o=Math.abs(n)-i+e;return Math.min(Math.max(r,o),0)+E(Math.max(r,0),Math.max(o,0))-e},[E]),C=b(()=>{let t=G.current,n=$.current,s=q.current;if(!t||!n||!s)return;let i=t.getContext("2d");if(!i)return;let e=Math.max(1,Math.floor(u*m)),r=Math.max(1,Math.floor(h*m));if(e<=0||r<=0)return;(t.width!==e||t.height!==r)&&(t.width=e,t.height=r);let o=new Uint8ClampedArray(e*r*4),c=0,M=[];for(let a=0;a<o.length;a+=4){let p=a/4%e,g=Math.floor(a/4/e),F={x:p/e,y:g/r},P=F.x-.5,V=F.y-.5,nt=I(P,V,.3,.2,R),st=x(.8,0,nt-.15),H=x(0,1,st),N={x:P*H+.5,y:V*H+.5},T=N.x*e-p,U=N.y*r-g;c=Math.max(c,Math.abs(T),Math.abs(U)),M.push(T,U)}c*=.5*y;let L=0;for(let a=0;a<o.length;a+=4){let p=M[L++]/c+.5,g=M[L++]/c+.5;o[a]=p*255,o[a+1]=g*255,o[a+2]=0,o[a+3]=255}i.putImageData(new ImageData(o,e,r),0,0),n.setAttributeNS("http://www.w3.org/1999/xlink","href",t.toDataURL()),s.setAttribute("scale",(c/m).toString())},[u,h,y,R,I,x]);_(()=>{let t=v.current;if(!t)return;let n=new ResizeObserver(s=>{for(let i of s){let{width:e,height:r}=i.contentRect;tt(Math.max(e,100)),et(Math.max(r,100))}});return n.observe(t),()=>n.disconnect()},[]),_(()=>{C()},[C]);let D={backdropFilter:`url(#${f}_filter) blur(${O}px) contrast(${z}) brightness(${W}) saturate(${B})`,boxShadow:w>0?`0 4px 8px rgba(0, 0, 0, ${w}), 0 -10px 25px inset rgba(0, 0, 0, 0.15)`:void 0};return S&&(D.borderRadius=`${S}px`),A(it,{children:[l("svg",{ref:Z,xmlns:"http://www.w3.org/2000/svg",width:"0",height:"0",style:{position:"fixed",top:0,left:0,pointerEvents:"none"},children:l("defs",{children:A("filter",{id:`${f}_filter`,filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB",x:"0",y:"0",width:u.toString(),height:h.toString(),children:[l("feImage",{ref:$,id:`${f}_map`,width:u.toString(),height:h.toString()}),l("feDisplacementMap",{ref:q,in:"SourceGraphic",in2:`${f}_map`,xChannelSelector:"R",yChannelSelector:"G"})]})})}),l("canvas",{ref:G,width:u*m,height:h*m,style:{display:"none"}}),l(X,{ref:v,className:`liquid-glass ${J}`,style:{...D,...K},children:Q})]})},ot=at;export{ot as LiquidGlass};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/LiquidGlass.tsx"],"sourcesContent":["import type React from \"react\";\nimport { useCallback, useEffect, useId, useRef, useState } from \"react\";\n\nexport interface LiquidGlassProps {\n // Core effect options\n borderRadius?: number;\n blur?: number;\n contrast?: number;\n brightness?: number;\n saturation?: number;\n shadowIntensity?: number;\n displacementScale?: number;\n elasticity?: number;\n\n // Customization\n className?: string;\n style?: React.CSSProperties; \n children?: React.ReactNode;\n\n // Advanced\n as?: React.ElementType; \n filterId?: string; \n}\n\nconst LiquidGlass: React.FC<LiquidGlassProps> = ({\n borderRadius = 20,\n blur = 0.25,\n contrast = 1.2,\n brightness = 1.05,\n saturation = 1.1,\n shadowIntensity = 0.25,\n displacementScale = 1,\n elasticity = 0.6,\n\n className = \"\",\n style = {},\n children,\n as: Component = \"div\",\n filterId,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const svgRef = useRef<SVGSVGElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const feImageRef = useRef<SVGFEImageElement>(null);\n const feDisplacementMapRef = useRef<SVGFEDisplacementMapElement>(null);\n\n const reactId = useId();\n const id = filterId || `liquid-glass-${reactId.replace(/:/g, \"-\")}`;\n\n const [width, setWidth] = useState(300);\n const [height, setHeight] = useState(200);\n const canvasDPI = 1;\n\n // Utility functions (همان قبلی‌ها)\n const smoothStep = useCallback((a: number, b: number, t: number) => {\n t = Math.max(0, Math.min(1, (t - a) / (b - a)));\n return t * t * (3 - 2 * t);\n }, []);\n\n const length = useCallback((x: number, y: number) => Math.sqrt(x * x + y * y), []);\n\n const roundedRectSDF = useCallback(\n (x: number, y: number, w: number, h: number, radius: number) => {\n const qx = Math.abs(x) - w + radius;\n const qy = Math.abs(y) - h + radius;\n return (\n Math.min(Math.max(qx, qy), 0) +\n length(Math.max(qx, 0), Math.max(qy, 0)) -\n radius\n );\n },\n [length]\n );\n\n const updateShader = useCallback(() => {\n // ... (کد updateShader قبلی بدون تغییر نگه داشته میشه)\n const canvas = canvasRef.current;\n const feImage = feImageRef.current;\n const feDisplacementMap = feDisplacementMapRef.current;\n if (!canvas || !feImage || !feDisplacementMap) return;\n\n const context = canvas.getContext(\"2d\");\n if (!context) return;\n\n const w = Math.max(1, Math.floor(width * canvasDPI));\n const h = Math.max(1, Math.floor(height * canvasDPI));\n\n if (w <= 0 || h <= 0) return;\n if (canvas.width !== w || canvas.height !== h) {\n canvas.width = w;\n canvas.height = h;\n }\n\n const data = new Uint8ClampedArray(w * h * 4);\n let maxScale = 0;\n const rawValues: number[] = [];\n\n for (let i = 0; i < data.length; i += 4) {\n const x = (i / 4) % w;\n const y = Math.floor(i / 4 / w);\n const uv = { x: x / w, y: y / h };\n\n const ix = uv.x - 0.5;\n const iy = uv.y - 0.5;\n const distanceToEdge = roundedRectSDF(ix, iy, 0.3, 0.2, elasticity);\n const displacement = smoothStep(0.8, 0, distanceToEdge - 0.15);\n const scaled = smoothStep(0, 1, displacement);\n\n const pos = {\n x: ix * scaled + 0.5,\n y: iy * scaled + 0.5,\n };\n\n const dx = pos.x * w - x;\n const dy = pos.y * h - y;\n\n maxScale = Math.max(maxScale, Math.abs(dx), Math.abs(dy));\n rawValues.push(dx, dy);\n }\n\n maxScale *= 0.5 * displacementScale;\n\n let index = 0;\n for (let i = 0; i < data.length; i += 4) {\n const r = rawValues[index++] / maxScale + 0.5;\n const g = rawValues[index++] / maxScale + 0.5;\n data[i] = r * 255;\n data[i + 1] = g * 255;\n data[i + 2] = 0;\n data[i + 3] = 255;\n }\n\n context.putImageData(new ImageData(data, w, h), 0, 0);\n feImage.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"href\", canvas.toDataURL());\n feDisplacementMap.setAttribute(\"scale\", (maxScale / canvasDPI).toString());\n }, [width, height, displacementScale, elasticity, roundedRectSDF, smoothStep]);\n\n // Resize Observer\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width: newWidth, height: newHeight } = entry.contentRect;\n setWidth(Math.max(newWidth, 100));\n setHeight(Math.max(newHeight, 100));\n }\n });\n\n resizeObserver.observe(container);\n return () => resizeObserver.disconnect();\n }, []);\n\n // Update shader when needed\n useEffect(() => {\n updateShader();\n }, [updateShader]);\n\n const filterStyle: React.CSSProperties = {\n borderRadius: `${borderRadius}px`,\n backdropFilter: `url(#${id}_filter) blur(${blur}px) contrast(${contrast}) brightness(${brightness}) saturate(${saturation})`,\n boxShadow: shadowIntensity > 0\n ? `0 4px 8px rgba(0, 0, 0, ${shadowIntensity}), 0 -10px 25px inset rgba(0, 0, 0, 0.15)`\n : undefined,\n };\n\n return (\n <>\n {/* SVG Filter - Hidden */}\n <svg\n ref={svgRef}\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"0\"\n height=\"0\"\n style={{ position: \"fixed\", top: 0, left: 0, pointerEvents: \"none\" }}\n >\n <defs>\n <filter\n id={`${id}_filter`}\n filterUnits=\"userSpaceOnUse\"\n colorInterpolationFilters=\"sRGB\"\n x=\"0\"\n y=\"0\"\n width={width.toString()}\n height={height.toString()}\n >\n <feImage ref={feImageRef} id={`${id}_map`} width={width.toString()} height={height.toString()} />\n <feDisplacementMap\n ref={feDisplacementMapRef}\n in=\"SourceGraphic\"\n in2={`${id}_map`}\n xChannelSelector=\"R\"\n yChannelSelector=\"G\"\n />\n </filter>\n </defs>\n </svg>\n\n {/* Hidden Canvas */}\n <canvas\n ref={canvasRef}\n width={width * canvasDPI}\n height={height * canvasDPI}\n style={{ display: \"none\" }}\n />\n\n {/* Main Glass Container - Fully Customizable */}\n <Component\n ref={containerRef}\n className={`liquid-glass ${className}`}\n style={{\n ...filterStyle,\n ...style, \n }}\n >\n {children}\n </Component>\n </>\n );\n};\n\nexport default LiquidGlass;"],"mappings":"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","names":["useCallback","useEffect","useId","useRef","useState","Fragment","jsx","jsxs","LiquidGlass","borderRadius","blur","contrast","brightness","saturation","shadowIntensity","displacementScale","elasticity","className","style","children","Component","filterId","containerRef","svgRef","canvasRef","feImageRef","feDisplacementMapRef","reactId","id","width","setWidth","height","setHeight","canvasDPI","smoothStep","a","b","t","length","x","y","roundedRectSDF","w","h","radius","qx","qy","updateShader","canvas","feImage","feDisplacementMap","context","data","maxScale","rawValues","i","uv","ix","iy","distanceToEdge","displacement","scaled","pos","dx","dy","index","r","container","resizeObserver","entries","entry","newWidth","newHeight","filterStyle","LiquidGlass_default"]}
1
+ {"version":3,"sources":["../src/components/LiquidGlass.tsx"],"sourcesContent":["import type React from \"react\";\nimport { useCallback, useEffect, useId, useRef, useState } from \"react\";\n\nexport interface LiquidGlassProps {\n // Core effect options\n borderRadius?: number;\n blur?: number;\n contrast?: number;\n brightness?: number;\n saturation?: number;\n shadowIntensity?: number;\n displacementScale?: number;\n elasticity?: number;\n\n // Customization\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n\n // Advanced\n as?: React.ElementType;\n filterId?: string;\n}\n\nconst LiquidGlass: React.FC<LiquidGlassProps> = ({\n borderRadius = undefined,\n blur = 0.25,\n contrast = 1.2,\n brightness = 1.05,\n saturation = 1.1,\n shadowIntensity = 0.25,\n displacementScale = 1,\n elasticity = 0.6,\n\n className = \"\",\n style = {},\n children,\n as: Component = \"div\",\n filterId,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const svgRef = useRef<SVGSVGElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const feImageRef = useRef<SVGFEImageElement>(null);\n const feDisplacementMapRef = useRef<SVGFEDisplacementMapElement>(null);\n\n const reactId = useId();\n const id = filterId || `liquid-glass-${reactId.replace(/:/g, \"-\")}`;\n\n const [width, setWidth] = useState(300);\n const [height, setHeight] = useState(200);\n const canvasDPI = 1;\n\n // Utility functions (همان قبلی‌ها)\n const smoothStep = useCallback((a: number, b: number, t: number) => {\n t = Math.max(0, Math.min(1, (t - a) / (b - a)));\n return t * t * (3 - 2 * t);\n }, []);\n\n const length = useCallback((x: number, y: number) => Math.sqrt(x * x + y * y), []);\n\n const roundedRectSDF = useCallback(\n (x: number, y: number, w: number, h: number, radius: number) => {\n const qx = Math.abs(x) - w + radius;\n const qy = Math.abs(y) - h + radius;\n return (\n Math.min(Math.max(qx, qy), 0) +\n length(Math.max(qx, 0), Math.max(qy, 0)) -\n radius\n );\n },\n [length]\n );\n\n const updateShader = useCallback(() => {\n // ... (کد updateShader قبلی بدون تغییر نگه داشته میشه)\n const canvas = canvasRef.current;\n const feImage = feImageRef.current;\n const feDisplacementMap = feDisplacementMapRef.current;\n if (!canvas || !feImage || !feDisplacementMap) return;\n\n const context = canvas.getContext(\"2d\");\n if (!context) return;\n\n const w = Math.max(1, Math.floor(width * canvasDPI));\n const h = Math.max(1, Math.floor(height * canvasDPI));\n\n if (w <= 0 || h <= 0) return;\n if (canvas.width !== w || canvas.height !== h) {\n canvas.width = w;\n canvas.height = h;\n }\n\n const data = new Uint8ClampedArray(w * h * 4);\n let maxScale = 0;\n const rawValues: number[] = [];\n\n for (let i = 0; i < data.length; i += 4) {\n const x = (i / 4) % w;\n const y = Math.floor(i / 4 / w);\n const uv = { x: x / w, y: y / h };\n\n const ix = uv.x - 0.5;\n const iy = uv.y - 0.5;\n const distanceToEdge = roundedRectSDF(ix, iy, 0.3, 0.2, elasticity);\n const displacement = smoothStep(0.8, 0, distanceToEdge - 0.15);\n const scaled = smoothStep(0, 1, displacement);\n\n const pos = {\n x: ix * scaled + 0.5,\n y: iy * scaled + 0.5,\n };\n\n const dx = pos.x * w - x;\n const dy = pos.y * h - y;\n\n maxScale = Math.max(maxScale, Math.abs(dx), Math.abs(dy));\n rawValues.push(dx, dy);\n }\n\n maxScale *= 0.5 * displacementScale;\n\n let index = 0;\n for (let i = 0; i < data.length; i += 4) {\n const r = rawValues[index++] / maxScale + 0.5;\n const g = rawValues[index++] / maxScale + 0.5;\n data[i] = r * 255;\n data[i + 1] = g * 255;\n data[i + 2] = 0;\n data[i + 3] = 255;\n }\n\n context.putImageData(new ImageData(data, w, h), 0, 0);\n feImage.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"href\", canvas.toDataURL());\n feDisplacementMap.setAttribute(\"scale\", (maxScale / canvasDPI).toString());\n }, [width, height, displacementScale, elasticity, roundedRectSDF, smoothStep]);\n\n // Resize Observer\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width: newWidth, height: newHeight } = entry.contentRect;\n setWidth(Math.max(newWidth, 100));\n setHeight(Math.max(newHeight, 100));\n }\n });\n\n resizeObserver.observe(container);\n return () => resizeObserver.disconnect();\n }, []);\n\n // Update shader when needed\n useEffect(() => {\n updateShader();\n }, [updateShader]);\n\n const filterStyle: React.CSSProperties = {\n backdropFilter: `url(#${id}_filter) blur(${blur}px) contrast(${contrast}) brightness(${brightness}) saturate(${saturation})`,\n boxShadow: shadowIntensity > 0\n ? `0 4px 8px rgba(0, 0, 0, ${shadowIntensity}), 0 -10px 25px inset rgba(0, 0, 0, 0.15)`\n : undefined,\n };\n\n if (borderRadius) {\n filterStyle.borderRadius = `${borderRadius}px`;\n }\n\n return (\n <>\n {/* SVG Filter - Hidden */}\n <svg\n ref={svgRef}\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"0\"\n height=\"0\"\n style={{ position: \"fixed\", top: 0, left: 0, pointerEvents: \"none\" }}\n >\n <defs>\n <filter\n id={`${id}_filter`}\n filterUnits=\"userSpaceOnUse\"\n colorInterpolationFilters=\"sRGB\"\n x=\"0\"\n y=\"0\"\n width={width.toString()}\n height={height.toString()}\n >\n <feImage ref={feImageRef} id={`${id}_map`} width={width.toString()} height={height.toString()} />\n <feDisplacementMap\n ref={feDisplacementMapRef}\n in=\"SourceGraphic\"\n in2={`${id}_map`}\n xChannelSelector=\"R\"\n yChannelSelector=\"G\"\n />\n </filter>\n </defs>\n </svg>\n\n {/* Hidden Canvas */}\n <canvas\n ref={canvasRef}\n width={width * canvasDPI}\n height={height * canvasDPI}\n style={{ display: \"none\" }}\n />\n\n {/* Main Glass Container - Fully Customizable */}\n <Component\n ref={containerRef}\n className={`liquid-glass ${className}`}\n style={{\n ...filterStyle,\n ...style,\n }}\n >\n {children}\n </Component>\n </>\n );\n};\n\nexport default LiquidGlass;"],"mappings":"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","names":["useCallback","useEffect","useId","useRef","useState","Fragment","jsx","jsxs","LiquidGlass","borderRadius","blur","contrast","brightness","saturation","shadowIntensity","displacementScale","elasticity","className","style","children","Component","filterId","containerRef","svgRef","canvasRef","feImageRef","feDisplacementMapRef","reactId","id","width","setWidth","height","setHeight","canvasDPI","smoothStep","a","b","t","length","x","y","roundedRectSDF","w","h","radius","qx","qy","updateShader","canvas","feImage","feDisplacementMap","context","data","maxScale","rawValues","i","uv","ix","iy","distanceToEdge","displacement","scaled","pos","dx","dy","index","r","container","resizeObserver","entries","entry","newWidth","newHeight","filterStyle","LiquidGlass_default"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@persian-caesar/liquid-glass",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Liquid Glass effect component for React - Beautiful glassmorphism with displacement distortion.",
5
5
  "author": "Sobhan-SRZA (mr.sinre) & Persian Caesar",
6
6
  "license": "MIT",