import 'package:flutter/material.dart'; import 'dart:ui'; import '../theme/app_colors.dart'; class GlassmorphismCard extends StatelessWidget { final Widget child; final EdgeInsetsGeometry? padding; final EdgeInsetsGeometry? margin; final double? width; final double? height; final double borderRadius; final double blur; final double opacity; final Color? backgroundColor; final Gradient? gradient; final Border? border; final List? boxShadow; final VoidCallback? onTap; const GlassmorphismCard({ super.key, required this.child, this.padding, this.margin, this.width, this.height, this.borderRadius = 16.0, this.blur = 10.0, this.opacity = 0.1, this.backgroundColor, this.gradient, this.border, this.boxShadow, this.onTap, }); @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return Container( width: width, height: height, margin: margin, child: Material( color: Colors.transparent, child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(borderRadius), child: ClipRRect( borderRadius: BorderRadius.circular(borderRadius), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur), child: Container( padding: padding, decoration: BoxDecoration( color: backgroundColor ?? (isDarkMode ? AppColors.glassCardDark : AppColors.glassCard), gradient: gradient ?? LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: isDarkMode ? AppColors.glassGradientDark : AppColors.glassGradient, ), borderRadius: BorderRadius.circular(borderRadius), border: border ?? Border.all( color: isDarkMode ? AppColors.glassBorderDark : AppColors.glassBorder, width: 1.5, ), boxShadow: boxShadow ?? [ BoxShadow( color: Colors.black.withValues(alpha: 0.1), blurRadius: 20, spreadRadius: -5, offset: const Offset(0, 10), ), ], ), child: child, ), ), ), ), ), ); } } // 애니메이션이 적용된 글래스모피즘 카드 class AnimatedGlassmorphismCard extends StatefulWidget { final Widget child; final EdgeInsetsGeometry? padding; final EdgeInsetsGeometry? margin; final double? width; final double? height; final double borderRadius; final double blur; final double opacity; final Duration animationDuration; final VoidCallback? onTap; const AnimatedGlassmorphismCard({ super.key, required this.child, this.padding, this.margin, this.width, this.height, this.borderRadius = 16.0, this.blur = 10.0, this.opacity = 0.1, this.animationDuration = const Duration(milliseconds: 200), this.onTap, }); @override State createState() => _AnimatedGlassmorphismCardState(); } class _AnimatedGlassmorphismCardState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _scaleAnimation; late Animation _blurAnimation; @override void initState() { super.initState(); _controller = AnimationController( duration: widget.animationDuration, vsync: this, ); _scaleAnimation = Tween( begin: 1.0, end: 0.98, ).animate(CurvedAnimation( parent: _controller, curve: Curves.easeInOut, )); _blurAnimation = Tween( begin: widget.blur, end: widget.blur * 1.5, ).animate(CurvedAnimation( parent: _controller, curve: Curves.easeInOut, )); } @override void dispose() { _controller.dispose(); super.dispose(); } void _handleTapDown(TapDownDetails details) { _controller.forward(); } void _handleTapUp(TapUpDetails details) { _controller.reverse(); } void _handleTapCancel() { _controller.reverse(); } @override Widget build(BuildContext context) { return GestureDetector( onTapDown: _handleTapDown, onTapUp: _handleTapUp, onTapCancel: _handleTapCancel, onTap: widget.onTap, child: AnimatedBuilder( animation: _controller, builder: (context, child) { return Transform.scale( scale: _scaleAnimation.value, child: GlassmorphismCard( padding: widget.padding, margin: widget.margin, width: widget.width, height: widget.height, borderRadius: widget.borderRadius, blur: _blurAnimation.value, opacity: widget.opacity, child: widget.child, ), ); }, ), ); } }