@marcosdemik/liquidglass 1.0.10 → 1.0.12

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.cjs CHANGED
@@ -196,23 +196,29 @@ var LiquidGlassButton = (0, import_react.forwardRef)(
196
196
  const displacerB = (0, import_react.useRef)(null);
197
197
  const filterId = "lg" + (0, import_react.useId)().replace(/:/g, "");
198
198
  const [maps, setMaps] = (0, import_react.useState)(null);
199
- const [painted, setPainted] = (0, import_react.useState)(false);
199
+ const [ready, setReady] = (0, import_react.useState)(false);
200
200
  (0, import_react.useEffect)(() => {
201
- setMaps(generateGlassMaps({ width, height, radius, edgeSize, intensity, distortion }));
202
- setPainted(false);
201
+ let cancelled = false;
202
+ const m = generateGlassMaps({ width, height, radius, edgeSize, intensity, distortion });
203
+ const img = new Image();
204
+ img.onload = () => {
205
+ if (cancelled) return;
206
+ setMaps(m);
207
+ };
208
+ img.src = m.displacement;
209
+ return () => {
210
+ cancelled = true;
211
+ };
203
212
  }, [width, height, radius, edgeSize, intensity, distortion]);
204
213
  (0, import_react.useEffect)(() => {
205
214
  if (!maps) return;
206
215
  let cancelled = false;
207
- requestAnimationFrame(() => {
208
- requestAnimationFrame(() => {
209
- requestAnimationFrame(() => {
210
- if (!cancelled) setPainted(true);
211
- });
212
- });
213
- });
216
+ const timer = setTimeout(() => {
217
+ if (!cancelled) setReady(true);
218
+ }, 150);
214
219
  return () => {
215
220
  cancelled = true;
221
+ clearTimeout(timer);
216
222
  };
217
223
  }, [maps]);
218
224
  (0, import_react.useEffect)(() => {
@@ -285,9 +291,8 @@ var LiquidGlassButton = (0, import_react.forwardRef)(
285
291
  border: "none",
286
292
  background: glassColor
287
293
  }, style), {
288
- // OUR control - AFTER user style so it can't be overridden
289
- opacity: painted ? 1 : 0,
290
- pointerEvents: painted ? void 0 : "none"
294
+ opacity: ready ? 1 : 0,
295
+ pointerEvents: ready ? void 0 : "none"
291
296
  })
292
297
  }, props), {
293
298
  children: [
@@ -298,7 +303,9 @@ var LiquidGlassButton = (0, import_react.forwardRef)(
298
303
  style: {
299
304
  borderRadius: "inherit",
300
305
  backdropFilter: `url(#${filterId})`,
301
- WebkitBackdropFilter: `url(#${filterId})`
306
+ WebkitBackdropFilter: `url(#${filterId})`,
307
+ willChange: "backdrop-filter",
308
+ transform: "translateZ(0)"
302
309
  }
303
310
  }
304
311
  ),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/liquid-glass-button.tsx","../src/utils.ts","../src/generate-displacement-map.ts"],"sourcesContent":["export { LiquidGlassButton } from \"./liquid-glass-button\";\nexport type { LiquidGlassButtonProps } from \"./liquid-glass-button\";\nexport { generateGlassMaps } from \"./generate-displacement-map\";\nexport type { MapOptions } from \"./generate-displacement-map\";\nexport { cn } from \"./utils\";\n","import React, { useRef, useEffect, useState, useId, forwardRef } from \"react\";\nimport gsap from \"gsap\";\nimport { cn } from \"./utils\";\nimport { generateGlassMaps } from \"./generate-displacement-map\";\n\nconst CONFIG = {\n initial: { scale: 1, displacement: 35, blur: 2, chroma: 3 },\n hover: { scale: 1.05, displacement: 65, blur: 4, chroma: 10 },\n click: { scaleDown: 0.95, scaleUp: 1.05 },\n duration: { hover: 0.4, clickDown: 0.1, clickUp: 0.3 },\n ease: {\n hover: \"power3.out\",\n hoverOut: \"power2.out\",\n clickDown: \"power2.in\",\n clickUp: \"back.out(2)\",\n },\n} as const;\n\nconst PADDING_PCT = 50;\n\nexport interface LiquidGlassButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n width?: number;\n height?: number;\n radius?: number;\n edgeSize?: number;\n intensity?: number;\n smoothness?: number;\n distortion?: number;\n chroma?: number;\n glassColor?: string;\n}\n\nexport const LiquidGlassButton = forwardRef<HTMLButtonElement, LiquidGlassButtonProps>(\n function LiquidGlassButton({ children, className, width = 300, height = 56, radius = 60, edgeSize, intensity, smoothness = 1, distortion, chroma = 3, glassColor = \"rgba(255,255,255,0.05)\", style, ...props }, ref) {\n const internalRef = useRef<HTMLButtonElement>(null);\n const buttonRef = (ref as React.RefObject<HTMLButtonElement>) ?? internalRef;\n\n const blurRef = useRef<SVGFEGaussianBlurElement>(null);\n const displacerR = useRef<SVGFEDisplacementMapElement>(null);\n const displacerG = useRef<SVGFEDisplacementMapElement>(null);\n const displacerB = useRef<SVGFEDisplacementMapElement>(null);\n\n const filterId = \"lg\" + useId().replace(/:/g, \"\");\n\n // Phase 1: generate displacement maps (client only)\n const [maps, setMaps] = useState<ReturnType<typeof generateGlassMaps> | null>(null);\n // Phase 2: browser has painted the SVG filter - safe to show\n const [painted, setPainted] = useState(false);\n\n useEffect(() => {\n setMaps(generateGlassMaps({ width, height, radius, edgeSize, intensity, distortion }));\n setPainted(false);\n }, [width, height, radius, edgeSize, intensity, distortion]);\n\n // After maps are in the DOM, wait for the browser to actually composite the SVG filter\n useEffect(() => {\n if (!maps) return;\n let cancelled = false;\n // Triple rAF: ensures React committed DOM, browser laid out, AND painted the filter\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (!cancelled) setPainted(true);\n });\n });\n });\n return () => { cancelled = true; };\n }, [maps]);\n\n useEffect(() => {\n const button = buttonRef.current;\n if (!button || !blurRef.current) return;\n\n if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) return;\n\n const fx = {\n displacement: CONFIG.initial.displacement,\n blur: CONFIG.initial.blur,\n chroma: chroma\n };\n\n const sync = () => {\n displacerR.current?.setAttribute(\"scale\", (fx.displacement + fx.chroma).toString());\n displacerG.current?.setAttribute(\"scale\", fx.displacement.toString());\n displacerB.current?.setAttribute(\"scale\", (fx.displacement - fx.chroma).toString());\n blurRef.current?.setAttribute(\"stdDeviation\", fx.blur.toString());\n };\n\n sync();\n\n const onEnter = () => {\n gsap.killTweensOf([fx, button]);\n gsap.to(fx, {\n displacement: CONFIG.hover.displacement,\n blur: CONFIG.hover.blur,\n chroma: chroma * 2.5,\n duration: CONFIG.duration.hover,\n ease: CONFIG.ease.hover,\n onUpdate: sync\n });\n gsap.to(button, { scale: CONFIG.hover.scale, duration: CONFIG.duration.hover, ease: CONFIG.ease.hover });\n };\n\n const onLeave = () => {\n gsap.killTweensOf([fx, button]);\n gsap.to(fx, {\n displacement: CONFIG.initial.displacement,\n blur: CONFIG.initial.blur,\n chroma: chroma,\n duration: CONFIG.duration.hover,\n ease: CONFIG.ease.hoverOut,\n onUpdate: sync\n });\n gsap.to(button, { scale: CONFIG.initial.scale, duration: CONFIG.duration.hover, ease: CONFIG.ease.hoverOut });\n };\n\n const onClick = () => {\n gsap.killTweensOf(button);\n const cur = gsap.getProperty(button, \"scale\") as number;\n gsap.timeline()\n .to(button, { scale: cur * CONFIG.click.scaleDown, duration: CONFIG.duration.clickDown, ease: CONFIG.ease.clickDown })\n .to(button, { scale: CONFIG.click.scaleUp, duration: CONFIG.duration.clickUp, ease: CONFIG.ease.clickUp });\n };\n\n button.addEventListener(\"pointerenter\", onEnter);\n button.addEventListener(\"pointerleave\", onLeave);\n button.addEventListener(\"click\", onClick);\n\n return () => {\n button.removeEventListener(\"pointerenter\", onEnter);\n button.removeEventListener(\"pointerleave\", onLeave);\n button.removeEventListener(\"click\", onClick);\n gsap.killTweensOf([button, fx]);\n };\n }, [buttonRef, maps, chroma]);\n\n // Server: maps=null → null. Client before maps: null. No hydration mismatch.\n if (!maps) return null;\n\n return (\n <>\n <button\n ref={buttonRef}\n className={cn(\"relative overflow-hidden shadow-2xl shadow-black/20 cursor-pointer\", className)}\n style={{\n width, height, borderRadius: radius, border: \"none\", background: glassColor,\n ...style,\n // OUR control - AFTER user style so it can't be overridden\n opacity: painted ? 1 : 0,\n pointerEvents: painted ? undefined : \"none\",\n }}\n {...props}\n >\n <div\n className=\"absolute inset-0 z-0\"\n style={{\n borderRadius: \"inherit\",\n backdropFilter: `url(#${filterId})`,\n WebkitBackdropFilter: `url(#${filterId})`\n }}\n />\n <div className=\"absolute inset-0 z-10 flex items-center justify-center font-bold text-white shadow-[inset_0_1px_1px_rgba(255,255,255,0.4)]\" style={{ background: \"linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.0) 100%)\", borderRadius: \"inherit\" }}>\n {children}\n </div>\n </button>\n\n <svg style={{ position: \"absolute\", width: 0, height: 0, pointerEvents: \"none\" }} aria-hidden=\"true\">\n <defs>\n <filter id={filterId} x={`-${PADDING_PCT}%`} y={`-${PADDING_PCT}%`} width={`${100 + PADDING_PCT * 2}%`} height={`${100 + PADDING_PCT * 2}%`} colorInterpolationFilters=\"sRGB\">\n <feGaussianBlur ref={blurRef} in=\"SourceGraphic\" stdDeviation={CONFIG.initial.blur} result=\"blurred_bg\" edgeMode=\"duplicate\" />\n\n <feImage href={maps.displacement} result=\"disp_map\" x={`${PADDING_PCT}%`} y={`${PADDING_PCT}%`} width={`${100}%`} height={`${100}%`} preserveAspectRatio=\"none\" />\n\n <feGaussianBlur in=\"disp_map\" stdDeviation={smoothness} result=\"disp_blurred\" edgeMode=\"duplicate\" />\n\n <feDisplacementMap ref={displacerR} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement + chroma} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_r\" />\n <feColorMatrix in=\"displaced_r\" type=\"matrix\" values=\"1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0\" result=\"red_channel\" />\n\n <feDisplacementMap ref={displacerG} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_g\" />\n <feColorMatrix in=\"displaced_g\" type=\"matrix\" values=\"0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0\" result=\"green_channel\" />\n\n <feDisplacementMap ref={displacerB} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement - chroma} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_b\" />\n <feColorMatrix in=\"displaced_b\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0\" result=\"blue_channel\" />\n\n <feBlend in=\"red_channel\" in2=\"green_channel\" mode=\"screen\" result=\"rg_channels\" />\n <feBlend in=\"rg_channels\" in2=\"blue_channel\" mode=\"screen\" result=\"rgb_channels\" />\n\n <feColorMatrix in=\"rgb_channels\" type=\"saturate\" values=\"1.2\" result=\"final\" />\n </filter>\n </defs>\n </svg>\n </>\n );\n }\n);\n","export function cn(...classes: (string | undefined | null | false)[]) {\n return classes.filter(Boolean).join(\" \");\n}\n","export interface MapOptions {\n width: number;\n height: number;\n radius?: number;\n edgeSize?: number;\n intensity?: number;\n distortion?: number;\n}\n\nconst VERT = `attribute vec4 position; void main(){ gl_Position = position; }`;\n\nconst FRAG = `\nprecision mediump float;\nuniform vec2 uRes;\nuniform float uRadius;\nuniform float uEdgeSize;\nuniform float uIntensity;\nuniform float uDistortion;\n\nfloat sdRoundedBox(vec2 p, vec2 b, float r){\n r = min(r, min(b.x, b.y));\n vec2 q = abs(p) - b + r;\n return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;\n}\n\nfloat getHeight(vec2 p) {\n vec2 halfSize = uRes * 0.5 - 2.0;\n\n // Aumenta o tamanho base do box ligeiramente proporcinal ao edge\n halfSize += uEdgeSize * 0.2;\n\n float d = sdRoundedBox(p, halfSize, uRadius);\n\n float borderSoftness = uEdgeSize * uIntensity;\n d = max(d, -borderSoftness);\n return smoothstep(0.0, -borderSoftness, d);\n}\n\nvoid main(){\n vec2 p = gl_FragCoord.xy - uRes * 0.5;\n p.y = -p.y;\n\n // --- Displacement Map ---\n const vec2 e = vec2(1.0, 0.0);\n float hx = getHeight(p + e.xy) - getHeight(p - e.xy);\n float hy = getHeight(p + e.yx) - getHeight(p - e.yx);\n\n vec2 normal = vec2(-hx, -hy) * uDistortion;\n vec2 color = clamp(normal * 0.5 + 0.5, 0.0, 1.0);\n\n gl_FragColor = vec4(color.x, color.y, 0.5, 1.0);\n}\n`;\n\nfunction compile(gl: WebGLRenderingContext, type: number, src: string) {\n const s = gl.createShader(type)!;\n gl.shaderSource(s, src);\n gl.compileShader(s);\n return s;\n}\n\nlet _cachedProgram: { gl: WebGLRenderingContext; program: WebGLProgram; canvas: HTMLCanvasElement } | null = null;\n\nfunction getGL() {\n if (_cachedProgram) return _cachedProgram;\n\n const canvas = document.createElement(\"canvas\");\n const gl = canvas.getContext(\"webgl\", { preserveDrawingBuffer: true, premultipliedAlpha: false })!;\n\n const vs = compile(gl, gl.VERTEX_SHADER, VERT);\n const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n gl.useProgram(program);\n\n const buf = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buf);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);\n const pos = gl.getAttribLocation(program, \"position\");\n gl.enableVertexAttribArray(pos);\n gl.vertexAttribPointer(pos, 2, gl.FLOAT, false, 0, 0);\n\n _cachedProgram = { gl, program, canvas };\n return _cachedProgram;\n}\n\nfunction render(width: number, height: number, radius: number, edgeSize: number, intensity: number, distortion: number): string {\n const { gl, program, canvas } = getGL();\n canvas.width = width;\n canvas.height = height;\n gl.viewport(0, 0, width, height);\n gl.clearColor(0.5, 0.5, 0.5, 1.0);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.useProgram(program);\n\n gl.uniform2f(gl.getUniformLocation(program, \"uRes\"), width, height);\n gl.uniform1f(gl.getUniformLocation(program, \"uRadius\"), radius);\n gl.uniform1f(gl.getUniformLocation(program, \"uEdgeSize\"), edgeSize);\n gl.uniform1f(gl.getUniformLocation(program, \"uIntensity\"), intensity);\n gl.uniform1f(gl.getUniformLocation(program, \"uDistortion\"), distortion);\n\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n return canvas.toDataURL(\"image/png\");\n}\n\nexport function generateGlassMaps(opts: MapOptions): { displacement: string } {\n const { width, height, radius = 60, edgeSize = 40, intensity = 1.0, distortion = 15.0 } = opts;\n const r = Math.min(radius, width / 2, height / 2);\n\n return {\n displacement: render(width, height, r, edgeSize, intensity, distortion),\n };\n}\n"],"mappings":"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","names":["LiquidGlassButton","_a","_b","gsap"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/liquid-glass-button.tsx","../src/utils.ts","../src/generate-displacement-map.ts"],"sourcesContent":["export { LiquidGlassButton } from \"./liquid-glass-button\";\nexport type { LiquidGlassButtonProps } from \"./liquid-glass-button\";\nexport { generateGlassMaps } from \"./generate-displacement-map\";\nexport type { MapOptions } from \"./generate-displacement-map\";\nexport { cn } from \"./utils\";\n","import React, { useRef, useEffect, useState, useId, forwardRef } from \"react\";\nimport gsap from \"gsap\";\nimport { cn } from \"./utils\";\nimport { generateGlassMaps } from \"./generate-displacement-map\";\n\nconst CONFIG = {\n initial: { scale: 1, displacement: 35, blur: 2, chroma: 3 },\n hover: { scale: 1.05, displacement: 65, blur: 4, chroma: 10 },\n click: { scaleDown: 0.95, scaleUp: 1.05 },\n duration: { hover: 0.4, clickDown: 0.1, clickUp: 0.3 },\n ease: {\n hover: \"power3.out\",\n hoverOut: \"power2.out\",\n clickDown: \"power2.in\",\n clickUp: \"back.out(2)\",\n },\n} as const;\n\nconst PADDING_PCT = 50;\n\nexport interface LiquidGlassButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n width?: number;\n height?: number;\n radius?: number;\n edgeSize?: number;\n intensity?: number;\n smoothness?: number;\n distortion?: number;\n chroma?: number;\n glassColor?: string;\n}\n\nexport const LiquidGlassButton = forwardRef<HTMLButtonElement, LiquidGlassButtonProps>(\n function LiquidGlassButton({ children, className, width = 300, height = 56, radius = 60, edgeSize, intensity, smoothness = 1, distortion, chroma = 3, glassColor = \"rgba(255,255,255,0.05)\", style, ...props }, ref) {\n const internalRef = useRef<HTMLButtonElement>(null);\n const buttonRef = (ref as React.RefObject<HTMLButtonElement>) ?? internalRef;\n\n const blurRef = useRef<SVGFEGaussianBlurElement>(null);\n const displacerR = useRef<SVGFEDisplacementMapElement>(null);\n const displacerG = useRef<SVGFEDisplacementMapElement>(null);\n const displacerB = useRef<SVGFEDisplacementMapElement>(null);\n\n const filterId = \"lg\" + useId().replace(/:/g, \"\");\n\n const [maps, setMaps] = useState<ReturnType<typeof generateGlassMaps> | null>(null);\n const [ready, setReady] = useState(false);\n\n // Phase 1: generate displacement maps + pre-decode the PNG data URL\n useEffect(() => {\n let cancelled = false;\n const m = generateGlassMaps({ width, height, radius, edgeSize, intensity, distortion });\n\n // Pre-decode the data URL PNG so the browser has it in cache\n // BEFORE the <feImage> references it\n const img = new Image();\n img.onload = () => {\n if (cancelled) return;\n setMaps(m);\n };\n img.src = m.displacement;\n\n return () => { cancelled = true; };\n }, [width, height, radius, edgeSize, intensity, distortion]);\n\n // Phase 2: after maps are in the DOM + feImage has the pre-decoded image,\n // wait for the browser to fully composite the SVG filter\n useEffect(() => {\n if (!maps) return;\n let cancelled = false;\n // 150ms timeout guarantees the browser has composited the filter\n const timer = setTimeout(() => {\n if (!cancelled) setReady(true);\n }, 150);\n return () => { cancelled = true; clearTimeout(timer); };\n }, [maps]);\n\n useEffect(() => {\n const button = buttonRef.current;\n if (!button || !blurRef.current) return;\n\n if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) return;\n\n const fx = {\n displacement: CONFIG.initial.displacement,\n blur: CONFIG.initial.blur,\n chroma: chroma\n };\n\n const sync = () => {\n displacerR.current?.setAttribute(\"scale\", (fx.displacement + fx.chroma).toString());\n displacerG.current?.setAttribute(\"scale\", fx.displacement.toString());\n displacerB.current?.setAttribute(\"scale\", (fx.displacement - fx.chroma).toString());\n blurRef.current?.setAttribute(\"stdDeviation\", fx.blur.toString());\n };\n\n sync();\n\n const onEnter = () => {\n gsap.killTweensOf([fx, button]);\n gsap.to(fx, {\n displacement: CONFIG.hover.displacement,\n blur: CONFIG.hover.blur,\n chroma: chroma * 2.5,\n duration: CONFIG.duration.hover,\n ease: CONFIG.ease.hover,\n onUpdate: sync\n });\n gsap.to(button, { scale: CONFIG.hover.scale, duration: CONFIG.duration.hover, ease: CONFIG.ease.hover });\n };\n\n const onLeave = () => {\n gsap.killTweensOf([fx, button]);\n gsap.to(fx, {\n displacement: CONFIG.initial.displacement,\n blur: CONFIG.initial.blur,\n chroma: chroma,\n duration: CONFIG.duration.hover,\n ease: CONFIG.ease.hoverOut,\n onUpdate: sync\n });\n gsap.to(button, { scale: CONFIG.initial.scale, duration: CONFIG.duration.hover, ease: CONFIG.ease.hoverOut });\n };\n\n const onClick = () => {\n gsap.killTweensOf(button);\n const cur = gsap.getProperty(button, \"scale\") as number;\n gsap.timeline()\n .to(button, { scale: cur * CONFIG.click.scaleDown, duration: CONFIG.duration.clickDown, ease: CONFIG.ease.clickDown })\n .to(button, { scale: CONFIG.click.scaleUp, duration: CONFIG.duration.clickUp, ease: CONFIG.ease.clickUp });\n };\n\n button.addEventListener(\"pointerenter\", onEnter);\n button.addEventListener(\"pointerleave\", onLeave);\n button.addEventListener(\"click\", onClick);\n\n return () => {\n button.removeEventListener(\"pointerenter\", onEnter);\n button.removeEventListener(\"pointerleave\", onLeave);\n button.removeEventListener(\"click\", onClick);\n gsap.killTweensOf([button, fx]);\n };\n }, [buttonRef, maps, chroma]);\n\n // Nothing in the DOM until maps are decoded - no hydration mismatch\n if (!maps) return null;\n\n return (\n <>\n <button\n ref={buttonRef}\n className={cn(\"relative overflow-hidden shadow-2xl shadow-black/20 cursor-pointer\", className)}\n style={{\n width, height, borderRadius: radius, border: \"none\", background: glassColor,\n ...style,\n opacity: ready ? 1 : 0,\n pointerEvents: ready ? undefined : \"none\",\n }}\n {...props}\n >\n <div\n className=\"absolute inset-0 z-0\"\n style={{\n borderRadius: \"inherit\",\n backdropFilter: `url(#${filterId})`,\n WebkitBackdropFilter: `url(#${filterId})`,\n willChange: \"backdrop-filter\",\n transform: \"translateZ(0)\",\n }}\n />\n <div className=\"absolute inset-0 z-10 flex items-center justify-center font-bold text-white shadow-[inset_0_1px_1px_rgba(255,255,255,0.4)]\" style={{ background: \"linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.0) 100%)\", borderRadius: \"inherit\" }}>\n {children}\n </div>\n </button>\n\n <svg style={{ position: \"absolute\", width: 0, height: 0, pointerEvents: \"none\" }} aria-hidden=\"true\">\n <defs>\n <filter id={filterId} x={`-${PADDING_PCT}%`} y={`-${PADDING_PCT}%`} width={`${100 + PADDING_PCT * 2}%`} height={`${100 + PADDING_PCT * 2}%`} colorInterpolationFilters=\"sRGB\">\n <feGaussianBlur ref={blurRef} in=\"SourceGraphic\" stdDeviation={CONFIG.initial.blur} result=\"blurred_bg\" edgeMode=\"duplicate\" />\n\n <feImage href={maps.displacement} result=\"disp_map\" x={`${PADDING_PCT}%`} y={`${PADDING_PCT}%`} width={`${100}%`} height={`${100}%`} preserveAspectRatio=\"none\" />\n\n <feGaussianBlur in=\"disp_map\" stdDeviation={smoothness} result=\"disp_blurred\" edgeMode=\"duplicate\" />\n\n <feDisplacementMap ref={displacerR} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement + chroma} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_r\" />\n <feColorMatrix in=\"displaced_r\" type=\"matrix\" values=\"1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0\" result=\"red_channel\" />\n\n <feDisplacementMap ref={displacerG} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_g\" />\n <feColorMatrix in=\"displaced_g\" type=\"matrix\" values=\"0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0\" result=\"green_channel\" />\n\n <feDisplacementMap ref={displacerB} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement - chroma} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_b\" />\n <feColorMatrix in=\"displaced_b\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0\" result=\"blue_channel\" />\n\n <feBlend in=\"red_channel\" in2=\"green_channel\" mode=\"screen\" result=\"rg_channels\" />\n <feBlend in=\"rg_channels\" in2=\"blue_channel\" mode=\"screen\" result=\"rgb_channels\" />\n\n <feColorMatrix in=\"rgb_channels\" type=\"saturate\" values=\"1.2\" result=\"final\" />\n </filter>\n </defs>\n </svg>\n </>\n );\n }\n);\n","export function cn(...classes: (string | undefined | null | false)[]) {\n return classes.filter(Boolean).join(\" \");\n}\n","export interface MapOptions {\n width: number;\n height: number;\n radius?: number;\n edgeSize?: number;\n intensity?: number;\n distortion?: number;\n}\n\nconst VERT = `attribute vec4 position; void main(){ gl_Position = position; }`;\n\nconst FRAG = `\nprecision mediump float;\nuniform vec2 uRes;\nuniform float uRadius;\nuniform float uEdgeSize;\nuniform float uIntensity;\nuniform float uDistortion;\n\nfloat sdRoundedBox(vec2 p, vec2 b, float r){\n r = min(r, min(b.x, b.y));\n vec2 q = abs(p) - b + r;\n return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;\n}\n\nfloat getHeight(vec2 p) {\n vec2 halfSize = uRes * 0.5 - 2.0;\n\n // Aumenta o tamanho base do box ligeiramente proporcinal ao edge\n halfSize += uEdgeSize * 0.2;\n\n float d = sdRoundedBox(p, halfSize, uRadius);\n\n float borderSoftness = uEdgeSize * uIntensity;\n d = max(d, -borderSoftness);\n return smoothstep(0.0, -borderSoftness, d);\n}\n\nvoid main(){\n vec2 p = gl_FragCoord.xy - uRes * 0.5;\n p.y = -p.y;\n\n // --- Displacement Map ---\n const vec2 e = vec2(1.0, 0.0);\n float hx = getHeight(p + e.xy) - getHeight(p - e.xy);\n float hy = getHeight(p + e.yx) - getHeight(p - e.yx);\n\n vec2 normal = vec2(-hx, -hy) * uDistortion;\n vec2 color = clamp(normal * 0.5 + 0.5, 0.0, 1.0);\n\n gl_FragColor = vec4(color.x, color.y, 0.5, 1.0);\n}\n`;\n\nfunction compile(gl: WebGLRenderingContext, type: number, src: string) {\n const s = gl.createShader(type)!;\n gl.shaderSource(s, src);\n gl.compileShader(s);\n return s;\n}\n\nlet _cachedProgram: { gl: WebGLRenderingContext; program: WebGLProgram; canvas: HTMLCanvasElement } | null = null;\n\nfunction getGL() {\n if (_cachedProgram) return _cachedProgram;\n\n const canvas = document.createElement(\"canvas\");\n const gl = canvas.getContext(\"webgl\", { preserveDrawingBuffer: true, premultipliedAlpha: false })!;\n\n const vs = compile(gl, gl.VERTEX_SHADER, VERT);\n const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n gl.useProgram(program);\n\n const buf = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buf);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);\n const pos = gl.getAttribLocation(program, \"position\");\n gl.enableVertexAttribArray(pos);\n gl.vertexAttribPointer(pos, 2, gl.FLOAT, false, 0, 0);\n\n _cachedProgram = { gl, program, canvas };\n return _cachedProgram;\n}\n\nfunction render(width: number, height: number, radius: number, edgeSize: number, intensity: number, distortion: number): string {\n const { gl, program, canvas } = getGL();\n canvas.width = width;\n canvas.height = height;\n gl.viewport(0, 0, width, height);\n gl.clearColor(0.5, 0.5, 0.5, 1.0);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.useProgram(program);\n\n gl.uniform2f(gl.getUniformLocation(program, \"uRes\"), width, height);\n gl.uniform1f(gl.getUniformLocation(program, \"uRadius\"), radius);\n gl.uniform1f(gl.getUniformLocation(program, \"uEdgeSize\"), edgeSize);\n gl.uniform1f(gl.getUniformLocation(program, \"uIntensity\"), intensity);\n gl.uniform1f(gl.getUniformLocation(program, \"uDistortion\"), distortion);\n\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n return canvas.toDataURL(\"image/png\");\n}\n\nexport function generateGlassMaps(opts: MapOptions): { displacement: string } {\n const { width, height, radius = 60, edgeSize = 40, intensity = 1.0, distortion = 15.0 } = opts;\n const r = Math.min(radius, width / 2, height / 2);\n\n return {\n displacement: render(width, height, r, edgeSize, intensity, distortion),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAsE;AACtE,kBAAiB;;;ACDV,SAAS,MAAM,SAAgD;AACpE,SAAO,QAAQ,OAAO,OAAO,EAAE,KAAK,GAAG;AACzC;;;ACOA,IAAM,OAAO;AAEb,IAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2Cb,SAAS,QAAQ,IAA2B,MAAc,KAAa;AACrE,QAAM,IAAI,GAAG,aAAa,IAAI;AAC9B,KAAG,aAAa,GAAG,GAAG;AACtB,KAAG,cAAc,CAAC;AAClB,SAAO;AACT;AAEA,IAAI,iBAAyG;AAE7G,SAAS,QAAQ;AACf,MAAI,eAAgB,QAAO;AAE3B,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,QAAM,KAAK,OAAO,WAAW,SAAS,EAAE,uBAAuB,MAAM,oBAAoB,MAAM,CAAC;AAEhG,QAAM,KAAK,QAAQ,IAAI,GAAG,eAAe,IAAI;AAC7C,QAAM,KAAK,QAAQ,IAAI,GAAG,iBAAiB,IAAI;AAC/C,QAAM,UAAU,GAAG,cAAc;AACjC,KAAG,aAAa,SAAS,EAAE;AAC3B,KAAG,aAAa,SAAS,EAAE;AAC3B,KAAG,YAAY,OAAO;AACtB,KAAG,WAAW,OAAO;AAErB,QAAM,MAAM,GAAG,aAAa;AAC5B,KAAG,WAAW,GAAG,cAAc,GAAG;AAClC,KAAG,WAAW,GAAG,cAAc,IAAI,aAAa,CAAC,IAAI,IAAI,GAAG,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,WAAW;AAC7F,QAAM,MAAM,GAAG,kBAAkB,SAAS,UAAU;AACpD,KAAG,wBAAwB,GAAG;AAC9B,KAAG,oBAAoB,KAAK,GAAG,GAAG,OAAO,OAAO,GAAG,CAAC;AAEpD,mBAAiB,EAAE,IAAI,SAAS,OAAO;AACvC,SAAO;AACT;AAEA,SAAS,OAAO,OAAe,QAAgB,QAAgB,UAAkB,WAAmB,YAA4B;AAC9H,QAAM,EAAE,IAAI,SAAS,OAAO,IAAI,MAAM;AACtC,SAAO,QAAQ;AACf,SAAO,SAAS;AAChB,KAAG,SAAS,GAAG,GAAG,OAAO,MAAM;AAC/B,KAAG,WAAW,KAAK,KAAK,KAAK,CAAG;AAChC,KAAG,MAAM,GAAG,gBAAgB;AAC5B,KAAG,WAAW,OAAO;AAErB,KAAG,UAAU,GAAG,mBAAmB,SAAS,MAAM,GAAG,OAAO,MAAM;AAClE,KAAG,UAAU,GAAG,mBAAmB,SAAS,SAAS,GAAG,MAAM;AAC9D,KAAG,UAAU,GAAG,mBAAmB,SAAS,WAAW,GAAG,QAAQ;AAClE,KAAG,UAAU,GAAG,mBAAmB,SAAS,YAAY,GAAG,SAAS;AACpE,KAAG,UAAU,GAAG,mBAAmB,SAAS,aAAa,GAAG,UAAU;AAEtE,KAAG,WAAW,GAAG,gBAAgB,GAAG,CAAC;AACrC,SAAO,OAAO,UAAU,WAAW;AACrC;AAEO,SAAS,kBAAkB,MAA4C;AAC5E,QAAM,EAAE,OAAO,QAAQ,SAAS,IAAI,WAAW,IAAI,YAAY,GAAK,aAAa,GAAK,IAAI;AAC1F,QAAM,IAAI,KAAK,IAAI,QAAQ,QAAQ,GAAG,SAAS,CAAC;AAEhD,SAAO;AAAA,IACL,cAAc,OAAO,OAAO,QAAQ,GAAG,UAAU,WAAW,UAAU;AAAA,EACxE;AACF;;;AFiCM;AA9IN,IAAM,SAAS;AAAA,EACb,SAAS,EAAE,OAAO,GAAG,cAAc,IAAI,MAAM,GAAG,QAAQ,EAAE;AAAA,EAC1D,OAAO,EAAE,OAAO,MAAM,cAAc,IAAI,MAAM,GAAG,QAAQ,GAAG;AAAA,EAC5D,OAAO,EAAE,WAAW,MAAM,SAAS,KAAK;AAAA,EACxC,UAAU,EAAE,OAAO,KAAK,WAAW,KAAK,SAAS,IAAI;AAAA,EACrD,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AACF;AAEA,IAAM,cAAc;AAcb,IAAM,wBAAoB;AAAA,EAC/B,SAASA,mBAAkB,IAAqL,KAAK;AAA1L,iBAAE,YAAU,WAAW,QAAQ,KAAK,SAAS,IAAI,SAAS,IAAI,UAAU,WAAW,aAAa,GAAG,YAAY,SAAS,GAAG,aAAa,0BAA0B,MAjC/L,IAiC6B,IAA4K,kBAA5K,IAA4K,CAA1K,YAAU,aAAW,SAAa,UAAa,UAAa,YAAU,aAAW,cAAgB,cAAY,UAAY,cAAuC;AAC3L,UAAM,kBAAc,qBAA0B,IAAI;AAClD,UAAM,YAAa,oBAA8C;AAEjE,UAAM,cAAU,qBAAiC,IAAI;AACrD,UAAM,iBAAa,qBAAoC,IAAI;AAC3D,UAAM,iBAAa,qBAAoC,IAAI;AAC3D,UAAM,iBAAa,qBAAoC,IAAI;AAE3D,UAAM,WAAW,WAAO,oBAAM,EAAE,QAAQ,MAAM,EAAE;AAEhD,UAAM,CAAC,MAAM,OAAO,QAAI,uBAAsD,IAAI;AAClF,UAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,KAAK;AAGxC,gCAAU,MAAM;AACd,UAAI,YAAY;AAChB,YAAM,IAAI,kBAAkB,EAAE,OAAO,QAAQ,QAAQ,UAAU,WAAW,WAAW,CAAC;AAItF,YAAM,MAAM,IAAI,MAAM;AACtB,UAAI,SAAS,MAAM;AACjB,YAAI,UAAW;AACf,gBAAQ,CAAC;AAAA,MACX;AACA,UAAI,MAAM,EAAE;AAEZ,aAAO,MAAM;AAAE,oBAAY;AAAA,MAAM;AAAA,IACnC,GAAG,CAAC,OAAO,QAAQ,QAAQ,UAAU,WAAW,UAAU,CAAC;AAI3D,gCAAU,MAAM;AACd,UAAI,CAAC,KAAM;AACX,UAAI,YAAY;AAEhB,YAAM,QAAQ,WAAW,MAAM;AAC7B,YAAI,CAAC,UAAW,UAAS,IAAI;AAAA,MAC/B,GAAG,GAAG;AACN,aAAO,MAAM;AAAE,oBAAY;AAAM,qBAAa,KAAK;AAAA,MAAG;AAAA,IACxD,GAAG,CAAC,IAAI,CAAC;AAET,gCAAU,MAAM;AACd,YAAM,SAAS,UAAU;AACzB,UAAI,CAAC,UAAU,CAAC,QAAQ,QAAS;AAEjC,UAAI,OAAO,WAAW,kCAAkC,EAAE,QAAS;AAEnE,YAAM,KAAK;AAAA,QACT,cAAc,OAAO,QAAQ;AAAA,QAC7B,MAAM,OAAO,QAAQ;AAAA,QACrB;AAAA,MACF;AAEA,YAAM,OAAO,MAAM;AAxFzB,YAAAC,KAAAC,KAAA;AAyFQ,SAAAD,MAAA,WAAW,YAAX,gBAAAA,IAAoB,aAAa,UAAU,GAAG,eAAe,GAAG,QAAQ,SAAS;AACjF,SAAAC,MAAA,WAAW,YAAX,gBAAAA,IAAoB,aAAa,SAAS,GAAG,aAAa,SAAS;AACnE,yBAAW,YAAX,mBAAoB,aAAa,UAAU,GAAG,eAAe,GAAG,QAAQ,SAAS;AACjF,sBAAQ,YAAR,mBAAiB,aAAa,gBAAgB,GAAG,KAAK,SAAS;AAAA,MACjE;AAEA,WAAK;AAEL,YAAM,UAAU,MAAM;AACpB,oBAAAC,QAAK,aAAa,CAAC,IAAI,MAAM,CAAC;AAC9B,oBAAAA,QAAK,GAAG,IAAI;AAAA,UACV,cAAc,OAAO,MAAM;AAAA,UAC3B,MAAM,OAAO,MAAM;AAAA,UACnB,QAAQ,SAAS;AAAA,UACjB,UAAU,OAAO,SAAS;AAAA,UAC1B,MAAM,OAAO,KAAK;AAAA,UAClB,UAAU;AAAA,QACZ,CAAC;AACD,oBAAAA,QAAK,GAAG,QAAQ,EAAE,OAAO,OAAO,MAAM,OAAO,UAAU,OAAO,SAAS,OAAO,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,MACzG;AAEA,YAAM,UAAU,MAAM;AACpB,oBAAAA,QAAK,aAAa,CAAC,IAAI,MAAM,CAAC;AAC9B,oBAAAA,QAAK,GAAG,IAAI;AAAA,UACV,cAAc,OAAO,QAAQ;AAAA,UAC7B,MAAM,OAAO,QAAQ;AAAA,UACrB;AAAA,UACA,UAAU,OAAO,SAAS;AAAA,UAC1B,MAAM,OAAO,KAAK;AAAA,UAClB,UAAU;AAAA,QACZ,CAAC;AACD,oBAAAA,QAAK,GAAG,QAAQ,EAAE,OAAO,OAAO,QAAQ,OAAO,UAAU,OAAO,SAAS,OAAO,MAAM,OAAO,KAAK,SAAS,CAAC;AAAA,MAC9G;AAEA,YAAM,UAAU,MAAM;AACpB,oBAAAA,QAAK,aAAa,MAAM;AACxB,cAAM,MAAM,YAAAA,QAAK,YAAY,QAAQ,OAAO;AAC5C,oBAAAA,QAAK,SAAS,EACX,GAAG,QAAQ,EAAE,OAAO,MAAM,OAAO,MAAM,WAAW,UAAU,OAAO,SAAS,WAAW,MAAM,OAAO,KAAK,UAAU,CAAC,EACpH,GAAG,QAAQ,EAAE,OAAO,OAAO,MAAM,SAAS,UAAU,OAAO,SAAS,SAAS,MAAM,OAAO,KAAK,QAAQ,CAAC;AAAA,MAC7G;AAEA,aAAO,iBAAiB,gBAAgB,OAAO;AAC/C,aAAO,iBAAiB,gBAAgB,OAAO;AAC/C,aAAO,iBAAiB,SAAS,OAAO;AAExC,aAAO,MAAM;AACX,eAAO,oBAAoB,gBAAgB,OAAO;AAClD,eAAO,oBAAoB,gBAAgB,OAAO;AAClD,eAAO,oBAAoB,SAAS,OAAO;AAC3C,oBAAAA,QAAK,aAAa,CAAC,QAAQ,EAAE,CAAC;AAAA,MAChC;AAAA,IACF,GAAG,CAAC,WAAW,MAAM,MAAM,CAAC;AAG5B,QAAI,CAAC,KAAM,QAAO;AAElB,WACE,4EACE;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,WAAW,GAAG,sEAAsE,SAAS;AAAA,UAC7F,OAAO;AAAA,YACL;AAAA,YAAO;AAAA,YAAQ,cAAc;AAAA,YAAQ,QAAQ;AAAA,YAAQ,YAAY;AAAA,aAC9D,QAFE;AAAA,YAGL,SAAS,QAAQ,IAAI;AAAA,YACrB,eAAe,QAAQ,SAAY;AAAA,UACrC;AAAA,WACI,QATL;AAAA,UAWC;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,cAAc;AAAA,kBACd,gBAAgB,QAAQ,QAAQ;AAAA,kBAChC,sBAAsB,QAAQ,QAAQ;AAAA,kBACtC,YAAY;AAAA,kBACZ,WAAW;AAAA,gBACb;AAAA;AAAA,YACF;AAAA,YACA,4CAAC,SAAI,WAAU,8HAA6H,OAAO,EAAE,YAAY,kFAAkF,cAAc,UAAU,GACxQ,UACH;AAAA;AAAA;AAAA,MACF;AAAA,MAEA,4CAAC,SAAI,OAAO,EAAE,UAAU,YAAY,OAAO,GAAG,QAAQ,GAAG,eAAe,OAAO,GAAG,eAAY,QAC5F,sDAAC,UACC,uDAAC,YAAO,IAAI,UAAU,GAAG,IAAI,WAAW,KAAK,GAAG,IAAI,WAAW,KAAK,OAAO,GAAG,MAAM,cAAc,CAAC,KAAK,QAAQ,GAAG,MAAM,cAAc,CAAC,KAAK,2BAA0B,QACrK;AAAA,oDAAC,oBAAe,KAAK,SAAS,IAAG,iBAAgB,cAAc,OAAO,QAAQ,MAAM,QAAO,cAAa,UAAS,aAAY;AAAA,QAE7H,4CAAC,aAAQ,MAAM,KAAK,cAAc,QAAO,YAAW,GAAG,GAAG,WAAW,KAAK,GAAG,GAAG,WAAW,KAAK,OAAO,GAAG,GAAG,KAAK,QAAQ,GAAG,GAAG,KAAK,qBAAoB,QAAO;AAAA,QAEhK,4CAAC,oBAAe,IAAG,YAAW,cAAc,YAAY,QAAO,gBAAe,UAAS,aAAY;AAAA,QAEnG,4CAAC,uBAAkB,KAAK,YAAY,IAAG,cAAa,KAAI,gBAAe,OAAO,OAAO,QAAQ,eAAe,QAAQ,kBAAiB,KAAI,kBAAiB,KAAI,QAAO,eAAc;AAAA,QACnL,4CAAC,mBAAc,IAAG,eAAc,MAAK,UAAS,QAAO,8CAA6C,QAAO,eAAc;AAAA,QAEvH,4CAAC,uBAAkB,KAAK,YAAY,IAAG,cAAa,KAAI,gBAAe,OAAO,OAAO,QAAQ,cAAc,kBAAiB,KAAI,kBAAiB,KAAI,QAAO,eAAc;AAAA,QAC1K,4CAAC,mBAAc,IAAG,eAAc,MAAK,UAAS,QAAO,8CAA6C,QAAO,iBAAgB;AAAA,QAEzH,4CAAC,uBAAkB,KAAK,YAAY,IAAG,cAAa,KAAI,gBAAe,OAAO,OAAO,QAAQ,eAAe,QAAQ,kBAAiB,KAAI,kBAAiB,KAAI,QAAO,eAAc;AAAA,QACnL,4CAAC,mBAAc,IAAG,eAAc,MAAK,UAAS,QAAO,8CAA6C,QAAO,gBAAe;AAAA,QAExH,4CAAC,aAAQ,IAAG,eAAc,KAAI,iBAAgB,MAAK,UAAS,QAAO,eAAc;AAAA,QACjF,4CAAC,aAAQ,IAAG,eAAc,KAAI,gBAAe,MAAK,UAAS,QAAO,gBAAe;AAAA,QAEjF,4CAAC,mBAAc,IAAG,gBAAe,MAAK,YAAW,QAAO,OAAM,QAAO,SAAQ;AAAA,SAC/E,GACF,GACF;AAAA,OACF;AAAA,EAEJ;AACF;","names":["LiquidGlassButton","_a","_b","gsap"]}
package/dist/index.js CHANGED
@@ -161,23 +161,29 @@ var LiquidGlassButton = forwardRef(
161
161
  const displacerB = useRef(null);
162
162
  const filterId = "lg" + useId().replace(/:/g, "");
163
163
  const [maps, setMaps] = useState(null);
164
- const [painted, setPainted] = useState(false);
164
+ const [ready, setReady] = useState(false);
165
165
  useEffect(() => {
166
- setMaps(generateGlassMaps({ width, height, radius, edgeSize, intensity, distortion }));
167
- setPainted(false);
166
+ let cancelled = false;
167
+ const m = generateGlassMaps({ width, height, radius, edgeSize, intensity, distortion });
168
+ const img = new Image();
169
+ img.onload = () => {
170
+ if (cancelled) return;
171
+ setMaps(m);
172
+ };
173
+ img.src = m.displacement;
174
+ return () => {
175
+ cancelled = true;
176
+ };
168
177
  }, [width, height, radius, edgeSize, intensity, distortion]);
169
178
  useEffect(() => {
170
179
  if (!maps) return;
171
180
  let cancelled = false;
172
- requestAnimationFrame(() => {
173
- requestAnimationFrame(() => {
174
- requestAnimationFrame(() => {
175
- if (!cancelled) setPainted(true);
176
- });
177
- });
178
- });
181
+ const timer = setTimeout(() => {
182
+ if (!cancelled) setReady(true);
183
+ }, 150);
179
184
  return () => {
180
185
  cancelled = true;
186
+ clearTimeout(timer);
181
187
  };
182
188
  }, [maps]);
183
189
  useEffect(() => {
@@ -250,9 +256,8 @@ var LiquidGlassButton = forwardRef(
250
256
  border: "none",
251
257
  background: glassColor
252
258
  }, style), {
253
- // OUR control - AFTER user style so it can't be overridden
254
- opacity: painted ? 1 : 0,
255
- pointerEvents: painted ? void 0 : "none"
259
+ opacity: ready ? 1 : 0,
260
+ pointerEvents: ready ? void 0 : "none"
256
261
  })
257
262
  }, props), {
258
263
  children: [
@@ -263,7 +268,9 @@ var LiquidGlassButton = forwardRef(
263
268
  style: {
264
269
  borderRadius: "inherit",
265
270
  backdropFilter: `url(#${filterId})`,
266
- WebkitBackdropFilter: `url(#${filterId})`
271
+ WebkitBackdropFilter: `url(#${filterId})`,
272
+ willChange: "backdrop-filter",
273
+ transform: "translateZ(0)"
267
274
  }
268
275
  }
269
276
  ),
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/liquid-glass-button.tsx","../src/utils.ts","../src/generate-displacement-map.ts"],"sourcesContent":["import React, { useRef, useEffect, useState, useId, forwardRef } from \"react\";\nimport gsap from \"gsap\";\nimport { cn } from \"./utils\";\nimport { generateGlassMaps } from \"./generate-displacement-map\";\n\nconst CONFIG = {\n initial: { scale: 1, displacement: 35, blur: 2, chroma: 3 },\n hover: { scale: 1.05, displacement: 65, blur: 4, chroma: 10 },\n click: { scaleDown: 0.95, scaleUp: 1.05 },\n duration: { hover: 0.4, clickDown: 0.1, clickUp: 0.3 },\n ease: {\n hover: \"power3.out\",\n hoverOut: \"power2.out\",\n clickDown: \"power2.in\",\n clickUp: \"back.out(2)\",\n },\n} as const;\n\nconst PADDING_PCT = 50;\n\nexport interface LiquidGlassButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n width?: number;\n height?: number;\n radius?: number;\n edgeSize?: number;\n intensity?: number;\n smoothness?: number;\n distortion?: number;\n chroma?: number;\n glassColor?: string;\n}\n\nexport const LiquidGlassButton = forwardRef<HTMLButtonElement, LiquidGlassButtonProps>(\n function LiquidGlassButton({ children, className, width = 300, height = 56, radius = 60, edgeSize, intensity, smoothness = 1, distortion, chroma = 3, glassColor = \"rgba(255,255,255,0.05)\", style, ...props }, ref) {\n const internalRef = useRef<HTMLButtonElement>(null);\n const buttonRef = (ref as React.RefObject<HTMLButtonElement>) ?? internalRef;\n\n const blurRef = useRef<SVGFEGaussianBlurElement>(null);\n const displacerR = useRef<SVGFEDisplacementMapElement>(null);\n const displacerG = useRef<SVGFEDisplacementMapElement>(null);\n const displacerB = useRef<SVGFEDisplacementMapElement>(null);\n\n const filterId = \"lg\" + useId().replace(/:/g, \"\");\n\n // Phase 1: generate displacement maps (client only)\n const [maps, setMaps] = useState<ReturnType<typeof generateGlassMaps> | null>(null);\n // Phase 2: browser has painted the SVG filter - safe to show\n const [painted, setPainted] = useState(false);\n\n useEffect(() => {\n setMaps(generateGlassMaps({ width, height, radius, edgeSize, intensity, distortion }));\n setPainted(false);\n }, [width, height, radius, edgeSize, intensity, distortion]);\n\n // After maps are in the DOM, wait for the browser to actually composite the SVG filter\n useEffect(() => {\n if (!maps) return;\n let cancelled = false;\n // Triple rAF: ensures React committed DOM, browser laid out, AND painted the filter\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (!cancelled) setPainted(true);\n });\n });\n });\n return () => { cancelled = true; };\n }, [maps]);\n\n useEffect(() => {\n const button = buttonRef.current;\n if (!button || !blurRef.current) return;\n\n if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) return;\n\n const fx = {\n displacement: CONFIG.initial.displacement,\n blur: CONFIG.initial.blur,\n chroma: chroma\n };\n\n const sync = () => {\n displacerR.current?.setAttribute(\"scale\", (fx.displacement + fx.chroma).toString());\n displacerG.current?.setAttribute(\"scale\", fx.displacement.toString());\n displacerB.current?.setAttribute(\"scale\", (fx.displacement - fx.chroma).toString());\n blurRef.current?.setAttribute(\"stdDeviation\", fx.blur.toString());\n };\n\n sync();\n\n const onEnter = () => {\n gsap.killTweensOf([fx, button]);\n gsap.to(fx, {\n displacement: CONFIG.hover.displacement,\n blur: CONFIG.hover.blur,\n chroma: chroma * 2.5,\n duration: CONFIG.duration.hover,\n ease: CONFIG.ease.hover,\n onUpdate: sync\n });\n gsap.to(button, { scale: CONFIG.hover.scale, duration: CONFIG.duration.hover, ease: CONFIG.ease.hover });\n };\n\n const onLeave = () => {\n gsap.killTweensOf([fx, button]);\n gsap.to(fx, {\n displacement: CONFIG.initial.displacement,\n blur: CONFIG.initial.blur,\n chroma: chroma,\n duration: CONFIG.duration.hover,\n ease: CONFIG.ease.hoverOut,\n onUpdate: sync\n });\n gsap.to(button, { scale: CONFIG.initial.scale, duration: CONFIG.duration.hover, ease: CONFIG.ease.hoverOut });\n };\n\n const onClick = () => {\n gsap.killTweensOf(button);\n const cur = gsap.getProperty(button, \"scale\") as number;\n gsap.timeline()\n .to(button, { scale: cur * CONFIG.click.scaleDown, duration: CONFIG.duration.clickDown, ease: CONFIG.ease.clickDown })\n .to(button, { scale: CONFIG.click.scaleUp, duration: CONFIG.duration.clickUp, ease: CONFIG.ease.clickUp });\n };\n\n button.addEventListener(\"pointerenter\", onEnter);\n button.addEventListener(\"pointerleave\", onLeave);\n button.addEventListener(\"click\", onClick);\n\n return () => {\n button.removeEventListener(\"pointerenter\", onEnter);\n button.removeEventListener(\"pointerleave\", onLeave);\n button.removeEventListener(\"click\", onClick);\n gsap.killTweensOf([button, fx]);\n };\n }, [buttonRef, maps, chroma]);\n\n // Server: maps=null → null. Client before maps: null. No hydration mismatch.\n if (!maps) return null;\n\n return (\n <>\n <button\n ref={buttonRef}\n className={cn(\"relative overflow-hidden shadow-2xl shadow-black/20 cursor-pointer\", className)}\n style={{\n width, height, borderRadius: radius, border: \"none\", background: glassColor,\n ...style,\n // OUR control - AFTER user style so it can't be overridden\n opacity: painted ? 1 : 0,\n pointerEvents: painted ? undefined : \"none\",\n }}\n {...props}\n >\n <div\n className=\"absolute inset-0 z-0\"\n style={{\n borderRadius: \"inherit\",\n backdropFilter: `url(#${filterId})`,\n WebkitBackdropFilter: `url(#${filterId})`\n }}\n />\n <div className=\"absolute inset-0 z-10 flex items-center justify-center font-bold text-white shadow-[inset_0_1px_1px_rgba(255,255,255,0.4)]\" style={{ background: \"linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.0) 100%)\", borderRadius: \"inherit\" }}>\n {children}\n </div>\n </button>\n\n <svg style={{ position: \"absolute\", width: 0, height: 0, pointerEvents: \"none\" }} aria-hidden=\"true\">\n <defs>\n <filter id={filterId} x={`-${PADDING_PCT}%`} y={`-${PADDING_PCT}%`} width={`${100 + PADDING_PCT * 2}%`} height={`${100 + PADDING_PCT * 2}%`} colorInterpolationFilters=\"sRGB\">\n <feGaussianBlur ref={blurRef} in=\"SourceGraphic\" stdDeviation={CONFIG.initial.blur} result=\"blurred_bg\" edgeMode=\"duplicate\" />\n\n <feImage href={maps.displacement} result=\"disp_map\" x={`${PADDING_PCT}%`} y={`${PADDING_PCT}%`} width={`${100}%`} height={`${100}%`} preserveAspectRatio=\"none\" />\n\n <feGaussianBlur in=\"disp_map\" stdDeviation={smoothness} result=\"disp_blurred\" edgeMode=\"duplicate\" />\n\n <feDisplacementMap ref={displacerR} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement + chroma} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_r\" />\n <feColorMatrix in=\"displaced_r\" type=\"matrix\" values=\"1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0\" result=\"red_channel\" />\n\n <feDisplacementMap ref={displacerG} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_g\" />\n <feColorMatrix in=\"displaced_g\" type=\"matrix\" values=\"0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0\" result=\"green_channel\" />\n\n <feDisplacementMap ref={displacerB} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement - chroma} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_b\" />\n <feColorMatrix in=\"displaced_b\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0\" result=\"blue_channel\" />\n\n <feBlend in=\"red_channel\" in2=\"green_channel\" mode=\"screen\" result=\"rg_channels\" />\n <feBlend in=\"rg_channels\" in2=\"blue_channel\" mode=\"screen\" result=\"rgb_channels\" />\n\n <feColorMatrix in=\"rgb_channels\" type=\"saturate\" values=\"1.2\" result=\"final\" />\n </filter>\n </defs>\n </svg>\n </>\n );\n }\n);\n","export function cn(...classes: (string | undefined | null | false)[]) {\n return classes.filter(Boolean).join(\" \");\n}\n","export interface MapOptions {\n width: number;\n height: number;\n radius?: number;\n edgeSize?: number;\n intensity?: number;\n distortion?: number;\n}\n\nconst VERT = `attribute vec4 position; void main(){ gl_Position = position; }`;\n\nconst FRAG = `\nprecision mediump float;\nuniform vec2 uRes;\nuniform float uRadius;\nuniform float uEdgeSize;\nuniform float uIntensity;\nuniform float uDistortion;\n\nfloat sdRoundedBox(vec2 p, vec2 b, float r){\n r = min(r, min(b.x, b.y));\n vec2 q = abs(p) - b + r;\n return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;\n}\n\nfloat getHeight(vec2 p) {\n vec2 halfSize = uRes * 0.5 - 2.0;\n\n // Aumenta o tamanho base do box ligeiramente proporcinal ao edge\n halfSize += uEdgeSize * 0.2;\n\n float d = sdRoundedBox(p, halfSize, uRadius);\n\n float borderSoftness = uEdgeSize * uIntensity;\n d = max(d, -borderSoftness);\n return smoothstep(0.0, -borderSoftness, d);\n}\n\nvoid main(){\n vec2 p = gl_FragCoord.xy - uRes * 0.5;\n p.y = -p.y;\n\n // --- Displacement Map ---\n const vec2 e = vec2(1.0, 0.0);\n float hx = getHeight(p + e.xy) - getHeight(p - e.xy);\n float hy = getHeight(p + e.yx) - getHeight(p - e.yx);\n\n vec2 normal = vec2(-hx, -hy) * uDistortion;\n vec2 color = clamp(normal * 0.5 + 0.5, 0.0, 1.0);\n\n gl_FragColor = vec4(color.x, color.y, 0.5, 1.0);\n}\n`;\n\nfunction compile(gl: WebGLRenderingContext, type: number, src: string) {\n const s = gl.createShader(type)!;\n gl.shaderSource(s, src);\n gl.compileShader(s);\n return s;\n}\n\nlet _cachedProgram: { gl: WebGLRenderingContext; program: WebGLProgram; canvas: HTMLCanvasElement } | null = null;\n\nfunction getGL() {\n if (_cachedProgram) return _cachedProgram;\n\n const canvas = document.createElement(\"canvas\");\n const gl = canvas.getContext(\"webgl\", { preserveDrawingBuffer: true, premultipliedAlpha: false })!;\n\n const vs = compile(gl, gl.VERTEX_SHADER, VERT);\n const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n gl.useProgram(program);\n\n const buf = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buf);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);\n const pos = gl.getAttribLocation(program, \"position\");\n gl.enableVertexAttribArray(pos);\n gl.vertexAttribPointer(pos, 2, gl.FLOAT, false, 0, 0);\n\n _cachedProgram = { gl, program, canvas };\n return _cachedProgram;\n}\n\nfunction render(width: number, height: number, radius: number, edgeSize: number, intensity: number, distortion: number): string {\n const { gl, program, canvas } = getGL();\n canvas.width = width;\n canvas.height = height;\n gl.viewport(0, 0, width, height);\n gl.clearColor(0.5, 0.5, 0.5, 1.0);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.useProgram(program);\n\n gl.uniform2f(gl.getUniformLocation(program, \"uRes\"), width, height);\n gl.uniform1f(gl.getUniformLocation(program, \"uRadius\"), radius);\n gl.uniform1f(gl.getUniformLocation(program, \"uEdgeSize\"), edgeSize);\n gl.uniform1f(gl.getUniformLocation(program, \"uIntensity\"), intensity);\n gl.uniform1f(gl.getUniformLocation(program, \"uDistortion\"), distortion);\n\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n return canvas.toDataURL(\"image/png\");\n}\n\nexport function generateGlassMaps(opts: MapOptions): { displacement: string } {\n const { width, height, radius = 60, edgeSize = 40, intensity = 1.0, distortion = 15.0 } = opts;\n const r = Math.min(radius, width / 2, height / 2);\n\n return {\n displacement: render(width, height, r, edgeSize, intensity, distortion),\n };\n}\n"],"mappings":"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","names":["LiquidGlassButton","_a","_b"]}
1
+ {"version":3,"sources":["../src/liquid-glass-button.tsx","../src/utils.ts","../src/generate-displacement-map.ts"],"sourcesContent":["import React, { useRef, useEffect, useState, useId, forwardRef } from \"react\";\nimport gsap from \"gsap\";\nimport { cn } from \"./utils\";\nimport { generateGlassMaps } from \"./generate-displacement-map\";\n\nconst CONFIG = {\n initial: { scale: 1, displacement: 35, blur: 2, chroma: 3 },\n hover: { scale: 1.05, displacement: 65, blur: 4, chroma: 10 },\n click: { scaleDown: 0.95, scaleUp: 1.05 },\n duration: { hover: 0.4, clickDown: 0.1, clickUp: 0.3 },\n ease: {\n hover: \"power3.out\",\n hoverOut: \"power2.out\",\n clickDown: \"power2.in\",\n clickUp: \"back.out(2)\",\n },\n} as const;\n\nconst PADDING_PCT = 50;\n\nexport interface LiquidGlassButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n width?: number;\n height?: number;\n radius?: number;\n edgeSize?: number;\n intensity?: number;\n smoothness?: number;\n distortion?: number;\n chroma?: number;\n glassColor?: string;\n}\n\nexport const LiquidGlassButton = forwardRef<HTMLButtonElement, LiquidGlassButtonProps>(\n function LiquidGlassButton({ children, className, width = 300, height = 56, radius = 60, edgeSize, intensity, smoothness = 1, distortion, chroma = 3, glassColor = \"rgba(255,255,255,0.05)\", style, ...props }, ref) {\n const internalRef = useRef<HTMLButtonElement>(null);\n const buttonRef = (ref as React.RefObject<HTMLButtonElement>) ?? internalRef;\n\n const blurRef = useRef<SVGFEGaussianBlurElement>(null);\n const displacerR = useRef<SVGFEDisplacementMapElement>(null);\n const displacerG = useRef<SVGFEDisplacementMapElement>(null);\n const displacerB = useRef<SVGFEDisplacementMapElement>(null);\n\n const filterId = \"lg\" + useId().replace(/:/g, \"\");\n\n const [maps, setMaps] = useState<ReturnType<typeof generateGlassMaps> | null>(null);\n const [ready, setReady] = useState(false);\n\n // Phase 1: generate displacement maps + pre-decode the PNG data URL\n useEffect(() => {\n let cancelled = false;\n const m = generateGlassMaps({ width, height, radius, edgeSize, intensity, distortion });\n\n // Pre-decode the data URL PNG so the browser has it in cache\n // BEFORE the <feImage> references it\n const img = new Image();\n img.onload = () => {\n if (cancelled) return;\n setMaps(m);\n };\n img.src = m.displacement;\n\n return () => { cancelled = true; };\n }, [width, height, radius, edgeSize, intensity, distortion]);\n\n // Phase 2: after maps are in the DOM + feImage has the pre-decoded image,\n // wait for the browser to fully composite the SVG filter\n useEffect(() => {\n if (!maps) return;\n let cancelled = false;\n // 150ms timeout guarantees the browser has composited the filter\n const timer = setTimeout(() => {\n if (!cancelled) setReady(true);\n }, 150);\n return () => { cancelled = true; clearTimeout(timer); };\n }, [maps]);\n\n useEffect(() => {\n const button = buttonRef.current;\n if (!button || !blurRef.current) return;\n\n if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) return;\n\n const fx = {\n displacement: CONFIG.initial.displacement,\n blur: CONFIG.initial.blur,\n chroma: chroma\n };\n\n const sync = () => {\n displacerR.current?.setAttribute(\"scale\", (fx.displacement + fx.chroma).toString());\n displacerG.current?.setAttribute(\"scale\", fx.displacement.toString());\n displacerB.current?.setAttribute(\"scale\", (fx.displacement - fx.chroma).toString());\n blurRef.current?.setAttribute(\"stdDeviation\", fx.blur.toString());\n };\n\n sync();\n\n const onEnter = () => {\n gsap.killTweensOf([fx, button]);\n gsap.to(fx, {\n displacement: CONFIG.hover.displacement,\n blur: CONFIG.hover.blur,\n chroma: chroma * 2.5,\n duration: CONFIG.duration.hover,\n ease: CONFIG.ease.hover,\n onUpdate: sync\n });\n gsap.to(button, { scale: CONFIG.hover.scale, duration: CONFIG.duration.hover, ease: CONFIG.ease.hover });\n };\n\n const onLeave = () => {\n gsap.killTweensOf([fx, button]);\n gsap.to(fx, {\n displacement: CONFIG.initial.displacement,\n blur: CONFIG.initial.blur,\n chroma: chroma,\n duration: CONFIG.duration.hover,\n ease: CONFIG.ease.hoverOut,\n onUpdate: sync\n });\n gsap.to(button, { scale: CONFIG.initial.scale, duration: CONFIG.duration.hover, ease: CONFIG.ease.hoverOut });\n };\n\n const onClick = () => {\n gsap.killTweensOf(button);\n const cur = gsap.getProperty(button, \"scale\") as number;\n gsap.timeline()\n .to(button, { scale: cur * CONFIG.click.scaleDown, duration: CONFIG.duration.clickDown, ease: CONFIG.ease.clickDown })\n .to(button, { scale: CONFIG.click.scaleUp, duration: CONFIG.duration.clickUp, ease: CONFIG.ease.clickUp });\n };\n\n button.addEventListener(\"pointerenter\", onEnter);\n button.addEventListener(\"pointerleave\", onLeave);\n button.addEventListener(\"click\", onClick);\n\n return () => {\n button.removeEventListener(\"pointerenter\", onEnter);\n button.removeEventListener(\"pointerleave\", onLeave);\n button.removeEventListener(\"click\", onClick);\n gsap.killTweensOf([button, fx]);\n };\n }, [buttonRef, maps, chroma]);\n\n // Nothing in the DOM until maps are decoded - no hydration mismatch\n if (!maps) return null;\n\n return (\n <>\n <button\n ref={buttonRef}\n className={cn(\"relative overflow-hidden shadow-2xl shadow-black/20 cursor-pointer\", className)}\n style={{\n width, height, borderRadius: radius, border: \"none\", background: glassColor,\n ...style,\n opacity: ready ? 1 : 0,\n pointerEvents: ready ? undefined : \"none\",\n }}\n {...props}\n >\n <div\n className=\"absolute inset-0 z-0\"\n style={{\n borderRadius: \"inherit\",\n backdropFilter: `url(#${filterId})`,\n WebkitBackdropFilter: `url(#${filterId})`,\n willChange: \"backdrop-filter\",\n transform: \"translateZ(0)\",\n }}\n />\n <div className=\"absolute inset-0 z-10 flex items-center justify-center font-bold text-white shadow-[inset_0_1px_1px_rgba(255,255,255,0.4)]\" style={{ background: \"linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.0) 100%)\", borderRadius: \"inherit\" }}>\n {children}\n </div>\n </button>\n\n <svg style={{ position: \"absolute\", width: 0, height: 0, pointerEvents: \"none\" }} aria-hidden=\"true\">\n <defs>\n <filter id={filterId} x={`-${PADDING_PCT}%`} y={`-${PADDING_PCT}%`} width={`${100 + PADDING_PCT * 2}%`} height={`${100 + PADDING_PCT * 2}%`} colorInterpolationFilters=\"sRGB\">\n <feGaussianBlur ref={blurRef} in=\"SourceGraphic\" stdDeviation={CONFIG.initial.blur} result=\"blurred_bg\" edgeMode=\"duplicate\" />\n\n <feImage href={maps.displacement} result=\"disp_map\" x={`${PADDING_PCT}%`} y={`${PADDING_PCT}%`} width={`${100}%`} height={`${100}%`} preserveAspectRatio=\"none\" />\n\n <feGaussianBlur in=\"disp_map\" stdDeviation={smoothness} result=\"disp_blurred\" edgeMode=\"duplicate\" />\n\n <feDisplacementMap ref={displacerR} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement + chroma} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_r\" />\n <feColorMatrix in=\"displaced_r\" type=\"matrix\" values=\"1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0\" result=\"red_channel\" />\n\n <feDisplacementMap ref={displacerG} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_g\" />\n <feColorMatrix in=\"displaced_g\" type=\"matrix\" values=\"0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0\" result=\"green_channel\" />\n\n <feDisplacementMap ref={displacerB} in=\"blurred_bg\" in2=\"disp_blurred\" scale={CONFIG.initial.displacement - chroma} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"displaced_b\" />\n <feColorMatrix in=\"displaced_b\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0\" result=\"blue_channel\" />\n\n <feBlend in=\"red_channel\" in2=\"green_channel\" mode=\"screen\" result=\"rg_channels\" />\n <feBlend in=\"rg_channels\" in2=\"blue_channel\" mode=\"screen\" result=\"rgb_channels\" />\n\n <feColorMatrix in=\"rgb_channels\" type=\"saturate\" values=\"1.2\" result=\"final\" />\n </filter>\n </defs>\n </svg>\n </>\n );\n }\n);\n","export function cn(...classes: (string | undefined | null | false)[]) {\n return classes.filter(Boolean).join(\" \");\n}\n","export interface MapOptions {\n width: number;\n height: number;\n radius?: number;\n edgeSize?: number;\n intensity?: number;\n distortion?: number;\n}\n\nconst VERT = `attribute vec4 position; void main(){ gl_Position = position; }`;\n\nconst FRAG = `\nprecision mediump float;\nuniform vec2 uRes;\nuniform float uRadius;\nuniform float uEdgeSize;\nuniform float uIntensity;\nuniform float uDistortion;\n\nfloat sdRoundedBox(vec2 p, vec2 b, float r){\n r = min(r, min(b.x, b.y));\n vec2 q = abs(p) - b + r;\n return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;\n}\n\nfloat getHeight(vec2 p) {\n vec2 halfSize = uRes * 0.5 - 2.0;\n\n // Aumenta o tamanho base do box ligeiramente proporcinal ao edge\n halfSize += uEdgeSize * 0.2;\n\n float d = sdRoundedBox(p, halfSize, uRadius);\n\n float borderSoftness = uEdgeSize * uIntensity;\n d = max(d, -borderSoftness);\n return smoothstep(0.0, -borderSoftness, d);\n}\n\nvoid main(){\n vec2 p = gl_FragCoord.xy - uRes * 0.5;\n p.y = -p.y;\n\n // --- Displacement Map ---\n const vec2 e = vec2(1.0, 0.0);\n float hx = getHeight(p + e.xy) - getHeight(p - e.xy);\n float hy = getHeight(p + e.yx) - getHeight(p - e.yx);\n\n vec2 normal = vec2(-hx, -hy) * uDistortion;\n vec2 color = clamp(normal * 0.5 + 0.5, 0.0, 1.0);\n\n gl_FragColor = vec4(color.x, color.y, 0.5, 1.0);\n}\n`;\n\nfunction compile(gl: WebGLRenderingContext, type: number, src: string) {\n const s = gl.createShader(type)!;\n gl.shaderSource(s, src);\n gl.compileShader(s);\n return s;\n}\n\nlet _cachedProgram: { gl: WebGLRenderingContext; program: WebGLProgram; canvas: HTMLCanvasElement } | null = null;\n\nfunction getGL() {\n if (_cachedProgram) return _cachedProgram;\n\n const canvas = document.createElement(\"canvas\");\n const gl = canvas.getContext(\"webgl\", { preserveDrawingBuffer: true, premultipliedAlpha: false })!;\n\n const vs = compile(gl, gl.VERTEX_SHADER, VERT);\n const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n gl.useProgram(program);\n\n const buf = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buf);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);\n const pos = gl.getAttribLocation(program, \"position\");\n gl.enableVertexAttribArray(pos);\n gl.vertexAttribPointer(pos, 2, gl.FLOAT, false, 0, 0);\n\n _cachedProgram = { gl, program, canvas };\n return _cachedProgram;\n}\n\nfunction render(width: number, height: number, radius: number, edgeSize: number, intensity: number, distortion: number): string {\n const { gl, program, canvas } = getGL();\n canvas.width = width;\n canvas.height = height;\n gl.viewport(0, 0, width, height);\n gl.clearColor(0.5, 0.5, 0.5, 1.0);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.useProgram(program);\n\n gl.uniform2f(gl.getUniformLocation(program, \"uRes\"), width, height);\n gl.uniform1f(gl.getUniformLocation(program, \"uRadius\"), radius);\n gl.uniform1f(gl.getUniformLocation(program, \"uEdgeSize\"), edgeSize);\n gl.uniform1f(gl.getUniformLocation(program, \"uIntensity\"), intensity);\n gl.uniform1f(gl.getUniformLocation(program, \"uDistortion\"), distortion);\n\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n return canvas.toDataURL(\"image/png\");\n}\n\nexport function generateGlassMaps(opts: MapOptions): { displacement: string } {\n const { width, height, radius = 60, edgeSize = 40, intensity = 1.0, distortion = 15.0 } = opts;\n const r = Math.min(radius, width / 2, height / 2);\n\n return {\n displacement: render(width, height, r, edgeSize, intensity, distortion),\n };\n}\n"],"mappings":"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","names":["LiquidGlassButton","_a","_b"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marcosdemik/liquidglass",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Liquid Glass UI effect for React - glassmorphism refraction with SVG filters, WebGL and GSAP animations",
5
5
  "author": "Marcos Demik <marcosdemik>",
6
6
  "license": "MIT",