Flutter에서는 다양한 애니메이션과 인터랙션을 쉽게 구현할 수 있습니다. 이번에는 사용자의 움직임(터치 또는 드래그)에 따라 이미지가 기울어지는 카드 효과를 만들어보겠습니다.
이 효과는 게임 카드, 상품 카드, 포켓몬 카드 등 다양한 곳에서 활용할 수 있습니다. 특히 3D 느낌을 강조할 수 있는 디자인 요소로, UI의 생동감을 더하는 데 유용합니다.
0. 결과물
1. 기울기 효과란?
일반적인 정적인 UI가 아니라, 사용자의 입력(터치 또는 마우스 이동)에 따라 카드가 기울어지는 효과를 구현하는 것이 목표입니다.
! 사용자가 카드를 터치하고 움직이면, 기울기가 변함
! 손을 떼면 원래 위치로 부드럽게 복귀
! 기울기에 따라 빛 반사(Glare) 효과 적용
이제 이를 어떻게 Flutter에서 구현할지 살펴보겠습니다.
2. 기능 설명
2.1 기울기 효과의 원리
이 기능의 핵심은 사용자의 입력을 감지하여 요소의 기울기 값을 변경하고, 손을 떼면 자연스럽게 원래 위치로 돌아가도록 하는 것입니다. 이를 위해 사용자의 입력을 GestureDetector로 감지하고, Transform을 사용하여 UI 요소를 기울이도록 만듭니다.
Flutter에서는 Matrix4를 활용하여 3D 변환을 적용할 수 있으며, 이를 사용해 카드가 X축, Y축을 기준으로 회전하도록 구현할 것입니다.
2.2 터치 이벤트 감지
Flutter의 GestureDetector는 사용자의 터치 입력을 감지할 수 있는 위젯입니다. 이를 활용하면 사용자가 화면을 터치하고 드래그할 때 X축과 Y축의 움직임을 계산하여 기울기 값을 조절할 수 있습니다.
- onPanUpdate: 사용자가 터치를 유지한 채 이동할 때 호출됨. 이때 details.localPosition을 활용하여 현재 터치 위치를 가져와 기울기 계산
- onPanEnd: 사용자가 터치를 떼면 호출됨. 애니메이션을 적용하여 원래 위치로 복귀하도록 설정
이 방식을 활용하면 사용자의 움직임에 반응하여 부드러운 기울기 효과를 적용할 수 있습니다.
2.3 Transform을 활용한 회전
Flutter의 Transform 위젯을 사용하면 UI 요소를 회전, 이동, 크기 조절하는 것이 가능합니다. Matrix4.identity()를 사용하여 3D 변환 행렬을 초기화하고, rotateX와 rotateY를 활용하여 기울기를 적용합니다.
Transform(
transform: Matrix4.identity()
..setEntry(3, 2, 0.001) // 원근감을 추가
..rotateX(tiltX * (pi / 180))
..rotateY(tiltY * (pi / 180)),
alignment: FractionalOffset.center,
child: Container(
width: 260.w,
height: 350.h,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.r),
color: Colors.white,
),
),
)
2.4 애니메이션을 활용한 원래 위치로 복귀
카드가 기울어진 상태에서 손을 떼면 자연스럽게 원래 위치로 돌아오도록 애니메이션을 적용합니다. AnimationController와 TweenAnimation을 활용하면 부드러운 복귀 애니메이션을 추가할 수 있습니다.
- Tween<double>(begin: tiltX, end: 0.0).animate(...) → 현재 기울어진 값을 점진적으로 0으로 변경
- CurvedAnimation을 사용해 자연스럽게 감속하는 효과 적용
이렇게 하면 카드가 기울어졌다가 사용자가 손을 떼면 부드럽게 원래 위치로 돌아가도록 할 수 있습니다.
3. 코드 작성하기
아래는 기울어지는 카드 효과를 구현한 코드입니다.
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
/// 기울기 효과를 적용한 카드 UI
class TiltCardContent extends StatefulWidget {
const TiltCardContent({super.key});
@override
TiltCardContentState createState() => TiltCardContentState();
}
class TiltCardContentState extends State<TiltCardContent> with SingleTickerProviderStateMixin {
double tiltX = 0.0; // X축 기울기 값
double tiltY = 0.0; // Y축 기울기 값
late AnimationController _animationController; // 애니메이션 컨트롤러
@override
void initState() {
super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 300), // 애니메이션 지속 시간 설정
vsync: this,
);
}
/// 사용자의 터치 위치에 따라 기울기 값 조절
void _onPointerMove(Offset position) {
setState(() {
tiltX = ((position.dy - 200) / 20).clamp(-8.0, 8.0);
tiltY = (-(position.dx - 125) / 20).clamp(-8.0, 8.0);
});
}
/// 손을 떼면 원래 위치로 돌아가는 애니메이션 적용
void _resetTilt() {
_animationController.forward(from: 0.0).then((_) {
setState(() {
tiltX = 0.0;
tiltY = 0.0;
});
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanUpdate: (details) => _onPointerMove(details.localPosition),
onPanEnd: (_) => _resetTilt(),
child: Transform(
transform: Matrix4.identity()
..rotateX(tiltX * (pi / 180))
..rotateY(tiltY * (pi / 180)),
alignment: FractionalOffset.center,
child: Container(
width: 260.w,
height: 350.h,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.r),
color: Colors.white,
),
),
),
);
}
}
이제 터치 입력에 따라 이미지가 부드럽게 기울어지는 카드 효과가 완성되었습니다. 이를 활용해 여러 가지 UI를 만들 수 있습니다.
Flutter를 활용하면 이렇게 간단한 코드로도 생동감 있는 UI를 만들 수 있습니다.
오늘도 다들 즐코 빡코 ~!
'Flutter' 카테고리의 다른 글
Flutter의 렌더링 파이프라인: Build 단계 이해하기 (0) | 2025.02.25 |
---|---|
이미지 크기 조절하기: fast_image_resizer 사용법 (0) | 2025.02.21 |
Flutter 3.29 업데이트 (3) | 2025.02.16 |
Flutter 앱에 Google 광고 넣기 (0) | 2025.02.15 |
Dart 3.7 업데이트! 개발자들을 위한 최신 포맷팅 스타일 총정리 (4) | 2025.02.14 |