Created
November 6, 2025 06:41
-
-
Save hongsw/35e3a09c7e7a87bd69f59cb712ada1b3 to your computer and use it in GitHub Desktop.
animation flutter task3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 1. Fade-in/Fade-out 애니메이션: 위젯이 서서히 나타나고 사라지는 효과 | |
| // 2. Slide 애니메이션: 위젯이 화면 안팎으로 미끄러져 들어오고 나가는 효과 | |
| // 3. Rotate 애니메이션: 위젯이 특정 축을 중심으로 회전하는 효과 | |
| import 'package:flutter/material.dart'; | |
| void main() { | |
| runApp(const MyApp()); | |
| } | |
| class MyApp extends StatelessWidget { | |
| const MyApp({super.key}); | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| title: 'Animation Example', // 앱 제목 변경 | |
| theme: ThemeData( | |
| primarySwatch: Colors.blue, | |
| ), | |
| home: const AnimationScreen(), | |
| ); | |
| } | |
| } | |
| // 애니메이션을 구현할 StatefulWidget | |
| // TickerProviderStateMixin은 AnimationController의 vsync 인자를 위해 필요합니다. | |
| class AnimationScreen extends StatefulWidget { | |
| const AnimationScreen({super.key}); | |
| @override | |
| State<AnimationScreen> createState() => _AnimationScreenState(); | |
| } | |
| class _AnimationScreenState extends State<AnimationScreen> | |
| with TickerProviderStateMixin { | |
| // 1. AnimationController 선언: 애니메이션의 진행을 제어 | |
| late AnimationController _controller; | |
| // 2. Animation<double> 선언: 크기 애니메이션 (0.0 ~ 1.0 스케일) | |
| late Animation<double> _scaleAnimation; | |
| // 3. Animation<Color?> 선언: 색상 애니메이션 | |
| late Animation<Color?> _colorAnimation; | |
| @override | |
| void initState() { | |
| super.initState(); | |
| // AnimationController 초기화 | |
| _controller = AnimationController( | |
| duration: const Duration(seconds: 1), // 애니메이션 지속 시간 1초 | |
| // TIP: duration을 변경하여 애니메이션의 속도를 조절할 수 있습니다. | |
| // 예: const Duration(milliseconds: 500)은 더 빠른 애니메이션을 만듭니다. | |
| vsync: this, // TickerProviderStateMixin 제공 | |
| ); | |
| // Tween을 사용하여 크기 애니메이션 정의 | |
| _scaleAnimation = Tween<double>(begin: 1.0, end: 1.5).animate( | |
| // TIP: begin과 end 값을 변경하여 확대/축소 비율을 조절할 수 있습니다. | |
| // 예: begin: 0.5, end: 1.0은 작게 시작하여 원래 크기로 돌아오는 애니메이션입니다. | |
| CurvedAnimation( | |
| parent: _controller, | |
| curve: Curves.easeOut, // 시작은 빠르게, 끝은 느리게 | |
| // TIP: Curves를 변경하여 애니메이션의 가속/감속 효과를 다르게 할 수 있습니다. | |
| // 예: Curves.bounceOut은 마지막에 통통 튀는 효과를, Curves.elasticOut은 고무줄처럼 늘어나는 효과를 줍니다. | |
| ), | |
| ); | |
| // Tween을 사용하여 색상 애니메이션 정의 | |
| _colorAnimation = ColorTween(begin: Colors.blue, end: Colors.red).animate( | |
| // TIP: begin과 end 색상을 변경하여 다양한 색상 전환 효과를 만들 수 있습니다. | |
| // 예: begin: Colors.green, end: Colors.purple | |
| CurvedAnimation( | |
| parent: _controller, | |
| curve: Curves.easeInOut, // 시작과 끝 모두 부드럽게 | |
| // TIP: 이 CurvedAnimation의 curve도 변경하여 색상 전환의 타이밍을 조절할 수 있습니다. | |
| ), | |
| ); | |
| } | |
| @override | |
| void dispose() { | |
| // 위젯이 제거될 때 컨트롤러도 함께 제거하여 리소스 누수 방지 | |
| _controller.dispose(); | |
| super.dispose(); | |
| } | |
| // 애니메이션을 토글(시작/되감기)하는 함수 | |
| void _toggleAnimation() { | |
| if (_controller.status == AnimationStatus.completed) { | |
| // 애니메이션이 완료된 상태면 되감기 | |
| _controller.reverse(); | |
| } else { | |
| // 그 외의 상태면 앞으로 재생 | |
| _controller.forward(); | |
| } | |
| // TIP: 애니메이션 반복을 원한다면, _controller.repeat()을 사용할 수 있습니다. | |
| // 예: _controller.repeat(reverse: true);는 애니메이션을 계속 반복하고, 끝에 도달하면 되감습니다. | |
| // _controller.forward(); 대신 _controller.repeat(reverse: true);를 호출하여 자동 반복 애니메이션을 만들 수 있습니다. | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| appBar: AppBar( | |
| title: const Text('애니메이션 예제'), // 앱 바 제목 변경 | |
| ), | |
| body: Center( | |
| child: GestureDetector( | |
| onTap: _toggleAnimation, // 탭하면 애니메이션 실행/되감기 | |
| child: AnimatedBuilder( | |
| animation: _controller, // _controller가 변경될 때마다 builder 함수 호출 | |
| builder: (BuildContext context, Widget? child) { | |
| return Transform.scale( | |
| scale: _scaleAnimation.value, // _scaleAnimation의 현재 값으로 크기 조절 | |
| child: Container( | |
| width: 100, | |
| height: 100, | |
| decoration: BoxDecoration( | |
| color: _colorAnimation.value, // _colorAnimation의 현재 값으로 색상 변경 | |
| borderRadius: BorderRadius.circular(20), // 모서리 둥글게 | |
| // TIP: borderRadius 값을 변경하여 다른 모양으로 만들 수 있습니다. | |
| // 예: BorderRadius.circular(50)은 완벽한 원을 만듭니다. | |
| // shape: BoxShape.circle을 사용하면 사각형 대신 원을 기본 모양으로 가질 수 있습니다. | |
| ), | |
| child: const Center( | |
| child: Text( | |
| '탭하세요!', | |
| style: TextStyle(color: Colors.white, fontSize: 16), | |
| ), | |
| ), | |
| ), | |
| ); | |
| }, | |
| ), | |
| ), | |
| ), | |
| floatingActionButton: FloatingActionButton( | |
| onPressed: _toggleAnimation, | |
| child: const Icon(Icons.play_arrow), // 재생 아이콘 | |
| // TIP: 아이콘을 Icons.pause, Icons.stop 등으로 변경하여 다른 동작을 나타낼 수 있습니다. | |
| ), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment