[flutter] 클리퍼를 이용한 플러터 앱 버튼 애니메이션 구현 방법

안녕하세요! 이번 포스트에서는 클리퍼(Clipper)를 이용하여 플러터(Flutter) 앱 버튼 애니메이션을 구현하는 방법에 대해 알아보겠습니다.

1. 클리퍼란?

클리퍼는 플러터에서 UI 요소를 원하는 모양으로 잘라내는 역할을 합니다. 예를 들어, 사각형 버튼을 원형으로 자르거나, 다각형 모양으로 자를 수 있습니다. 클리퍼는 CustomClipper 클래스를 상속받아 구현할 수 있습니다.

2. 버튼 애니메이션 구현

먼저, CustomClipper 클래스를 상속받아 클리퍼를 구현합니다. 이 예시에서는 버튼을 원형으로 자르는 CircularClipper를 구현해보겠습니다.

class CircularClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    Path path = Path();
    path.addOval(Rect.fromCircle(center: size.center(Offset.zero), radius: size.width / 2));
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return false;
  }
}

getClip() 메소드에서는 버튼을 원형으로 자르기 위해 Path를 사용합니다. shouldReclip() 메소드에서는 클리퍼가 다시 그려져야 할 때를 결정하는데, 이 예시에서는 항상 false를 반환하여 클리퍼를 다시 그리지 않도록 설정했습니다.

다음으로, 버튼 위젯을 생성하고 ClipPath 위젯을 이용해 클리퍼를 적용해보겠습니다.

class AnimatedButton extends StatefulWidget {
  @override
  _AnimatedButtonState createState() => _AnimatedButtonState();
}

class _AnimatedButtonState extends State<AnimatedButton> with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  bool _isPressed = false;

  @override
  void initState() {
    _animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 200));
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (_) {
        _animationController.forward();
        setState(() {
          _isPressed = true;
        });
      },
      onTapUp: (_) {
        _animationController.reverse();
        setState(() {
          _isPressed = false;
        });
      },
      child: AnimatedContainer(
        duration: Duration(milliseconds: 200),
        width: _isPressed ? 80 : 100,
        height: 40,
        decoration: BoxDecoration(
          color: _isPressed ? Colors.blue.withOpacity(0.8) : Colors.blue,
          borderRadius: BorderRadius.circular(_isPressed ? 20 : 0),
        ),
        child: ClipPath(
          clipper: CircularClipper(),
          child: Center(
            child: Text(
              "버튼",
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
      ),
    );
  }
}

AnimatedButton 위젯은 StatefulWidget을 상속받아 구현되었습니다. AnimationController를 사용하여 버튼이 눌러졌을 때 애니메이션을 추가합니다. GestureDetector를 사용하여 버튼의 터치 이벤트를 처리하고, AnimatedContainer 위젯을 사용하여 버튼의 크기와 색상 등을 애니메이션으로 처리합니다. 마지막으로, ClipPath 위젯을 이용하여 클리퍼를 적용하고, CircularClipper를 사용하여 버튼을 원형으로 자릅니다.

3. 버튼 애니메이션 사용 예시

위에서 구현한 버튼 애니메이션은 다음과 같이 사용할 수 있습니다.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("버튼 애니메이션 예시")),
        body: Center(
          child: AnimatedButton(),
        ),
      ),
    );
  }
}

void main() {
  runApp(MyApp());
}

MyApp 위젯에서 AnimatedButton을 사용하여 버튼 애니메이션을 표시합니다.

결론

이번 포스트에서는 클리퍼를 이용하여 플러터 앱 버튼 애니메이션을 구현하는 방법에 대해 알아보았습니다. 클리퍼를 사용하면 다양한 버튼 애니메이션을 구현할 수 있으니, 창의적인 디자인을 위해 활용해보세요. 감사합니다!