[flutter] 플러터 커스텀 클리퍼와 애니메이션을 함께 사용하는 방법

플러터(Flutter)에서는 커스텀 클리퍼(Custom Clipper)를 사용하여 독특한 모양의 위젯을 만들 수 있습니다. 또한, 애니메이션과 함께 사용하면 흥미로운 시각적 효과를 적용할 수 있습니다. 이번 포스트에서는 플러터에서 커스텀 클리퍼와 애니메이션을 함께 사용하는 방법에 대해 알아보겠습니다.

커스텀 클리퍼를 사용하여 모양 만들기

먼저, 커스텀 클리퍼를 사용하여 원하는 모양을 만들어보겠습니다. 아래의 코드는 커스텀 클리퍼를 사용하여 사각형 위에 원을 그리는 예제입니다.

import 'package:flutter/material.dart';

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

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

class CustomShapeWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ClipPath(
      clipper: CircleClipper(),
      child: Container(
        width: 200,
        height: 200,
        color: Colors.blue,
      ),
    );
  }
}

위 코드에서 CircleClipper 클래스는 CustomClipper<Path>를 상속받아서 구현한 클래스입니다. getClip() 메서드를 오버라이드하여 클리핑될 경로를 정의하고, shouldReclip() 메서드를 오버라이드하여 클리퍼가 업데이트되는지 여부를 결정합니다.

CustomShapeWidgetClipPath 위젯을 사용하여 사각형 위에 원을 그리고 있습니다.

애니메이션 적용하기

이제 애니메이션을 추가하여 커스텀 클리퍼의 모양을 변화시켜보겠습니다. 아래의 코드는 애니메이션을 적용한 커스텀 클리퍼 예제입니다.

import 'package:flutter/material.dart';

class CircleClipper extends CustomClipper<Path> {
  final double progress;

  CircleClipper(this.progress);

  @override
  Path getClip(Size size) {
    final path = Path();
    final radius = size.width / 2 * progress;
    path.addOval(Rect.fromCircle(
      center: Offset(size.width / 2, size.height / 2),
      radius: radius,
    ));
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}

class CustomAnimatedShapeWidget extends StatefulWidget {
  @override
  _CustomAnimatedShapeWidgetState createState() =>
      _CustomAnimatedShapeWidgetState();
}

class _CustomAnimatedShapeWidgetState extends State<CustomAnimatedShapeWidget>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 2),
    )..repeat(reverse: true);
    _animation = CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        return ClipPath(
          clipper: CircleClipper(_animation.value),
          child: Container(
            width: 200,
            height: 200,
            color: Colors.blue,
          ),
        );
      },
    );
  }
}

위 코드에서 CircleClipper 클래스의 생성자에 progress 값을 전달받아 클리퍼의 모양을 조절하고 있습니다. CustomAnimatedShapeWidgetAnimatedBuilder를 사용하여 애니메이션을 구현하고, ClipPath 위젯과 함께 사용하여 모양이 변화하는 애니메이션을 보여줍니다.

결론

플러터에서는 커스텀 클리퍼와 애니메이션을 함께 사용하여 다양한 모양의 위젯을 구현할 수 있습니다. 위에서 제시한 예제 코드를 참고하여 원하는 모양과 애니메이션을 구현해보세요.


참고 자료