import 'package:flutter/material.dart';

class ExplicitAnimationsScreen extends StatefulWidget {
  const ExplicitAnimationsScreen({super.key});

  
  State<ExplicitAnimationsScreen> createState() =>
      _ExplicitAnimationsScreenState();
}

class _ExplicitAnimationsScreenState extends State<ExplicitAnimationsScreen>
    with SingleTickerProviderStateMixin {
  late final AnimationController _animationController = AnimationController(
    vsync: this,
    duration: const Duration(seconds: 2),
  );

  late final Animation<Decoration> _decoration = DecorationTween(
    begin: BoxDecoration(
      color: Colors.amber,
      borderRadius: BorderRadius.circular(20),
    ),
    end: BoxDecoration(
      color: Colors.red,
      borderRadius: BorderRadius.circular(120),
    ),
  ).animate(_animationController);

  late final Animation<double> _rotation = Tween(
    begin: 0.0,
    end: 2.0,
  ).animate(_animationController);

  late final Animation<double> _scale = Tween(
    begin: 1.0,
    end: 1.1,
  ).animate(_animationController);

  late final Animation<Offset> _position = Tween(
    begin: Offset.zero,
    end: const Offset(0, -0.2),
  ).animate(_animationController);

  void _play() {
    _animationController.forward();
  }

  void _pause() {
    _animationController.stop();
  }

  void _rewind() {
    _animationController.reverse();
  }

  
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    print("build");
    return Scaffold(
      appBar: AppBar(
        title: const Text('Explicit Animations'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SlideTransition(
              position: _position,
              child: ScaleTransition(
                scale: _scale,
                child: RotationTransition(
                  turns: _rotation,
                  child: DecoratedBoxTransition(
                    decoration: _decoration,
                    child: const SizedBox(
                      height: 400,
                      width: 400,
                    ),
                  ),
                ),
              ),
            ),
            const SizedBox(
              height: 50,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: _play,
                  child: const Text("Play"),
                ),
                ElevatedButton(
                  onPressed: _pause,
                  child: const Text("Pause"),
                ),
                ElevatedButton(
                  onPressed: _rewind,
                  child: const Text("Rewind"),
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}

이 Flutter 예제에서 사용된 다양한 애니메이션 객체와 애니메이션 위젯은 각각의 독특한 애니메이션 효과를 구현하고, 이들을 조합하여 복합적인 애니메이션 효과를 만듭니다. 아래에서 각 애니메이션 객체와 위젯의 역할과 작동 방식을 자세히 설명하겠습니다.

1. 애니메이션 객체:

_decoration:

  • DecorationTween을 사용하여 박스의 BoxDecoration을 애니메이션화합니다.
  • beginend로 시작 및 종료 상태를 정의합니다. 여기서는 색상(color)과 테두리 반경(borderRadius)이 변합니다.
  • 애니메이션이 진행됨에 따라, 색상은 Colors.amber에서 Colors.red로, 테두리 반경은 20에서 120으로 부드럽게 변화합니다.

_rotation:

  • Tween<double>을 사용하여 회전 애니메이션을 구현합니다.
  • begin 값 0.0과 end 값 2.0은 회전을 나타내며, 이는 360도 회전을 두 번 수행함을 의미합니다.
  • _animationController의 진행 상태에 따라 위젯이 회전합니다.

_scale:

  • Tween<double>을 사용하여 크기 변화(scale) 애니메이션을 만듭니다.
  • 1.0에서 1.1로 변화하는 값은 위젯의 크기가 10% 증가함을 나타냅니다.
  • 이 애니메이션은 위젯을 약간 확대하거나 축소합니다.

_position:

  • Tween<Offset>을 사용하여 위젯의 위치 이동 애니메이션을 만듭니다.
  • Offset.zero에서 Offset(0, -0.2)로 이동하는 것은 위젯이 수직 방향으로 약간 위로 이동함을 의미합니다.

2. 애니메이션 위젯:

SlideTransition:

  • _position 애니메이션을 적용하여 위젯의 위치를 이동시킵니다.
  • SlideTransitionOffset 값을 사용하여 위젯의 위치를 변화시키는데, 이는 위젯을 수직 방향으로 부드럽게 이동시킵니다.

ScaleTransition:

  • _scale 애니메이션을 적용하여 위젯의 크기를 조절합니다.
  • ScaleTransition은 위젯의 크기를 확대하거나 축소하는 효과를 만듭니다.

RotationTransition:

  • _rotation 애니메이션을 적용하여 위젯을 회전시킵니다.
  • RotationTransition은 위젯을 주어진 각도만큼 회전시키며, 이 경우에는 두 바퀴 회전합니다.

DecoratedBoxTransition:

  • _decoration 애니메이션을 적용하여 위젯의 배경 색상과 테두리 반경을 변화시킵니다.
  • DecoratedBoxTransition은 박스의 디자인을 변화시키며, 이는 색상과 테두리 반경의 부드러운 전환을 포함합니다.

CurvedAnimation 추가:

import 'package:flutter/material.dart';

class ExplicitAnimationsScreen extends StatefulWidget {
  const ExplicitAnimationsScreen({super.key});

  
  State<ExplicitAnimationsScreen> createState() =>
      _ExplicitAnimationsScreenState();
}

class _ExplicitAnimationsScreenState extends State<ExplicitAnimationsScreen>
    with SingleTickerProviderStateMixin {
  late final AnimationController _animationController = AnimationController(
    vsync: this,
    duration: const Duration(seconds: 2),
    reverseDuration: const Duration(seconds: 1),
  );

  late final Animation<Decoration> _decoration = DecorationTween(
    begin: BoxDecoration(
      color: Colors.amber,
      borderRadius: BorderRadius.circular(20),
    ),
    end: BoxDecoration(
      color: Colors.red,
      borderRadius: BorderRadius.circular(120),
    ),
  ).animate(_curve);

  late final Animation<double> _rotation = Tween(
    begin: 0.0,
    end: 0.5,
  ).animate(_curve);

  late final Animation<double> _scale = Tween(
    begin: 1.0,
    end: 1.1,
  ).animate(_curve);

  late final Animation<Offset> _position = Tween(
    begin: Offset.zero,
    end: const Offset(0, -0.2),
  ).animate(_curve);

  late final CurvedAnimation _curve = CurvedAnimation(
    parent: _animationController,
    curve: Curves.elasticOut,
    reverseCurve: Curves.bounceIn,
  );

  void _play() {
    _animationController.forward();
  }

  void _pause() {
    _animationController.stop();
  }

  void _rewind() {
    _animationController.reverse();
  }

  
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    print("build");
    return Scaffold(
      appBar: AppBar(
        title: const Text('Explicit Animations'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SlideTransition(
              position: _position,
              child: ScaleTransition(
                scale: _scale,
                child: RotationTransition(
                  turns: _rotation,
                  child: DecoratedBoxTransition(
                    decoration: _decoration,
                    child: const SizedBox(
                      height: 400,
                      width: 400,
                    ),
                  ),
                ),
              ),
            ),
            const SizedBox(
              height: 50,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: _play,
                  child: const Text("Play"),
                ),
                ElevatedButton(
                  onPressed: _pause,
                  child: const Text("Pause"),
                ),
                ElevatedButton(
                  onPressed: _rewind,
                  child: const Text("Rewind"),
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}

이 코드의 CurvedAnimation 객체는 애니메이션에 특정한 가속도 곡선(curve)을 적용하여, 움직임의 자연스러움과 동적인 표현을 향상시키는 역할을 합니다. CurvedAnimation을 사용하면 애니메이션의 시작과 끝에서 속도를 조절하여 보다 부드러운 효과를 만들 수 있습니다.

CurvedAnimation의 구성요소:

  • parent:

    • parent 속성은 CurvedAnimation이 적용될 기본 Animation 객체를 지정합니다. 여기서는 _animationControllerparent로 사용되어, AnimationController에 곡선을 적용합니다.
  • curve:

    • curve 속성은 애니메이션의 정방향 재생 시 적용될 가속도 곡선을 정의합니다.
    • Curves.elasticOut는 애니메이션이 끝날 때 탄성 있는 효과를 줍니다. 이는 애니메이션이 목표 지점에 도달하면서 뒤로 조금 당겨진 후 최종 상태로 돌아오는 효과를 만들어냅니다.
  • reverseCurve:

    • reverseCurve는 애니메이션이 역방향으로 재생될 때 적용될 가속도 곡선을 정의합니다.
    • Curves.bounceIn은 애니메이션이 역방향으로 재생될 때 튕기는 듯한 효과를 줍니다. 이는 애니메이션이 시작 지점으로 돌아갈 때 마치 공이 튕기는 것처럼 동작합니다.

CurvedAnimation의 활용:

CurvedAnimation은 애니메이션에 생동감을 더하기 위한 중요한 도구입니다. 기본적인 선형 또는 일정한 속도의 애니메이션 대신에, 이를 사용하면 다음과 같은 효과를 얻을 수 있습니다:

  • 자연스러운 움직임: 곡선을 통해 실제 세계의 움직임처럼 자연스러운 가속도와 감속 효과를 만들 수 있습니다.
  • 시각적 관심 증가: 탄성이나 튕기는 효과는 사용자의 관심을 끌고, UI에 생동감을 더하는 좋은 방법입니다.
  • 사용자 경험 향상: 부드러운 애니메이션은 사용자 경험을 개선하고, 애플리케이션의 전반적인 느낌을 향상시킵니다.

이러한 방식으로 CurvedAnimation은 Flutter 애플리케이션에서 애니메이션의 품질을 높이는 데 기여하며, 사용자에게 더욱 풍부하고 매력적인 인터랙션을 제공합니다.

profile
공부하는 개발자

0개의 댓글