Skip to content

LiquidGlassWrapper 液态玻璃容器

一个高级毛玻璃效果组件,使用物理光学原理模拟真实的玻璃折射和高光效果。

导入

ts
import { LiquidGlassWrapper } from '@xcloud/ui-core/components/liquid-glass-wrapper';

示例

基础用法

tsx
import { LiquidGlassWrapper } from '@xcloud/ui-core/components/liquid-glass-wrapper';

function GlassCard() {
  return (
    <div style={{ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', padding: '40px' }}>
      <LiquidGlassWrapper>
        <h4>标题</h4>
        <p>这是一个带有液态玻璃效果的容器</p>
      </LiquidGlassWrapper>
    </div>
  );
}

不同表面类型

组件提供三种表面类型,每种产生不同的折射效果:

tsx
{/* 凸面玻璃 - 向外凸出,中心放大 */}
<LiquidGlassWrapper surfaceType="convex">
  <p>Convex Surface</p>
</LiquidGlassWrapper>

{/* 凹面玻璃 - 向内凹陷,边缘放大 */}
<LiquidGlassWrapper surfaceType="concave">
  <p>Concave Surface</p>
</LiquidGlassWrapper>

{/* 方圆形玻璃 - 介于圆形和方形之间 */}
<LiquidGlassWrapper surfaceType="squircle">
  <p>Squircle Surface</p>
</LiquidGlassWrapper>

自定义参数

tsx
<LiquidGlassWrapper
  scale={15}                  // 折射强度
  surfaceType="convex"        // 表面类型
  highlightIntensity={0.7}    // 高光强度
  blurIntensity={3}           // 模糊强度
  saturation={2.5}            // 饱和度
>
  <div>自定义玻璃效果</div>
</LiquidGlassWrapper>

响应式效果

组件使用 ResizeObserver 自动响应容器尺寸变化,并重新计算折射贴图:

tsx
<LiquidGlassWrapper>
  <div style={{ width: '100%', minHeight: '200px' }}>
    容器尺寸变化时,效果会自动更新
  </div>
</LiquidGlassWrapper>

API

LiquidGlassWrapper

属性类型默认值说明
childrenReact.ReactNode-子元素内容
scalenumber10位移强度(像素),可设置动画效果
surfaceType'convex' | 'concave' | 'squircle''convex'玻璃表面类型
highlightIntensitynumber0.5镜面高光强度,范围 0-1
blurIntensitynumber2.4折射前的模糊强度
saturationnumber2颜色饱和度倍数
classNamestring-自定义类名
styleReact.CSSProperties-自定义样式
...propsReact.HTMLAttributes<HTMLDivElement>-其他 div 属性

实现原理

1. 物理光学模拟

组件使用简化的斯涅尔定律(Snell's Law)计算光线折射:

  • 空气折射率: n₁ = 1.0
  • 玻璃折射率: n₂ = 1.5
  • 根据表面法线和入射角计算折射角

2. SVG 滤镜链

效果通过以下 SVG 滤镜步骤实现:

xml
<filter>
  <!-- 1. 高斯模糊平滑背景 -->
  <feGaussianBlur stdDeviation="2.4" />

  <!-- 2. 使用位移贴图产生折射 -->
  <feDisplacementMap scale="10" />

  <!-- 3. 增强颜色饱和度 -->
  <feColorMatrix type="saturate" values="2" />

  <!-- 4. 添加镜面高光 -->
  <feBlend mode="screen" />
</filter>

3. 动态生成位移贴图

  • 使用 Canvas API 生成径向折射贴图
  • 根据表面曲率函数计算每个像素的法线方向
  • R/G 通道分别存储 X/Y 轴位移量

4. 性能优化

  • 位移贴图生成使用 memoization 缓存
  • ResizeObserver 更新采用 150ms 防抖
  • SVG 元素动态添加/移除避免内存泄漏

使用场景

1. 卡片覆盖层

tsx
<div style={{ background: 'url(/background.jpg)', padding: '40px' }}>
  <LiquidGlassWrapper>
    <div className="p-6">
      <h3>卡片标题</h3>
      <p>卡片内容</p>
    </div>
  </LiquidGlassWrapper>
</div>

2. 导航栏

tsx
<nav style={{ position: 'fixed', top: 0, left: 0, right: 0 }}>
  <LiquidGlassWrapper surfaceType="squircle" scale={5}>
    <div className="flex items-center justify-between p-4">
      <Logo />
      <Menu />
    </div>
  </LiquidGlassWrapper>
</nav>

3. 模态对话框

tsx
<Modal>
  <LiquidGlassWrapper blurIntensity={4} highlightIntensity={0.3}>
    <ModalContent />
  </LiquidGlassWrapper>
</Modal>

性能注意事项

  1. SVG 滤镜开销: 在低端设备上可能影响性能
  2. 动画限制: 避免频繁改变 scale 等参数触发重绘
  3. 尺寸建议: 大尺寸容器(>1000px)会增加滤镜计算时间
  4. 防抖延迟: 150ms 的 resize 防抖可能在快速调整时有延迟

浏览器兼容性

  • ✅ Chrome/Edge (现代版本)
  • ✅ Firefox (现代版本)
  • ⚠️ Safari (需要 -webkit-backdrop-filter 前缀,已自动添加)
  • ❌ IE11 (不支持 backdrop-filter)

最佳实践

  1. 背景要求: 必须有渐变或图片背景才能看到折射效果
  2. 颜色对比: 确保内容文字与背景有足够对比度
  3. 滤镜限制: 避免在同一页面使用过多玻璃效果组件
  4. 响应式设计: 在移动端考虑使用更简单的半透明背景代替
tsx
const GlassCard = ({ children }) => {
  const isMobile = useMediaQuery('(max-width: 768px)');

  if (isMobile) {
    return <div className="bg-white/10 backdrop-blur-md">{children}</div>;
  }

  return <LiquidGlassWrapper>{children}</LiquidGlassWrapper>;
};

基于 MIT 许可发布