GestureViewer Props
enableLoop (기본값: false)
루프 모드를 활성화합니다. true일 때 마지막 아이템에서 다음으로 가면 첫 번째로, 첫 번째에서 이전으로 가면 마지막으로 돌아갑니다.
import { GestureViewer } from 'react-native-gesture-image-viewer';
function App() {
return (
<GestureViewer
data={data}
renderItem={renderItem}
enableLoop={true}
/>
);
}
windowSize (기본값: 3)
현재 아이템을 포함해 내부 render-window slot을 몇 개 마운트할지 제어합니다. 값은 최소 3 이상의 홀수로 정규화됩니다. 예를 들어 4는 5가 됩니다.
하드 최대값은 없습니다. 큰 값은 더 많은 renderItem 콘텐츠를 의도적으로 마운트하므로, 메모리, 렌더링, 이미지 디코딩 비용을 감수하는 명시적인 선택으로 다루세요.
import { GestureViewer } from 'react-native-gesture-image-viewer';
function App() {
return (
<GestureViewer
data={data}
renderItem={renderItem}
windowSize={5}
/>
);
}
pageSpacing (기본값: 0)
페이지 사이의 가로 시각 간격을 설정합니다. 페이지 stride는 width + pageSpacing이며, zoom bounds는 계속 width와 height를 사용합니다.
import { GestureViewer } from 'react-native-gesture-image-viewer';
function App() {
return (
<GestureViewer
data={data}
renderItem={renderItem}
pageSpacing={16}
/>
);
}
horizontalSwipe
사용자가 직접 수행하는 좌우 페이지 스와이프 제스처를 제어합니다. 비활성화해도 controller 이동과 autoplay는 계속 사용할 수 있습니다.
기본값:
enabled: true
distanceThresholdRatio: 뷰어 너비의 0.25
velocityThreshold: 초당 800 points
절대 가로 이동 거리가 width * distanceThresholdRatio보다 엄격히 클 때, 또는 절대 가로 속도가 velocityThreshold보다 엄격히 클 때 페이지가 전환됩니다. 거리와 속도는 엄격한 > OR 조건으로 동작합니다. 0과 모든 유한한 0 이상의 값은 허용되며, 1보다 큰 거리 비율도 허용됩니다. 음수와 유한하지 않은 값은 기본값으로 대체됩니다.
import { GestureViewer } from 'react-native-gesture-image-viewer';
function App() {
return (
<GestureViewer
data={data}
renderItem={renderItem}
horizontalSwipe={{
enabled: true,
distanceThresholdRatio: 0.25,
velocityThreshold: 800,
}}
/>
);
}
사용자/마우스 가로 제스처만 비활성화합니다.
<GestureViewer
data={data}
renderItem={renderItem}
horizontalSwipe={{ enabled: false }}
/>
거리 중심 설정을 사용합니다.
<GestureViewer
data={data}
renderItem={renderItem}
horizontalSwipe={{ distanceThresholdRatio: 0.5, velocityThreshold: 100_000 }}
/>
속도 중심 설정을 사용합니다.
<GestureViewer
data={data}
renderItem={renderItem}
horizontalSwipe={{ distanceThresholdRatio: 10, velocityThreshold: 100 }}
/>
사용자 제스처를 비활성화해도 autoplay는 계속 동작합니다.
<GestureViewer
data={data}
renderItem={renderItem}
horizontalSwipe={{ enabled: false }}
autoPlay={true}
autoPlayInterval={1000}
/>
autoPlay (기본값: false)
자동 재생 모드를 활성화합니다. true일 때 지정된 간격 후 다음 아이템으로 자동으로 재생됩니다.
enableLoop이 활성화되면 마지막 아이템에서 다음으로 가면 첫 번째로, 첫 번째에서 이전으로 가면 마지막으로 돌아갑니다.
enableLoop이 비활성화되면 마지막 아이템에서 정지됩니다.
- 아이템이 하나만 있을 때 자동 재생이 비활성화됩니다.
- 줌 또는 회전 제스처가 감지되면 자동 재생이 일시 중지됩니다.
import { GestureViewer } from 'react-native-gesture-image-viewer';
function App() {
return (
<GestureViewer
data={data}
renderItem={renderItem}
autoPlay={true}
/>
);
}
autoPlayInterval (기본값: 3000)
자동 재생 간격을 밀리초 단위로 설정합니다.
양수 정수여야 합니다. 값이 250ms 미만이면 런타임에서 250ms로 제한됩니다.
import { GestureViewer } from 'react-native-gesture-image-viewer';
function App() {
return (
<GestureViewer
data={data}
renderItem={renderItem}
autoPlay={true}
autoPlayInterval={3000}
/>
);
}
onSingleTap
뷰어에서 싱글 탭이 확정되면 실행됩니다. 헤더, 푸터, 캡션, 액션 버튼처럼 뷰어 컨트롤 UI를 토글할 때 유용하며, 뷰어 위에 별도의 pressable을 덮지 않아도 됩니다.
- 더블 탭 줌이 활성화되어 있으면 더블 탭이 아닌지 확인한 뒤 실행되므로 약간 늦게 호출될 수 있습니다
- 스와이프, 핀치, dismiss, 더블 탭 줌 제스처에서는 호출되지 않습니다
import { GestureViewer } from 'react-native-gesture-image-viewer';
function App() {
const [showControls, setShowControls] = useState(true);
return (
<GestureViewer
data={images}
renderItem={renderImage}
onSingleTap={() => setShowControls((prev) => !prev)}
/>
);
}
initialIndex (기본값: 0)
초기 인덱스 값을 설정할 수 있습니다.
maxZoomScale (기본값: 2)
최대 줌 배율을 제어할 수 있습니다.
GestureViewerProps interface
Go to source
GestureViewerProps
export type GestureViewerRenderItemInfo = {
/**
* 렌더링된 아이템이 현재 활성 상태인지 여부입니다.
* @remarks 페이지 전환 중에는 기존 아이템이 활성 상태를 유지합니다. 전환이 완료되어 다른 아이템으로 이동하면 해당 아이템이 활성화됩니다.
*/
readonly isActive: boolean;
};
export interface GestureViewerProps<ItemT> {
/**
* 여러 개의 `GestureViewer` 인스턴스를 효율적으로 관리하고 싶다면 `id` prop을 사용해 각각의 `GestureViewer`를 구분할 수 있습니다.
* @remarks `GestureViewer`는 컴포넌트가 언마운트되면 인스턴스를 메모리에서 자동으로 제거하므로 별도의 수동 메모리 관리가 필요하지 않습니다.
* @defaultValue 'default'
*/
id?: string;
/**
* `GestureViewer`에 표시할 데이터입니다.
*/
data: ItemT[];
/**
* 컴포넌트가 마운트될 때 `GestureViewer`에 처음 표시할 아이템의 인덱스입니다.
* @defaultValue 0
*/
initialIndex?: number;
/**
* `GestureViewer`가 닫힐 때 호출되는 콜백 함수입니다.
*/
onDismiss?: () => void;
/**
* dismiss 인터랙션이 시작될 때 호출되는 콜백 함수입니다.
* @remarks dismiss 제스처/애니메이션이 진행되는 동안 외부 UI(예: 헤더, 버튼)를 숨길 때 유용합니다.
*/
onDismissStart?: () => void;
/**
* 아이템을 렌더링할 때 호출되는 콜백 함수입니다.
* @param item - 렌더링할 아이템입니다.
* @param index - `data` 배열에서 아이템의 인덱스입니다.
* @param info - 마운트된 이 slot의 렌더링 상태입니다.
*/
renderItem: (item: ItemT, index: number, info: GestureViewerRenderItemInfo) => React.ReactElement;
/**
* 뷰어 콘텐츠에서 싱글 탭이 확정되었을 때 호출되는 콜백 함수입니다.
* @remarks
* - 이 콜백은 탭이 싱글 탭으로 확정된 뒤에만 실행되므로, 더블 탭 줌이 활성화되어 있으면 약간 지연될 수 있습니다.
* - 스와이프, 핀치, dismiss, 더블 탭 줌 제스처에서는 호출되지 않습니다.
* - 전체 화면 탭 처리가 필요하다면 `renderContainer`에서 pressable을 덮어씌우는 대신 이 콜백 사용을 권장합니다.
*/
onSingleTap?: (event: GestureViewerSingleTapEvent<ItemT>) => void;
/**
* 컨테이너를 렌더링할 때 호출되는 콜백 함수입니다.
* @remarks 뷰어 주변에 추가 UI(예: 닫기 버튼, 툴바)를 구성할 때 유용합니다.
* 전체 화면 탭 처리는 뷰어 콘텐츠 위에 pressable을 덮어씌우기보다 `onSingleTap` 사용을 권장합니다.
* 두 번째 인자는 `dismiss()`처럼 뷰어를 닫을 수 있는 제어 헬퍼를 제공합니다.
*
* @param children - 컨테이너 내부에 렌더링할 뷰어 콘텐츠입니다.
* @param helpers - 뷰어 제어 헬퍼입니다. 현재는 `dismiss()`를 포함합니다.
* @returns 전달된 `children`을 감싸서 렌더링하는 React 엘리먼트입니다.
*/
renderContainer?: (
children: React.ReactElement,
helpers: { dismiss: () => void },
) => React.ReactElement;
/**
* `GestureViewer`의 너비입니다.
* @remarks 이 prop을 지정하지 않으면 `GestureViewer`의 너비는 화면 너비와 동일해집니다.
* @defaultValue 화면 너비
*/
width?: number;
/**
* `GestureViewer`의 높이입니다.
* @remarks 이 prop을 지정하지 않으면 `GestureViewer`의 높이는 화면 높이와 동일해집니다.
* @defaultValue 화면 높이
*/
height?: number;
/**
* backdrop의 스타일입니다.
*/
backdropStyle?: StyleProp<ViewStyle>;
/**
* 컨테이너의 스타일입니다.
*/
containerStyle?: StyleProp<ViewStyle>;
/**
* 자동 재생 모드입니다.
* @remarks
* - `true`이면 지정된 간격 후 다음 아이템이 자동으로 재생됩니다.
* - `enableLoop`가 활성화되어 있으면 마지막 아이템 다음에 첫 번째 아이템으로 돌아갑니다.
* - `enableLoop`가 비활성화되어 있으면 마지막 아이템에서 멈춥니다.
* - 아이템이 하나뿐이면 자동 재생은 비활성화됩니다.
* - 줌 또는 회전 제스처가 감지되면 자동 재생이 일시 정지됩니다.
* @defaultValue false
*/
autoPlay?: boolean;
/**
* 자동 재생 간격입니다.
* @remarks
* - `autoPlay`가 활성화되어 있으면 지정된 간격(ms)마다 다음 아이템으로 이동합니다.
* - 양의 정수여야 합니다. 250ms 미만 값은 런타임에서 250ms로 보정됩니다.
* @defaultValue 3000
*/
autoPlayInterval?: number;
/**
* dismiss 제스처 옵션입니다.
* @remarks 위/아래 방향을 선택할 수 있는 수직 스와이프 닫기 제스처에 유용합니다.
*/
dismiss?: {
/**
* `false`이면 dismiss 제스처가 비활성화됩니다.
* @defaultValue true
*/
enabled?: boolean;
/**
* 어떤 수직 스와이프 방향에서 `onDismiss`를 호출할지 설정합니다.
* @remarks 기존 동작과 호환되는 `down`, 위로만 닫는 `up`, 양방향 모두 허용하는 `both`를 사용할 수 있습니다.
* @defaultValue 'down'
*/
direction?: GestureViewerDismissDirection;
/**
* `threshold`는 수직 제스처 중 임계값을 적용해 `onDismiss`가 호출되는 시점을 제어합니다.
* @defaultValue 80
*/
threshold?: number;
/**
* `resistance`는 dismiss 제스처 중 저항을 적용해 수직 이동 범위를 제어합니다.
* @defaultValue 2
*/
resistance?: number;
/**
* 기본적으로 설정된 dismiss 방향으로 드래그하는 동안 배경 `opacity`가 점진적으로 감소합니다.
* @remarks `false`이면 이 애니메이션이 비활성화됩니다.
* @defaultValue true
*/
fadeBackdrop?: boolean;
};
/**
* 가로 스와이프 제스처 옵션입니다.
* @remarks 사용자가 직접 수행하는 좌우 페이지 스와이프 제스처를 제어합니다. 비활성화해도 controller 이동과 autoplay는 계속 사용할 수 있습니다.
*/
horizontalSwipe?: {
/**
* `false`이면 사용자가 직접 수행하는 가로 페이지 스와이프 제스처가 비활성화됩니다.
* @defaultValue true
*/
enabled?: boolean;
/**
* 뷰어 너비에 대한 거리 임계값 비율입니다.
* @remarks 절대 가로 이동 거리가 `width * distanceThresholdRatio`보다 엄격히 클 때, 또는 속도가 `velocityThreshold`를 넘을 때 페이지가 전환됩니다. `0`과 `1`보다 큰 유한한 값은 허용되며, 음수와 유한하지 않은 값은 기본값으로 대체됩니다.
* @defaultValue 0.25
*/
distanceThresholdRatio?: number;
/**
* 초당 points 단위의 가로 속도 임계값입니다.
* @remarks 절대 가로 속도가 `velocityThreshold`보다 엄격히 클 때, 또는 거리가 `distanceThresholdRatio`를 넘을 때 페이지가 전환됩니다. `0`과 모든 유한한 0 이상의 값은 허용되며, 음수와 유한하지 않은 값은 기본값으로 대체됩니다.
* @defaultValue 800
*/
velocityThreshold?: number;
};
/**
* 줌이 활성화된 경우에만 동작하며, 확대된 상태에서 아이템 위치를 이동할 수 있게 합니다.
* @remarks `false`이면 줌 중 제스처 이동이 비활성화됩니다.
* @defaultValue true
*/
enablePanWhenZoomed?: boolean;
/**
* 두 손가락 핀치 제스처를 제어합니다.
* @remarks `false`이면 두 손가락 줌 제스처가 비활성화됩니다.
* @defaultValue true
*/
enablePinchZoom?: boolean;
/**
* 더블 탭 줌 제스처를 제어합니다.
* @remarks `false`이면 더블 탭 줌 제스처가 비활성화됩니다.
* @defaultValue true
*/
enableDoubleTapZoom?: boolean;
/**
* 무한 루프 탐색을 활성화합니다.
* @defaultValue false
*/
enableLoop?: boolean;
/**
* 현재 아이템을 포함해 마운트할 render-window 슬롯 수입니다.
* @remarks 값은 최소 3 이상의 홀수로 정규화됩니다. 예를 들어 `4`는 `5`가 됩니다.
* @defaultValue 3
*/
windowSize?: number;
/**
* 페이지 사이의 가로 시각 간격입니다.
* @remarks 페이지 stride는 `width + pageSpacing`이며, zoom bounds는 계속 `width`와 `height`를 사용합니다.
* @defaultValue 0
*/
pageSpacing?: number;
/**
* 최대 줌 배율입니다.
* @defaultValue 2
*/
maxZoomScale?: number;
/**
* 트리거 기반 애니메이션 설정입니다.
* @remarks 애니메이션 지속 시간, easing, 시스템 reduce-motion 동작을 커스터마이즈할 수 있습니다.
*
* @example
* ```tsx
* <GestureViewer
* triggerAnimation={{
* duration: 250,
* easing: Easing.out(Easing.cubic),
* reduceMotion: 'system',
* onAnimationComplete: () => {
* console.log('애니메이션 완료');
* },
* }}
* />
* ```
*/
triggerAnimation?: TriggerAnimationConfig;
}