import 'package:flutter/material.dart'; import 'dart:math' as math; /// 웨이브 애니메이션 배경 효과를 제공하는 위젯 /// /// [controller]와 [pulseController]를 통해 애니메이션을 제어합니다. class AnimatedWaveBackground extends StatelessWidget { final AnimationController controller; final AnimationController pulseController; const AnimatedWaveBackground({ Key? key, required this.controller, required this.pulseController, }) : super(key: key); @override Widget build(BuildContext context) { return Stack( children: [ // 웨이브 애니메이션 배경 요소 - 사인/코사인 함수 대신 더 부드러운 곡선 사용 AnimatedBuilder( animation: controller, builder: (context, child) { // 0~1 사이의 값을 0~2π 사이의 값으로 변환하여 부드러운 주기 생성 final angle = controller.value * 2 * math.pi; // 사인 함수를 사용하여 부드러운 움직임 생성 final xOffset = 20 * math.sin(angle); final yOffset = 10 * math.cos(angle); return Positioned( right: -40 + xOffset, top: -60 + yOffset, child: Transform.rotate( // 회전도 선형적으로 변화하도록 수정 angle: 0.2 * math.sin(angle * 0.5), child: Container( width: 200, height: 200, decoration: BoxDecoration( color: Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(100), ), ), ), ); }, ), AnimatedBuilder( animation: controller, builder: (context, child) { // 첫 번째 원과 약간 다른 위상을 가지도록 설정 final angle = (controller.value * 2 * math.pi) + (math.pi / 3); final xOffset = 20 * math.cos(angle); final yOffset = 10 * math.sin(angle); return Positioned( left: -80 + xOffset, bottom: -70 + yOffset, child: Transform.rotate( // 반대 방향으로 회전하도록 설정 angle: -0.3 * math.sin(angle * 0.5), child: Container( width: 220, height: 220, decoration: BoxDecoration( color: Colors.white.withOpacity(0.05), borderRadius: BorderRadius.circular(110), ), ), ), ); }, ), // 배경에 추가적인 작은 원 추가하여 깊이감 증가 AnimatedBuilder( animation: controller, builder: (context, child) { // 세 번째 원은 다른 위상으로 움직이도록 설정 final angle = (controller.value * 2 * math.pi) + (math.pi * 2 / 3); final xOffset = 15 * math.sin(angle * 0.7); final yOffset = 8 * math.cos(angle * 0.7); return Positioned( right: 40 + xOffset, bottom: -40 + yOffset, child: Transform.rotate( angle: 0.4 * math.cos(angle * 0.5), child: Container( width: 120, height: 120, decoration: BoxDecoration( color: Colors.white.withOpacity(0.08), borderRadius: BorderRadius.circular(60), ), ), ), ); }, ), // 숨쉬는 효과가 있는 작은 원 AnimatedBuilder( animation: pulseController, builder: (context, child) { return Positioned( top: 10, left: 200, child: Container( width: 30, height: 30, decoration: BoxDecoration( color: Colors.white.withOpacity( 0.1 + 0.1 * pulseController.value, ), borderRadius: BorderRadius.circular(15), ), ), ); }, ), ], ); } }