Flitter의 제스처 감지
Flitter의 제스처 감지를 사용하면 탭, 드래그, 마우스 이벤트와 같은 다양한 사용자 입력에 반응하여 상호작용하는 사용자 인터페이스를 만들 수 있습니다. GestureDetector 위젯은 이러한 상호작용을 처리하기 위한 포괄적인 API를 제공합니다.
핵심 개념
- 이벤트 유형: 클릭, 드래그, 마우스 이동 등 다양한 제스처 이벤트
- 이벤트 데이터: 제스처에 대한 상세 정보(좌표, 압력 등)
- 전파: 이벤트가 위젯 트리를 통해 흐르는 방식
- 상태 관리: 제스처 상태와 업데이트 처리
기본 사용법
간단한 클릭 감지:
import { GestureDetector, Container } from "@meursyphus/flitter";
const clickableContainer = GestureDetector({
onClick: (e) => {
console.log("클릭된 위치:", e.clientX, e.clientY);
},
child: Container({
width: 200,
height: 200,
color: "blue",
}),
});
제스처 유형
클릭/탭 이벤트
GestureDetector({
onClick: (e) => {
console.log("단일 클릭");
},
onDoubleClick: (e) => {
console.log("더블 클릭");
},
child: /* 위젯 */,
});
드래그 이벤트
GestureDetector({
onDragStart: (e) => {
console.log("드래그 시작");
},
onDragUpdate: (e) => {
console.log("드래그 위치:", e.clientX, e.clientY);
console.log("이동 거리:", e.delta.x, e.delta.y);
},
onDragEnd: (e) => {
console.log("드래그 완료");
},
child: /* 위젯 */,
});
마우스 이벤트
GestureDetector({
onMouseEnter: (e) => {
console.log("마우스 진입");
},
onMouseMove: (e) => {
console.log("마우스 위치:", e.clientX, e.clientY);
},
onMouseLeave: (e) => {
console.log("마우스 이탈");
},
child: /* 위젯 */,
});
고급 사용법
여러 제스처 결합하기
import { GestureDetector, Container, useState } from "@meursyphus/flitter";
function InteractiveBox() {
const [position, setPosition] = useState({ x: 0, y: 0 });
const [isHovered, setIsHovered] = useState(false);
return GestureDetector({
onDragUpdate: (e) => {
setPosition({
x: position.x + e.delta.x,
y: position.y + e.delta.y,
});
},
onMouseEnter: () => setIsHovered(true),
onMouseLeave: () => setIsHovered(false),
child: Container({
width: 100,
height: 100,
offset: position,
color: isHovered ? "red" : "blue",
}),
});
}
사용자 정의 제스처 인식
사용자 정의 길게 누르기 감지기 만들기:
function LongPressDetector({ onLongPress, child }) {
let pressTimer;
return GestureDetector({
onPointerDown: () => {
pressTimer = setTimeout(onLongPress, 500);
},
onPointerUp: () => {
clearTimeout(pressTimer);
},
onPointerCancel: () => {
clearTimeout(pressTimer);
},
child,
});
}
모범 사례
-
이벤트 처리:
- 이벤트 핸들러를 작고 집중적으로 유지
- 핸들러에서 비용이 많이 드는 작업 피하기
- 빈번한 이벤트에 대한 디바운싱 고려
-
사용자 경험:
- 상호작용에 대한 시각적 피드백 제공
- 일관된 동작 유지
- 터치와 마우스 상호작용 고려
-
성능:
- 적절한 이벤트 유형 사용
- 드래그 핸들러 최적화
- 이벤트 리스너 정리
-
접근성:
- 키보드 네비게이션 지원
- 대체 상호작용 제공
- 다양한 능력을 가진 사용자 고려
일반적인 패턴
드래그 가능한 위젯
function DraggableWidget({ child }) {
const [position, setPosition] = useState({ x: 0, y: 0 });
return GestureDetector({
onDragUpdate: (e) => {
setPosition({
x: position.x + e.delta.x,
y: position.y + e.delta.y,
});
},
child: Container({
offset: position,
child,
}),
});
}
상호작용 버튼
function InteractiveButton({ onPress, child }) {
const [isPressed, setIsPressed] = useState(false);
return GestureDetector({
onPointerDown: () => setIsPressed(true),
onPointerUp: () => {
setIsPressed(false);
onPress();
},
onPointerCancel: () => setIsPressed(false),
child: Container({
scale: isPressed ? 0.95 : 1,
child,
}),
});
}
문제 해결
이벤트 전파
이벤트 전파를 올바르게 처리하기:
GestureDetector({
onClick: (e) => {
e.stopPropagation(); // 이벤트가 상위로 전파되는 것을 방지
// 클릭 처리
},
child: /* 위젯 */,
});
제스처 충돌
서로 다른 제스처 핸들러 간의 충돌 해결:
Stack({
children: [
// 배경 핸들러
GestureDetector({
onClick: (e) => {
// 자식에 의해 처리되지 않은 경우에만 처리
if (!e.defaultPrevented) {
handleBackgroundClick();
}
},
child: Container({
/* ... */
}),
}),
// 전경 핸들러
GestureDetector({
onClick: (e) => {
e.preventDefault(); // 배경 처리 방지
handleForegroundClick();
},
child: Container({
/* ... */
}),
}),
],
});
결론
제스처 감지는 상호작용하는 Flitter 애플리케이션을 만드는 데 기본이 됩니다. GestureDetector 위젯은 사용자 상호작용을 처리하기 위한 풍부한 API를 제공하여 반응이 빠르고 매력적인 사용자 인터페이스를 만들 수 있게 해줍니다. 데스크톱과 모바일 상호작용을 모두 고려하고, 일관된 동작을 유지하며, 부드러운 사용자 경험을 위해 성능을 최적화하는 것을 잊지 마세요.