
2025/06/15
7 分钟阅读
在React项目中使用Liquid Glass的5种创意方法
探索Liquid Glass效果在React应用中的实际应用,从导航组件到交互式仪表板,包含完整代码示例和实现技巧。
Liquid Glass效果彻底改变了现代UI设计,将macOS Tahoe的优雅美学带到了Web应用中。以下是将liquid-glass-react集成到项目中的五种实用且富有创意的方法,包含完整的代码示例和最佳实践。
1. 交互式导航头部
使用响应用户交互和滚动位置的动态Liquid Glass效果来改造您的导航头部。
实现方案
'use client';
import { ConditionalLiquidGlass } from '@/components/shared/conditional-liquid-glass';
import { useState, useEffect } from 'react';
const LiquidGlassNavigation = () => {
const [scrollY, setScrollY] = useState(0);
const [isMenuOpen, setIsMenuOpen] = useState(false);
useEffect(() => {
const handleScroll = () => setScrollY(window.scrollY);
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
// 基于滚动位置的动态参数
const dynamicParams = {
displacementScale: Math.min(3.0 + scrollY * 0.01, 5.0),
blurAmount: Math.min(1.0 + scrollY * 0.005, 2.5),
elasticity: 0.8 + (scrollY * 0.001),
aberrationIntensity: Math.min(scrollY * 0.002, 0.5)
};
return (
<ConditionalLiquidGlass
{...dynamicParams}
cornerRadius={0}
className="fixed top-0 left-0 right-0 z-50 transition-all duration-300"
style={{
background: `rgba(255, 255, 255, ${Math.min(scrollY * 0.001, 0.1)})`,
backdropFilter: `blur(${Math.min(scrollY * 0.1, 20)}px) saturate(180%)`,
borderBottom: '1px solid rgba(255, 255, 255, 0.2)',
}}
>
<nav className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-16">
<div className="flex items-center space-x-8">
<div className="text-2xl font-bold">Logo</div>
<div className="hidden md:flex space-x-6">
{['首页', '关于', '服务', '联系'].map((item) => (
<a
key={item}
href={`#${item}`}
className="text-foreground/80 hover:text-foreground transition-colors"
>
{item}
</a>
))}
</div>
</div>
<button
onClick={() => setIsMenuOpen(!isMenuOpen)}
className="md:hidden p-2 rounded-lg bg-white/10 backdrop-blur-sm"
>
<div className="w-6 h-6 flex flex-col justify-center space-y-1">
<div className={`h-0.5 w-full bg-current transition-transform ${
isMenuOpen ? 'rotate-45 translate-y-1' : ''
}`} />
<div className={`h-0.5 w-full bg-current transition-opacity ${
isMenuOpen ? 'opacity-0' : ''
}`} />
<div className={`h-0.5 w-full bg-current transition-transform ${
isMenuOpen ? '-rotate-45 -translate-y-1' : ''
}`} />
</div>
</button>
</div>
</nav>
</ConditionalLiquidGlass>
);
};
主要特性
- 滚动响应效果: 参数根据滚动位置变化
- 移动端友好: 响应式设计与汉堡菜单
- 性能优化: 使用ConditionalLiquidGlass自动降级
2. 模态对话框和遮罩层
创建令人惊艳的模态对话框,感觉像具有深度和交互性的浮动玻璃面板。
实现方案
'use client';
import { ConditionalLiquidGlass } from '@/components/shared/conditional-liquid-glass';
import { X } from 'lucide-react';
import { useEffect, useState } from 'react';
interface LiquidGlassModalProps {
isOpen: boolean;
onClose: () => void;
title: string;
children: React.ReactNode;
size?: 'sm' | 'md' | 'lg' | 'xl';
}
const LiquidGlassModal = ({
isOpen,
onClose,
title,
children,
size = 'md'
}: LiquidGlassModalProps) => {
const [isVisible, setIsVisible] = useState(false);
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
useEffect(() => {
if (isOpen) {
setIsVisible(true);
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = 'unset';
const timer = setTimeout(() => setIsVisible(false), 150);
return () => clearTimeout(timer);
}
}, [isOpen]);
const handleMouseMove = (e: React.MouseEvent) => {
const rect = e.currentTarget.getBoundingClientRect();
setMousePosition({
x: ((e.clientX - rect.left) / rect.width) * 2 - 1,
y: ((e.clientY - rect.top) / rect.height) * 2 - 1,
});
};
const sizeClasses = {
sm: 'max-w-md',
md: 'max-w-lg',
lg: 'max-w-2xl',
xl: 'max-w-4xl'
};
if (!isVisible) return null;
return (
<div className={`fixed inset-0 z-50 flex items-center justify-center p-4 transition-opacity duration-150 ${
isOpen ? 'opacity-100' : 'opacity-0'
}`}>
{/* 背景遮罩 */}
<div
className="absolute inset-0 bg-black/50 backdrop-blur-sm"
onClick={onClose}
/>
{/* 模态框 */}
<ConditionalLiquidGlass
displacementScale={2.5 + Math.abs(mousePosition.x) * 0.5}
blurAmount={1.8}
elasticity={0.7 + Math.abs(mousePosition.y) * 0.1}
cornerRadius={20}
globalMousePos={mousePosition}
className={`relative ${sizeClasses[size]} w-full transform transition-all duration-150 ${
isOpen ? 'scale-100 opacity-100' : 'scale-95 opacity-0'
}`}
style={{
background: 'rgba(255, 255, 255, 0.05)',
backdropFilter: 'blur(25px) saturate(200%)',
border: '1px solid rgba(255, 255, 255, 0.2)',
boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.5)',
}}
onMouseMove={handleMouseMove}
>
<div className="p-6">
{/* 头部 */}
<div className="flex items-center justify-between mb-6">
<h2 className="text-2xl font-bold">{title}</h2>
<button
onClick={onClose}
className="p-2 rounded-full hover:bg-white/10 transition-colors"
>
<X className="w-5 h-5" />
</button>
</div>
{/* 内容 */}
<div className="space-y-4">
{children}
</div>
</div>
</ConditionalLiquidGlass>
</div>
);
};
3. 仪表板卡片和小部件
使用响应用户交互的交互式仪表板组件增强数据可视化。
实现方案
'use client';
import { ConditionalLiquidGlass } from '@/components/shared/conditional-liquid-glass';
import { TrendingUp, Users, DollarSign, Activity } from 'lucide-react';
import { useState } from 'react';
interface DashboardCardProps {
title: string;
value: string;
change: string;
trend: 'up' | 'down';
icon: React.ReactNode;
color: 'blue' | 'green' | 'purple' | 'orange';
}
const DashboardCard = ({ title, value, change, trend, icon, color }: DashboardCardProps) => {
const [isHovered, setIsHovered] = useState(false);
const [clickPosition, setClickPosition] = useState({ x: 0, y: 0 });
const colorSchemes = {
blue: {
background: 'rgba(59, 130, 246, 0.05)',
border: 'rgba(59, 130, 246, 0.2)',
accent: 'text-blue-400'
},
green: {
background: 'rgba(34, 197, 94, 0.05)',
border: 'rgba(34, 197, 94, 0.2)',
accent: 'text-green-400'
},
purple: {
background: 'rgba(147, 51, 234, 0.05)',
border: 'rgba(147, 51, 234, 0.2)',
accent: 'text-purple-400'
},
orange: {
background: 'rgba(249, 115, 22, 0.05)',
border: 'rgba(249, 115, 22, 0.2)',
accent: 'text-orange-400'
}
};
const handleClick = (e: React.MouseEvent) => {
const rect = e.currentTarget.getBoundingClientRect();
setClickPosition({
x: e.clientX - rect.left,
y: e.clientY - rect.top,
});
};
return (
<ConditionalLiquidGlass
displacementScale={isHovered ? 3.5 : 2.0}
blurAmount={isHovered ? 2.0 : 1.3}
elasticity={isHovered ? 0.9 : 0.7}
cornerRadius={16}
className="cursor-pointer transition-all duration-300 hover:scale-105"
style={{
background: colorSchemes[color].background,
backdropFilter: 'blur(20px) saturate(150%)',
border: `1px solid ${colorSchemes[color].border}`,
}}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
onClick={handleClick}
>
<div className="p-6">
<div className="flex items-center justify-between mb-4">
<div className={`p-3 rounded-full bg-white/10 ${colorSchemes[color].accent}`}>
{icon}
</div>
<div className={`text-sm font-medium ${
trend === 'up' ? 'text-green-400' : 'text-red-400'
}`}>
{trend === 'up' ? '↗' : '↘'} {change}
</div>
</div>
<h3 className="text-lg font-medium text-muted-foreground mb-2">{title}</h3>
<p className="text-3xl font-bold">{value}</p>
</div>
</ConditionalLiquidGlass>
);
};
4. 交互式表单和输入字段
使用提供视觉反馈的玻璃拟态输入字段来改造表单交互。
实现方案
'use client';
import { ConditionalLiquidGlass } from '@/components/shared/conditional-liquid-glass';
import { Eye, EyeOff, Mail, Lock, User } from 'lucide-react';
import { useState } from 'react';
interface LiquidGlassInputProps {
type: string;
placeholder: string;
icon: React.ReactNode;
value: string;
onChange: (value: string) => void;
error?: string;
}
const LiquidGlassInput = ({
type,
placeholder,
icon,
value,
onChange,
error
}: LiquidGlassInputProps) => {
const [isFocused, setIsFocused] = useState(false);
const [showPassword, setShowPassword] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const inputType = type === 'password' && showPassword ? 'text' : type;
return (
<div className="space-y-2">
<ConditionalLiquidGlass
displacementScale={isFocused ? 3.0 : isHovered ? 2.5 : 2.0}
blurAmount={isFocused ? 1.8 : 1.2}
elasticity={isFocused ? 0.8 : 0.6}
cornerRadius={12}
style={{
background: isFocused
? 'rgba(255, 255, 255, 0.08)'
: 'rgba(255, 255, 255, 0.03)',
backdropFilter: 'blur(16px) saturate(150%)',
border: `1px solid ${
error
? 'rgba(239, 68, 68, 0.5)'
: isFocused
? 'rgba(59, 130, 246, 0.5)'
: 'rgba(255, 255, 255, 0.1)'
}`,
}}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
<div className="flex items-center p-4 space-x-3">
<div className={`transition-colors ${
isFocused ? 'text-blue-400' : 'text-muted-foreground'
}`}>
{icon}
</div>
<input
type={inputType}
placeholder={placeholder}
value={value}
onChange={(e) => onChange(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
className="flex-1 bg-transparent border-none outline-none text-foreground placeholder-muted-foreground"
/>
{type === 'password' && (
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="text-muted-foreground hover:text-foreground transition-colors"
>
{showPassword ? <EyeOff className="w-5 h-5" /> : <Eye className="w-5 h-5" />}
</button>
)}
</div>
</ConditionalLiquidGlass>
{error && (
<p className="text-sm text-red-400 ml-4">{error}</p>
)}
</div>
);
};
5. 功能展示卡片
使用突出产品功能的交互式玻璃面板创建引人注目的功能展示。
实现方案
'use client';
import { ConditionalLiquidGlass } from '@/components/shared/conditional-liquid-glass';
import { Zap, Shield, Smartphone, Palette, Code, Globe } from 'lucide-react';
import { useState } from 'react';
const FeatureCard = ({ icon, title, description, features, color, delay }) => {
const [isHovered, setIsHovered] = useState(false);
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
const handleMouseMove = (e: React.MouseEvent) => {
const rect = e.currentTarget.getBoundingClientRect();
setMousePosition({
x: ((e.clientX - rect.left) / rect.width - 0.5) * 2,
y: ((e.clientY - rect.top) / rect.height - 0.5) * 2,
});
};
return (
<ConditionalLiquidGlass
displacementScale={isHovered ? 4.0 + Math.abs(mousePosition.x) : 2.5}
blurAmount={isHovered ? 2.2 : 1.4}
elasticity={0.7 + Math.abs(mousePosition.y) * 0.1}
cornerRadius={20}
globalMousePos={mousePosition}
className="group cursor-pointer transition-all duration-500 hover:scale-105 transform"
style={{
background: `linear-gradient(135deg, ${color}15 0%, ${color}05 100%)`,
backdropFilter: 'blur(20px) saturate(150%)',
border: `1px solid ${color}30`,
animationDelay: `${delay}ms`,
}}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
onMouseMove={handleMouseMove}
>
<div className="p-8 h-full">
{/* 图标和标题 */}
<div className="flex items-center space-x-4 mb-6">
<div
className="p-4 rounded-2xl transition-all duration-300 group-hover:scale-110"
style={{
background: `${color}20`,
color: color,
}}
>
{icon}
</div>
<h3 className="text-2xl font-bold">{title}</h3>
</div>
{/* 描述 */}
<p className="text-muted-foreground mb-6 leading-relaxed">
{description}
</p>
{/* 功能列表 */}
<ul className="space-y-3">
{features.map((feature, index) => (
<li
key={index}
className="flex items-center space-x-3 text-sm opacity-80 group-hover:opacity-100 transition-opacity"
>
<div
className="w-2 h-2 rounded-full"
style={{ backgroundColor: color }}
/>
<span>{feature}</span>
</li>
))}
</ul>
</div>
</ConditionalLiquidGlass>
);
};
实现技巧和最佳实践
性能考虑
- 使用ConditionalLiquidGlass: 始终使用包装组件进行自动降级
- 懒加载: 对不立即可见的组件实现懒加载
- 参数优化: 根据设备能力调整参数
- 内存管理: 在useEffect清理函数中清理WebGL资源
无障碍指南
- 尊重动画偏好: 遵循
prefers-reduced-motion
设置 - 键盘导航: 确保所有交互元素都可以通过键盘访问
- 焦点管理: 提供清晰的焦点指示器
- 屏幕阅读器支持: 使用正确的ARIA标签和描述
设计原则
- 细微为佳: 从细微效果开始,根据用户反馈增强
- 一致的主题: 在整个应用中保持一致的玻璃参数
- 适合上下文: 对英雄区域使用更强效果,UI组件使用更细微效果
- 性能预算: 监控性能影响并相应调整
结论
Liquid Glass效果为创建引人入胜的现代Web界面开辟了令人兴奋的可能性。这五个用例展示了liquid-glass-react库的多功能性和强大功能,从导航头部到交互式表单。
记住始终优先考虑用户体验和性能,使用渐进增强确保您的应用在所有设备和浏览器上都能完美运行。
资源
准备在您的项目中实现这些模式?从ConditionalLiquidGlass组件开始,使用这些经过验证的模式逐步增强您的用户界面。
更多文章
邮件列表
加入我们的社区
订阅邮件列表,及时获取最新消息和更新