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
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| children | React.ReactNode | - | 子元素内容 |
| scale | number | 10 | 位移强度(像素),可设置动画效果 |
| surfaceType | 'convex' | 'concave' | 'squircle' | 'convex' | 玻璃表面类型 |
| highlightIntensity | number | 0.5 | 镜面高光强度,范围 0-1 |
| blurIntensity | number | 2.4 | 折射前的模糊强度 |
| saturation | number | 2 | 颜色饱和度倍数 |
| className | string | - | 自定义类名 |
| style | React.CSSProperties | - | 自定义样式 |
| ...props | React.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>性能注意事项
- SVG 滤镜开销: 在低端设备上可能影响性能
- 动画限制: 避免频繁改变
scale等参数触发重绘 - 尺寸建议: 大尺寸容器(>1000px)会增加滤镜计算时间
- 防抖延迟: 150ms 的 resize 防抖可能在快速调整时有延迟
浏览器兼容性
- ✅ Chrome/Edge (现代版本)
- ✅ Firefox (现代版本)
- ⚠️ Safari (需要
-webkit-backdrop-filter前缀,已自动添加) - ❌ IE11 (不支持
backdrop-filter)
最佳实践
- 背景要求: 必须有渐变或图片背景才能看到折射效果
- 颜色对比: 确保内容文字与背景有足够对比度
- 滤镜限制: 避免在同一页面使用过多玻璃效果组件
- 响应式设计: 在移动端考虑使用更简单的半透明背景代替
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>;
};