react-native-gesture-image-viewer 1.5.1 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/lib/module/GestureViewer.js +21 -9
- package/lib/module/GestureViewer.js.map +1 -1
- package/lib/module/GestureViewerManager.js +63 -24
- package/lib/module/GestureViewerManager.js.map +1 -1
- package/lib/module/useGestureViewer.js +38 -20
- package/lib/module/useGestureViewer.js.map +1 -1
- package/lib/module/utils.js +52 -0
- package/lib/module/utils.js.map +1 -1
- package/lib/typescript/src/GestureViewer.d.ts +1 -1
- package/lib/typescript/src/GestureViewer.d.ts.map +1 -1
- package/lib/typescript/src/GestureViewerManager.d.ts +10 -4
- package/lib/typescript/src/GestureViewerManager.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +5 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewer.d.ts +2 -1
- package/lib/typescript/src/useGestureViewer.d.ts.map +1 -1
- package/lib/typescript/src/utils.d.ts +9 -0
- package/lib/typescript/src/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/GestureViewer.tsx +47 -31
- package/src/GestureViewerManager.ts +77 -19
- package/src/types.ts +5 -0
- package/src/useGestureViewer.ts +47 -18
- package/src/utils.ts +53 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GestureViewer.d.ts","sourceRoot":"","sources":["../../../src/GestureViewer.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAyE,MAAM,cAAc,CAAC;AAIpH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAKlD,wBAAgB,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,OAAO,QAAQ,EAAE,EAC3D,EAAc,EACd,IAAI,EACJ,UAAU,EAAE,cAAc,EAC1B,eAAe,EACf,aAAa,EACb,KAAK,EAAE,WAAW,EAClB,SAAS,EACT,aAAa,EAAE,kBAAkB,EACjC,cAAc,EACd,YAAgB,EAChB,WAAe,EACf,OAAe,EACf,GAAG,KAAK,EACT,EAAE,kBAAkB,CAAC,CAAC,EAAE,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"GestureViewer.d.ts","sourceRoot":"","sources":["../../../src/GestureViewer.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAyE,MAAM,cAAc,CAAC;AAIpH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAKlD,wBAAgB,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,OAAO,QAAQ,EAAE,EAC3D,EAAc,EACd,IAAI,EACJ,UAAU,EAAE,cAAc,EAC1B,eAAe,EACf,aAAa,EACb,KAAK,EAAE,WAAW,EAClB,SAAS,EACT,aAAa,EAAE,kBAAkB,EACjC,cAAc,EACd,YAAgB,EAChB,WAAe,EACf,OAAe,EACf,UAAkB,EAClB,GAAG,KAAK,EACT,EAAE,kBAAkB,CAAC,CAAC,EAAE,EAAE,CAAC,2CAsJ3B"}
|
|
@@ -5,14 +5,16 @@ declare class GestureViewerManager {
|
|
|
5
5
|
private dataLength;
|
|
6
6
|
private width;
|
|
7
7
|
private height;
|
|
8
|
+
private maxZoomScale;
|
|
9
|
+
private enableSwipeGesture;
|
|
10
|
+
private enableLoop;
|
|
11
|
+
private listRef;
|
|
8
12
|
private scale;
|
|
13
|
+
private rotation;
|
|
9
14
|
private translateX;
|
|
10
15
|
private translateY;
|
|
11
|
-
private
|
|
12
|
-
private listRef;
|
|
13
|
-
private enableSwipeGesture;
|
|
16
|
+
private loopCallback;
|
|
14
17
|
private listeners;
|
|
15
|
-
private rotation;
|
|
16
18
|
private eventListeners;
|
|
17
19
|
private notifyListeners;
|
|
18
20
|
subscribe(listener: (state: GestureViewerControllerState) => void): () => void;
|
|
@@ -24,6 +26,7 @@ declare class GestureViewerManager {
|
|
|
24
26
|
currentIndex: number;
|
|
25
27
|
totalCount: number;
|
|
26
28
|
};
|
|
29
|
+
setEnableLoop(enabled: boolean): void;
|
|
27
30
|
setWidth(width: number): void;
|
|
28
31
|
setHeight(height: number): void;
|
|
29
32
|
setListRef(ref: any): void;
|
|
@@ -38,9 +41,12 @@ declare class GestureViewerManager {
|
|
|
38
41
|
zoomOut: (multiplier?: number) => void;
|
|
39
42
|
resetZoom: (scale?: number) => void;
|
|
40
43
|
goToIndex: (index: number) => void;
|
|
44
|
+
handleMomentumScrollEnd: (scrollIndex: number) => boolean;
|
|
45
|
+
handleScrollBeginDrag: () => void;
|
|
41
46
|
goToPrevious: () => void;
|
|
42
47
|
goToNext: () => void;
|
|
43
48
|
cleanUp(): void;
|
|
49
|
+
private updateCurrentIndex;
|
|
44
50
|
}
|
|
45
51
|
export default GestureViewerManager;
|
|
46
52
|
//# sourceMappingURL=GestureViewerManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GestureViewerManager.d.ts","sourceRoot":"","sources":["../../../src/GestureViewerManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EACV,4BAA4B,EAC5B,0BAA0B,EAE1B,sBAAsB,EACvB,MAAM,SAAS,CAAC;AAGjB,cAAM,oBAAoB;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"GestureViewerManager.d.ts","sourceRoot":"","sources":["../../../src/GestureViewerManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EACV,4BAA4B,EAC5B,0BAA0B,EAE1B,sBAAsB,EACvB,MAAM,SAAS,CAAC;AAGjB,cAAM,oBAAoB;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAoB;IAEnC,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,QAAQ,CAAoC;IACpD,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,UAAU,CAAoC;IAEtD,OAAO,CAAC,YAAY,CAA6B;IAEjD,OAAO,CAAC,SAAS,CAA4D;IAC7E,OAAO,CAAC,cAAc,CAA+D;IAErF,OAAO,CAAC,eAAe;IAMvB,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,IAAI;IAQjE,gBAAgB,CAAC,CAAC,SAAS,sBAAsB,EAAE,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,0BAA0B,CAAC,CAAC,CAAC;IAoBxG,OAAO,CAAC,SAAS;IAQjB,cAAc,GAAI,OAAO,MAAM,EAAE,eAAe,MAAM,GAAG,IAAI,UAE3D;IAEF,kBAAkB,GAAI,UAAU,MAAM,EAAE,kBAAkB,MAAM,GAAG,IAAI,UAErE;IAEF,QAAQ;;;;IAOR,aAAa,CAAC,OAAO,EAAE,OAAO;IAI9B,QAAQ,CAAC,KAAK,EAAE,MAAM;IAItB,SAAS,CAAC,MAAM,EAAE,MAAM;IAIxB,UAAU,CAAC,GAAG,EAAE,GAAG;IAInB,aAAa,CAAC,MAAM,EAAE,MAAM;IAI5B,qBAAqB,CAAC,OAAO,EAAE,OAAO;IAItC,eAAe,CAAC,KAAK,EAAE,MAAM;IAM7B,mBAAmB,CACjB,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAC1B,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,EAC/B,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,EAC/B,YAAY,EAAE,MAAM;IAQtB,iBAAiB;IAIjB,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC;IAIzC,MAAM,GAAI,QAAO,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAQ,EAAE,mBAAgB,UA2B9D;IAEF,MAAM,GAAI,mBAAiB,UAoBzB;IAEF,OAAO,GAAI,mBAAiB,UA0B1B;IAEF,SAAS,GAAI,cAAS,UAQpB;IAEF,SAAS,GAAI,OAAO,MAAM,UA4CxB;IAEF,uBAAuB,GAAI,aAAa,MAAM,aAY5C;IAEF,qBAAqB,aAEnB;IAEF,YAAY,aAEV;IAEF,QAAQ,aAEN;IAEF,OAAO;IAeP,OAAO,CAAC,kBAAkB,CAGxB;CACH;AAED,eAAe,oBAAoB,CAAC"}
|
|
@@ -120,6 +120,11 @@ export interface GestureViewerProps<T = any, LC = typeof RNFlatList> {
|
|
|
120
120
|
* @defaultValue true
|
|
121
121
|
*/
|
|
122
122
|
enableDoubleTapGesture?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Enables infinite loop navigation.
|
|
125
|
+
* @defaultValue false
|
|
126
|
+
*/
|
|
127
|
+
enableLoop?: boolean;
|
|
123
128
|
/**
|
|
124
129
|
* The maximum zoom scale.
|
|
125
130
|
* @defaultValue 2
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type NativeScrollEvent, type NativeSyntheticEvent } from 'react-native';
|
|
2
2
|
import type { GestureViewerProps } from './types';
|
|
3
3
|
type UseGestureViewerProps<T = any> = Omit<GestureViewerProps<T>, 'renderItem' | 'renderContainer' | 'ListComponent' | 'listProps' | 'containerStyle' | 'backdropStyle'>;
|
|
4
|
-
export declare const useGestureViewer: <T = any>({ data, initialIndex, onIndexChange, onDismiss, width: customWidth, dismissThreshold, resistance, animateBackdrop, enableDismissGesture, enableSwipeGesture, enableZoomGesture, enableDoubleTapGesture, enableZoomPanGesture, maxZoomScale, itemSpacing, useSnap, id, }: UseGestureViewerProps<T>) => {
|
|
4
|
+
export declare const useGestureViewer: <T = any>({ data, initialIndex, onIndexChange, onDismiss, width: customWidth, dismissThreshold, resistance, animateBackdrop, enableDismissGesture, enableSwipeGesture, enableZoomGesture, enableDoubleTapGesture, enableZoomPanGesture, enableLoop, maxZoomScale, itemSpacing, useSnap, id, }: UseGestureViewerProps<T>) => {
|
|
5
5
|
currentIndex: number;
|
|
6
6
|
dataLength: number;
|
|
7
7
|
translateY: import("react-native-reanimated").SharedValue<number>;
|
|
@@ -11,6 +11,7 @@ export declare const useGestureViewer: <T = any>({ data, initialIndex, onIndexCh
|
|
|
11
11
|
dismissGesture: import("react-native-gesture-handler/lib/typescript/handlers/gestures/panGesture").PanGesture;
|
|
12
12
|
zoomGesture: import("react-native-gesture-handler/lib/typescript/handlers/gestures/gestureComposition").ComposedGesture;
|
|
13
13
|
onMomentumScrollEnd: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
|
|
14
|
+
onScrollBeginDrag: () => void;
|
|
14
15
|
animatedStyle: {
|
|
15
16
|
transform: ({
|
|
16
17
|
translateY: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGestureViewer.d.ts","sourceRoot":"","sources":["../../../src/useGestureViewer.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAE1B,MAAM,cAAc,CAAC;AActB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGlD,KAAK,qBAAqB,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,CACxC,kBAAkB,CAAC,CAAC,CAAC,EACrB,YAAY,GAAG,iBAAiB,GAAG,eAAe,GAAG,WAAW,GAAG,gBAAgB,GAAG,eAAe,CACtG,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,CAAC,GAAG,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"useGestureViewer.d.ts","sourceRoot":"","sources":["../../../src/useGestureViewer.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAE1B,MAAM,cAAc,CAAC;AActB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGlD,KAAK,qBAAqB,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,CACxC,kBAAkB,CAAC,CAAC,CAAC,EACrB,YAAY,GAAG,iBAAiB,GAAG,eAAe,GAAG,WAAW,GAAG,gBAAgB,GAAG,eAAe,CACtG,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,CAAC,GAAG,GAAG,EAAE,qRAqBvC,qBAAqB,CAAC,CAAC,CAAC;;;;;;;;;iCA6Kf,oBAAoB,CAAC,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+RlD,CAAC"}
|
|
@@ -13,4 +13,13 @@ export declare const createBoundsConstraint: ({ width, height }: {
|
|
|
13
13
|
translateX: number;
|
|
14
14
|
translateY: number;
|
|
15
15
|
};
|
|
16
|
+
export declare const createLoopData: <T>(dataRef: React.RefObject<T[]>, enableLoop: boolean) => T[];
|
|
17
|
+
export declare const getLoopAdjustedIndex: (scrollIndex: number, originalDataLength: number, enableLoop: boolean) => {
|
|
18
|
+
realIndex: number;
|
|
19
|
+
needsJump: boolean;
|
|
20
|
+
jumpToIndex?: number;
|
|
21
|
+
};
|
|
22
|
+
export declare const createScrollAction: (listRef: any, width: number) => {
|
|
23
|
+
scrollTo: (index: number, animated: boolean) => void;
|
|
24
|
+
};
|
|
16
25
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEtE,eAAO,MAAM,gBAAgB,GAAI,WAAW,GAAG,KAAG,SAAS,IAAI,mBAE9D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,WAAW,GAAG,KAAG,SAAS,IAAI,iBAM5D,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,WAAW,GAAG,KAAG,SAAS,IAAI,GAY7D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAChC,mBAAmB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,MACpD,mCAAmC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;;;CAiB5F,CAAC"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEtE,eAAO,MAAM,gBAAgB,GAAI,WAAW,GAAG,KAAG,SAAS,IAAI,mBAE9D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,WAAW,GAAG,KAAG,SAAS,IAAI,iBAM5D,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,WAAW,GAAG,KAAG,SAAS,IAAI,GAY7D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAChC,mBAAmB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,MACpD,mCAAmC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;;;CAiB5F,CAAC;AAEJ,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,SAAS,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,YAAY,OAAO,KAAG,CAAC,EAevF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,aAAa,MAAM,EACnB,oBAAoB,MAAM,EAC1B,YAAY,OAAO,KAClB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAoB/D,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,SAAS,GAAG,EAAE,OAAO,MAAM;sBAC1C,MAAM,YAAY,OAAO;CAO3C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-gesture-image-viewer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "🖼️ A highly customizable and easy-to-use React Native image viewer with gesture support and external controls",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
package/src/GestureViewer.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo } from 'react';
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
import { type FlatList, Platform, type ScrollViewProps, StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
3
3
|
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
4
4
|
import Animated from 'react-native-reanimated';
|
|
5
5
|
import { registry } from './GestureViewerRegistry';
|
|
6
6
|
import type { GestureViewerProps } from './types';
|
|
7
7
|
import { useGestureViewer } from './useGestureViewer';
|
|
8
|
-
import { isFlashListLike, isFlatListLike, isScrollViewLike } from './utils';
|
|
8
|
+
import { createLoopData, isFlashListLike, isFlatListLike, isScrollViewLike } from './utils';
|
|
9
9
|
import WebPagingFixStyle from './WebPagingFixStyle';
|
|
10
10
|
|
|
11
11
|
export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
@@ -21,14 +21,20 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
21
21
|
initialIndex = 0,
|
|
22
22
|
itemSpacing = 0,
|
|
23
23
|
useSnap = false,
|
|
24
|
+
enableLoop = false,
|
|
24
25
|
...props
|
|
25
26
|
}: GestureViewerProps<T, LC>) {
|
|
26
27
|
const Component = ListComponent as React.ComponentType<any>;
|
|
27
28
|
|
|
29
|
+
const dataRef = useRef(data);
|
|
30
|
+
dataRef.current = data;
|
|
31
|
+
|
|
28
32
|
const { width: screenWidth } = useWindowDimensions();
|
|
29
33
|
|
|
30
34
|
const width = useSnap ? customWidth || screenWidth : screenWidth;
|
|
31
35
|
|
|
36
|
+
const loopData = useMemo(() => createLoopData(dataRef, enableLoop), [enableLoop]);
|
|
37
|
+
|
|
32
38
|
const {
|
|
33
39
|
listRef,
|
|
34
40
|
isZoomed,
|
|
@@ -36,6 +42,7 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
36
42
|
dismissGesture,
|
|
37
43
|
zoomGesture,
|
|
38
44
|
onMomentumScrollEnd,
|
|
45
|
+
onScrollBeginDrag,
|
|
39
46
|
animatedStyle,
|
|
40
47
|
backdropStyle,
|
|
41
48
|
} = useGestureViewer({
|
|
@@ -45,14 +52,26 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
45
52
|
initialIndex,
|
|
46
53
|
itemSpacing,
|
|
47
54
|
useSnap,
|
|
55
|
+
enableLoop,
|
|
48
56
|
...props,
|
|
49
57
|
});
|
|
50
58
|
|
|
59
|
+
const keyExtractor = useCallback(
|
|
60
|
+
(item: T, index: number) => {
|
|
61
|
+
if (enableLoop) {
|
|
62
|
+
return typeof item === 'string' ? `${item}-${index}` : `item-${index}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return typeof item === 'string' ? item : `image-${index}`;
|
|
66
|
+
},
|
|
67
|
+
[enableLoop],
|
|
68
|
+
);
|
|
69
|
+
|
|
51
70
|
const renderItem = useCallback(
|
|
52
71
|
({ item, index }: { item: T; index: number }) => {
|
|
53
72
|
return (
|
|
54
73
|
<View
|
|
55
|
-
key={
|
|
74
|
+
key={keyExtractor(item, index)}
|
|
56
75
|
style={[
|
|
57
76
|
{
|
|
58
77
|
width,
|
|
@@ -67,7 +86,7 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
67
86
|
</View>
|
|
68
87
|
);
|
|
69
88
|
},
|
|
70
|
-
[width, itemSpacing, renderItemProp],
|
|
89
|
+
[width, itemSpacing, renderItemProp, keyExtractor],
|
|
71
90
|
);
|
|
72
91
|
|
|
73
92
|
const getItemLayout = useCallback(
|
|
@@ -79,11 +98,6 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
79
98
|
[width, itemSpacing],
|
|
80
99
|
);
|
|
81
100
|
|
|
82
|
-
const keyExtractor = useCallback(
|
|
83
|
-
(item: T, index: number) => (typeof item === 'string' ? item : `image-${index}`),
|
|
84
|
-
[],
|
|
85
|
-
);
|
|
86
|
-
|
|
87
101
|
const gesture = useMemo(() => {
|
|
88
102
|
return Gesture.Race(dismissGesture, zoomGesture);
|
|
89
103
|
}, [zoomGesture, dismissGesture]);
|
|
@@ -94,25 +108,27 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
94
108
|
return () => registry.deleteManager(id);
|
|
95
109
|
}, [id]);
|
|
96
110
|
|
|
97
|
-
const commonProps
|
|
98
|
-
() =>
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
const commonProps = useMemo(
|
|
112
|
+
() =>
|
|
113
|
+
({
|
|
114
|
+
horizontal: true,
|
|
115
|
+
scrollEnabled: !isZoomed && !isRotated,
|
|
116
|
+
showsHorizontalScrollIndicator: false,
|
|
117
|
+
onMomentumScrollEnd: onMomentumScrollEnd,
|
|
118
|
+
onScrollBeginDrag,
|
|
119
|
+
...(useSnap
|
|
120
|
+
? {
|
|
121
|
+
snapToInterval: width + itemSpacing,
|
|
122
|
+
snapToAlignment: 'center',
|
|
123
|
+
decelerationRate: 'fast',
|
|
124
|
+
}
|
|
125
|
+
: {
|
|
126
|
+
pagingEnabled: true,
|
|
127
|
+
}),
|
|
128
|
+
scrollEventThrottle: 16,
|
|
129
|
+
removeClippedSubviews: true,
|
|
130
|
+
}) satisfies ScrollViewProps,
|
|
131
|
+
[width, itemSpacing, isZoomed, isRotated, onMomentumScrollEnd, onScrollBeginDrag, useSnap],
|
|
116
132
|
);
|
|
117
133
|
|
|
118
134
|
const listComponent = (
|
|
@@ -127,16 +143,16 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
127
143
|
>
|
|
128
144
|
{isScrollViewLike(Component) ? (
|
|
129
145
|
<Component ref={listRef} {...commonProps} {...listProps}>
|
|
130
|
-
{
|
|
146
|
+
{loopData.map((item, index) => renderItem({ item, index }))}
|
|
131
147
|
</Component>
|
|
132
148
|
) : (
|
|
133
149
|
isFlatListLike(Component) && (
|
|
134
150
|
<Component
|
|
135
151
|
ref={listRef}
|
|
136
152
|
{...commonProps}
|
|
137
|
-
data={
|
|
153
|
+
data={loopData}
|
|
138
154
|
renderItem={renderItem}
|
|
139
|
-
initialScrollIndex={initialIndex}
|
|
155
|
+
initialScrollIndex={enableLoop && data.length > 1 ? initialIndex + 1 : initialIndex}
|
|
140
156
|
keyExtractor={keyExtractor}
|
|
141
157
|
windowSize={3}
|
|
142
158
|
maxToRenderPerBatch={3}
|
|
@@ -5,21 +5,26 @@ import type {
|
|
|
5
5
|
GestureViewerEventData,
|
|
6
6
|
GestureViewerEventType,
|
|
7
7
|
} from './types';
|
|
8
|
-
import { createBoundsConstraint } from './utils';
|
|
8
|
+
import { createBoundsConstraint, createScrollAction } from './utils';
|
|
9
9
|
|
|
10
10
|
class GestureViewerManager {
|
|
11
11
|
private currentIndex = 0;
|
|
12
12
|
private dataLength = 0;
|
|
13
13
|
private width = 0;
|
|
14
14
|
private height = 0;
|
|
15
|
+
private maxZoomScale = 2;
|
|
16
|
+
private enableSwipeGesture = true;
|
|
17
|
+
private enableLoop = false;
|
|
18
|
+
private listRef: any | null = null;
|
|
19
|
+
|
|
15
20
|
private scale: SharedValue<number> | null = null;
|
|
21
|
+
private rotation: SharedValue<number> | null = null;
|
|
16
22
|
private translateX: SharedValue<number> | null = null;
|
|
17
23
|
private translateY: SharedValue<number> | null = null;
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
24
|
+
|
|
25
|
+
private loopCallback: (() => void) | null = null;
|
|
26
|
+
|
|
21
27
|
private listeners = new Set<(state: GestureViewerControllerState) => void>();
|
|
22
|
-
private rotation: SharedValue<number> | null = null;
|
|
23
28
|
private eventListeners = new Map<GestureViewerEventType, Set<(data: any) => void>>();
|
|
24
29
|
|
|
25
30
|
private notifyListeners() {
|
|
@@ -79,6 +84,10 @@ class GestureViewerManager {
|
|
|
79
84
|
};
|
|
80
85
|
}
|
|
81
86
|
|
|
87
|
+
setEnableLoop(enabled: boolean) {
|
|
88
|
+
this.enableLoop = enabled;
|
|
89
|
+
}
|
|
90
|
+
|
|
82
91
|
setWidth(width: number) {
|
|
83
92
|
this.width = width;
|
|
84
93
|
}
|
|
@@ -215,40 +224,84 @@ class GestureViewerManager {
|
|
|
215
224
|
};
|
|
216
225
|
|
|
217
226
|
goToIndex = (index: number) => {
|
|
218
|
-
if (
|
|
227
|
+
if (!this.enableSwipeGesture || !this.listRef) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
this.loopCallback = null;
|
|
232
|
+
|
|
233
|
+
const { scrollTo } = createScrollAction(this.listRef, this.width);
|
|
234
|
+
|
|
235
|
+
if (this.enableLoop && this.dataLength > 1) {
|
|
236
|
+
if (index < 0) {
|
|
237
|
+
this.loopCallback = () => {
|
|
238
|
+
scrollTo(this.dataLength, false);
|
|
239
|
+
this.updateCurrentIndex(this.dataLength - 1);
|
|
240
|
+
this.loopCallback = null;
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
scrollTo(0, true);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (index >= this.dataLength) {
|
|
248
|
+
this.loopCallback = () => {
|
|
249
|
+
scrollTo(1, false);
|
|
250
|
+
this.updateCurrentIndex(0);
|
|
251
|
+
this.loopCallback = null;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
scrollTo(this.dataLength + 1, true);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
scrollTo(index + 1, true);
|
|
259
|
+
this.updateCurrentIndex(index);
|
|
260
|
+
|
|
219
261
|
return;
|
|
220
262
|
}
|
|
221
263
|
|
|
222
|
-
this.
|
|
264
|
+
if (index < 0 || index >= this.dataLength) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
223
267
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
268
|
+
scrollTo(index, true);
|
|
269
|
+
this.updateCurrentIndex(index);
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
handleMomentumScrollEnd = (scrollIndex: number) => {
|
|
273
|
+
if (!this.loopCallback) {
|
|
274
|
+
return false;
|
|
228
275
|
}
|
|
229
276
|
|
|
230
|
-
this.
|
|
277
|
+
if (scrollIndex === 0 || scrollIndex === this.dataLength + 1) {
|
|
278
|
+
this.loopCallback();
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
this.loopCallback = null;
|
|
283
|
+
return true;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
handleScrollBeginDrag = () => {
|
|
287
|
+
this.loopCallback = null;
|
|
231
288
|
};
|
|
232
289
|
|
|
233
290
|
goToPrevious = () => {
|
|
234
|
-
|
|
235
|
-
this.goToIndex(this.currentIndex - 1);
|
|
236
|
-
}
|
|
291
|
+
this.goToIndex(this.currentIndex - 1);
|
|
237
292
|
};
|
|
238
293
|
|
|
239
294
|
goToNext = () => {
|
|
240
|
-
|
|
241
|
-
this.goToIndex(this.currentIndex + 1);
|
|
242
|
-
}
|
|
295
|
+
this.goToIndex(this.currentIndex + 1);
|
|
243
296
|
};
|
|
244
297
|
|
|
245
298
|
cleanUp() {
|
|
299
|
+
this.loopCallback = null;
|
|
246
300
|
this.listeners.clear();
|
|
247
301
|
this.listRef = null;
|
|
248
302
|
this.enableSwipeGesture = true;
|
|
249
303
|
this.currentIndex = 0;
|
|
250
304
|
this.dataLength = 0;
|
|
251
|
-
|
|
252
305
|
this.maxZoomScale = 2;
|
|
253
306
|
this.scale = null;
|
|
254
307
|
this.translateX = null;
|
|
@@ -256,6 +309,11 @@ class GestureViewerManager {
|
|
|
256
309
|
this.rotation = null;
|
|
257
310
|
this.eventListeners.clear();
|
|
258
311
|
}
|
|
312
|
+
|
|
313
|
+
private updateCurrentIndex = (targetIndex: number) => {
|
|
314
|
+
this.currentIndex = targetIndex;
|
|
315
|
+
this.notifyListeners();
|
|
316
|
+
};
|
|
259
317
|
}
|
|
260
318
|
|
|
261
319
|
export default GestureViewerManager;
|
package/src/types.ts
CHANGED
|
@@ -130,6 +130,11 @@ export interface GestureViewerProps<T = any, LC = typeof RNFlatList> {
|
|
|
130
130
|
* @defaultValue true
|
|
131
131
|
*/
|
|
132
132
|
enableDoubleTapGesture?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Enables infinite loop navigation.
|
|
135
|
+
* @defaultValue false
|
|
136
|
+
*/
|
|
137
|
+
enableLoop?: boolean;
|
|
133
138
|
/**
|
|
134
139
|
* The maximum zoom scale.
|
|
135
140
|
* @defaultValue 2
|
package/src/useGestureViewer.ts
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import type GestureViewerManager from './GestureViewerManager';
|
|
20
20
|
import { registry } from './GestureViewerRegistry';
|
|
21
21
|
import type { GestureViewerProps } from './types';
|
|
22
|
-
import { createBoundsConstraint } from './utils';
|
|
22
|
+
import { createBoundsConstraint, createScrollAction, getLoopAdjustedIndex } from './utils';
|
|
23
23
|
|
|
24
24
|
type UseGestureViewerProps<T = any> = Omit<
|
|
25
25
|
GestureViewerProps<T>,
|
|
@@ -42,6 +42,7 @@ export const useGestureViewer = <T = any>({
|
|
|
42
42
|
enableZoomGesture = true,
|
|
43
43
|
enableDoubleTapGesture = true,
|
|
44
44
|
enableZoomPanGesture = true,
|
|
45
|
+
enableLoop = false,
|
|
45
46
|
maxZoomScale = 2,
|
|
46
47
|
itemSpacing = 0,
|
|
47
48
|
useSnap = false,
|
|
@@ -71,11 +72,28 @@ export const useGestureViewer = <T = any>({
|
|
|
71
72
|
|
|
72
73
|
const dataLength = data?.length || 0;
|
|
73
74
|
|
|
75
|
+
const adjustedInitialIndex = useMemo(() => {
|
|
76
|
+
if (enableLoop && data.length > 1) {
|
|
77
|
+
return initialIndex + 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return initialIndex;
|
|
81
|
+
}, [enableLoop, data.length, initialIndex]);
|
|
82
|
+
|
|
74
83
|
const constrainTranslation = useMemo(
|
|
75
84
|
() => createBoundsConstraint({ width, height: screenHeight }),
|
|
76
85
|
[width, screenHeight],
|
|
77
86
|
);
|
|
78
87
|
|
|
88
|
+
const scrollTo = useCallback(
|
|
89
|
+
(index: number, animated: boolean) => {
|
|
90
|
+
const scrollAction = createScrollAction(listRef.current, width + itemSpacing);
|
|
91
|
+
|
|
92
|
+
return scrollAction.scrollTo(index, animated);
|
|
93
|
+
},
|
|
94
|
+
[width, itemSpacing],
|
|
95
|
+
);
|
|
96
|
+
|
|
79
97
|
const emitZoomChange = useCallback(
|
|
80
98
|
(currentScale: number, prevScale: number | null) => {
|
|
81
99
|
manager?.emitZoomChange(currentScale, prevScale);
|
|
@@ -150,6 +168,7 @@ export const useGestureViewer = <T = any>({
|
|
|
150
168
|
manager.setHeight(screenHeight);
|
|
151
169
|
manager.setZoomSharedValues(scale, translateX, translateY, maxZoomScale);
|
|
152
170
|
manager.setRotation(rotation);
|
|
171
|
+
manager.setEnableLoop(enableLoop);
|
|
153
172
|
manager.notifyStateChange();
|
|
154
173
|
}, [
|
|
155
174
|
dataLength,
|
|
@@ -159,6 +178,7 @@ export const useGestureViewer = <T = any>({
|
|
|
159
178
|
width,
|
|
160
179
|
itemSpacing,
|
|
161
180
|
maxZoomScale,
|
|
181
|
+
enableLoop,
|
|
162
182
|
scale,
|
|
163
183
|
screenHeight,
|
|
164
184
|
translateX,
|
|
@@ -186,28 +206,18 @@ export const useGestureViewer = <T = any>({
|
|
|
186
206
|
startScale.value = 1;
|
|
187
207
|
rotation.value = 0;
|
|
188
208
|
|
|
189
|
-
if (
|
|
209
|
+
if (adjustedInitialIndex <= 0 || !listRef.current) {
|
|
190
210
|
return;
|
|
191
211
|
}
|
|
192
212
|
|
|
193
213
|
const runAfterInteractions = InteractionManager.runAfterInteractions(() => {
|
|
194
|
-
|
|
195
|
-
listRef.current.scrollToIndex({
|
|
196
|
-
index: initialIndex,
|
|
197
|
-
animated: false,
|
|
198
|
-
});
|
|
199
|
-
} else if (listRef.current.scrollTo) {
|
|
200
|
-
listRef.current.scrollTo({
|
|
201
|
-
x: initialIndex * (width + itemSpacing),
|
|
202
|
-
animated: false,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
214
|
+
scrollTo(adjustedInitialIndex, false);
|
|
205
215
|
});
|
|
206
216
|
|
|
207
217
|
return () => {
|
|
208
218
|
runAfterInteractions?.cancel();
|
|
209
219
|
};
|
|
210
|
-
}, [
|
|
220
|
+
}, [adjustedInitialIndex, translateY, backdropOpacity, translateX, scale, startScale, rotation, scrollTo]);
|
|
211
221
|
|
|
212
222
|
const onMomentumScrollEnd = useCallback(
|
|
213
223
|
(event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
@@ -216,12 +226,24 @@ export const useGestureViewer = <T = any>({
|
|
|
216
226
|
}
|
|
217
227
|
|
|
218
228
|
const contentOffset = event.nativeEvent.contentOffset;
|
|
219
|
-
const
|
|
229
|
+
const scrollIndex = Math.round(contentOffset.x / (width + itemSpacing));
|
|
220
230
|
|
|
221
|
-
|
|
231
|
+
const isLoopHandled = manager?.handleMomentumScrollEnd(scrollIndex);
|
|
232
|
+
|
|
233
|
+
if (isLoopHandled) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const { realIndex, needsJump, jumpToIndex } = getLoopAdjustedIndex(scrollIndex, dataLength, enableLoop);
|
|
238
|
+
|
|
239
|
+
if (needsJump && jumpToIndex !== undefined) {
|
|
240
|
+
scrollTo(jumpToIndex, false);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (realIndex !== currentIndex && realIndex >= 0 && realIndex < dataLength) {
|
|
222
244
|
if (manager) {
|
|
223
|
-
manager.setCurrentIndex(
|
|
224
|
-
setCurrentIndex(
|
|
245
|
+
manager.setCurrentIndex(realIndex);
|
|
246
|
+
setCurrentIndex(realIndex);
|
|
225
247
|
manager.notifyStateChange();
|
|
226
248
|
}
|
|
227
249
|
|
|
@@ -235,12 +257,14 @@ export const useGestureViewer = <T = any>({
|
|
|
235
257
|
}
|
|
236
258
|
},
|
|
237
259
|
[
|
|
260
|
+
scrollTo,
|
|
238
261
|
manager,
|
|
239
262
|
currentIndex,
|
|
240
263
|
dataLength,
|
|
241
264
|
width,
|
|
242
265
|
itemSpacing,
|
|
243
266
|
enableSwipeGesture,
|
|
267
|
+
enableLoop,
|
|
244
268
|
translateX,
|
|
245
269
|
translateY,
|
|
246
270
|
scale,
|
|
@@ -463,6 +487,10 @@ export const useGestureViewer = <T = any>({
|
|
|
463
487
|
return { opacity };
|
|
464
488
|
}, [animateBackdrop]);
|
|
465
489
|
|
|
490
|
+
const onScrollBeginDrag = useCallback(() => {
|
|
491
|
+
manager?.handleScrollBeginDrag();
|
|
492
|
+
}, [manager]);
|
|
493
|
+
|
|
466
494
|
return {
|
|
467
495
|
currentIndex,
|
|
468
496
|
dataLength,
|
|
@@ -474,6 +502,7 @@ export const useGestureViewer = <T = any>({
|
|
|
474
502
|
zoomGesture,
|
|
475
503
|
|
|
476
504
|
onMomentumScrollEnd,
|
|
505
|
+
onScrollBeginDrag,
|
|
477
506
|
|
|
478
507
|
animatedStyle,
|
|
479
508
|
backdropStyle,
|