Flitter의 제스처 감지

Flitter의 제스처 감지를 사용하면 탭, 드래그, 마우스 이벤트와 같은 다양한 사용자 입력에 반응하여 상호작용하는 사용자 인터페이스를 만들 수 있습니다. GestureDetector 위젯은 이러한 상호작용을 처리하기 위한 포괄적인 API를 제공합니다.

핵심 개념

  1. 이벤트 유형: 클릭, 드래그, 마우스 이동 등 다양한 제스처 이벤트
  2. 이벤트 데이터: 제스처에 대한 상세 정보(좌표, 압력 등)
  3. 전파: 이벤트가 위젯 트리를 통해 흐르는 방식
  4. 상태 관리: 제스처 상태와 업데이트 처리

기본 사용법

간단한 클릭 감지:

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,
  });
}

모범 사례

  1. 이벤트 처리:

    • 이벤트 핸들러를 작고 집중적으로 유지
    • 핸들러에서 비용이 많이 드는 작업 피하기
    • 빈번한 이벤트에 대한 디바운싱 고려
  2. 사용자 경험:

    • 상호작용에 대한 시각적 피드백 제공
    • 일관된 동작 유지
    • 터치와 마우스 상호작용 고려
  3. 성능:

    • 적절한 이벤트 유형 사용
    • 드래그 핸들러 최적화
    • 이벤트 리스너 정리
  4. 접근성:

    • 키보드 네비게이션 지원
    • 대체 상호작용 제공
    • 다양한 능력을 가진 사용자 고려

일반적인 패턴

드래그 가능한 위젯

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를 제공하여 반응이 빠르고 매력적인 사용자 인터페이스를 만들 수 있게 해줍니다. 데스크톱과 모바일 상호작용을 모두 고려하고, 일관된 동작을 유지하며, 부드러운 사용자 경험을 위해 성능을 최적화하는 것을 잊지 마세요.