Flitter의 애니메이션 컨트롤러

애니메이션 컨트롤러는 Flitter에서 애니메이션을 관리하는 핵심 클래스입니다. 애니메이션의 타이밍, 방향, 상태를 정밀하게 제어할 수 있어 부드럽고 상호작용이 가능한 애니메이션을 만들 수 있습니다.

핵심 개념

  1. 애니메이션 값: 0.0부터 1.0 사이의 double 값
  2. 지속 시간: 애니메이션이 완료되는 데 걸리는 시간
  3. 방향: 정방향 또는 역방향 애니메이션 재생
  4. 상태: 애니메이션 상태 (dismissed, forward, reverse, completed)

기본 사용법

간단한 애니메이션 컨트롤러 생성하기:

import { AnimationController } from "@meursyphus/flitter";

const controller = new AnimationController({
  duration: 1000, // 밀리초
});

// 애니메이션 시작
controller.forward();

애니메이션 상태

애니메이션 상태 제어하기

const controller = new AnimationController({ duration: 1000 });

// 정방향 애니메이션
controller.forward();

// 역방향 애니메이션
controller.reverse();

// 애니메이션 정지
controller.stop();

// 초기 상태로 리셋
controller.reset();

애니메이션 상태 확인하기

controller.addListener(() => {
  console.log({
    value: controller.value,
    isAnimating: controller.isAnimating,
    isDismissed: controller.isDismissed,
    isCompleted: controller.isCompleted,
  });
});

고급 기능

곡선 애니메이션

비선형 애니메이션을 위한 CurvedAnimation 사용하기:

import {
  AnimationController,
  CurvedAnimation,
  Curves,
} from "@meursyphus/flitter";

const controller = new AnimationController({
  duration: 1000,
});

const animation = new CurvedAnimation({
  parent: controller,
  curve: Curves.easeInOut,
});

// controller.value 대신 animation.value 사용

반복 애니메이션

루핑 애니메이션 생성하기:

controller.repeat({
  reverse: true, // 옵션: 핑퐁 애니메이션
});

사용자 정의 시작점

특정 지점에서 애니메이션 시작하기:

controller.forward({ from: 0.5 }); // 중간에서 시작
controller.reverse({ from: 1.0 }); // 끝에서 시작

애니메이션 패턴

페이딩 위젯

function FadingWidget({ child }) {
  const [controller] = useState(
    () => new AnimationController({ duration: 300 }),
  );

  return Container({
    opacity: controller.value,
    child,
  });
}

크기 애니메이션

function ExpandingWidget({ child }) {
  const [controller] = useState(
    () => new AnimationController({ duration: 500 }),
  );

  const size = new Tween({
    begin: 100,
    end: 200,
  }).evaluate(controller);

  return Container({
    width: size,
    height: size,
    child,
  });
}

복합 애니메이션

function ComplexAnimation({ child }) {
  const [controller] = useState(
    () => new AnimationController({ duration: 1000 }),
  );

  const scaleAnimation = new CurvedAnimation({
    parent: controller,
    curve: Curves.easeOut,
  });

  const fadeAnimation = new CurvedAnimation({
    parent: controller,
    curve: Curves.linear,
  });

  return Container({
    scale: 1 + scaleAnimation.value,
    opacity: fadeAnimation.value,
    child,
  });
}

모범 사례

  1. 리소스 관리:

    class AnimatedWidget extends StatefulWidget {
      dispose() {
        controller.dispose(); // 사용 후 정리
        super.dispose();
      }
    }
    
  2. 성능 최적화:

    • 애니메이션 컨트롤러를 재사용할 때는 주의하세요
    • 필요하지 않은 애니메이션 컨트롤러는 제거하세요
    • 부드러운 애니메이션을 위해 적절하게 곡선을 사용하세요
  3. 상태 관리:

    • 애니메이션 로직과 UI 로직을 분리하세요
    • 복잡한 애니메이션에는 상태 관리를 사용하세요
    • 애니메이션 완료 시 적절하게 처리하세요
  4. 오류 처리:

    • 애니메이션 상태를 확인하세요
    • 애니메이션 중단 시 적절하게 처리하세요
    • 애니메이션 실패 시 대체 상태를 제공하세요

일반적인 패턴

연속 애니메이션

function StaggeredAnimation() {
  const [controller1] = useState(
    () => new AnimationController({ duration: 500 }),
  );
  const [controller2] = useState(
    () => new AnimationController({ duration: 500 }),
  );

  controller1.addListener(() => {
    if (controller1.isCompleted) {
      controller2.forward();
    }
  });

  return Stack({
    children: [
      Container({ opacity: controller1.value }),
      Container({ opacity: controller2.value }),
    ],
  });
}

상호작용 애니메이션

function InteractiveAnimation() {
  const [controller] = useState(
    () => new AnimationController({ duration: 300 }),
  );

  return GestureDetector({
    onPointerDown: () => controller.forward(),
    onPointerUp: () => controller.reverse(),
    child: Container({
      scale: 1 + controller.value * 0.2,
    }),
  });
}

결론

애니메이션 컨트롤러는 Flitter에서 복잡한 애니메이션을 만들 수 있는 강력한 도구입니다. 애니메이션 컨트롤러의 기능을 이해하고 모범 사례를 따르면 부드럽고 성능이 좋은 애니메이션을 만들 수 있습니다. 리소스를 적절하게 관리하고, 성능을 최적화하고, 사용자 경험을 고려하여 애니메이션을 구현하세요.