react-native-gesture-image-viewer 1.2.1 → 1.2.3
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 +1 -1
- package/lib/module/useGestureViewer.js +2 -2
- package/lib/module/useGestureViewer.js.map +1 -1
- package/lib/typescript/src/useGestureViewer.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/GestureViewer.tsx +171 -0
- package/src/GestureViewerManager.ts +103 -0
- package/src/GestureViewerRegistry.ts +66 -0
- package/src/WebPagingFixStyle.tsx +24 -0
- package/src/index.tsx +3 -0
- package/src/types.ts +144 -0
- package/src/useGestureViewer.ts +424 -0
- package/src/useGestureViewerController.ts +48 -0
- package/src/utils.ts +29 -0
package/README.md
CHANGED
|
@@ -193,7 +193,7 @@ function App() {
|
|
|
193
193
|
|
|
194
194
|
#### Content Components
|
|
195
195
|
|
|
196
|
-
You can inject various types of content components like `expo-image`, `FastImage`, etc., through the `
|
|
196
|
+
You can inject various types of content components like `expo-image`, `FastImage`, etc., through the `renderItem` prop to use gestures.
|
|
197
197
|
|
|
198
198
|
```tsx
|
|
199
199
|
import { GestureViewer } from 'react-native-gesture-image-viewer';
|
|
@@ -149,7 +149,7 @@ export const useGestureViewer = ({
|
|
|
149
149
|
}
|
|
150
150
|
}, [manager, currentIndex, dataLength, width, itemSpacing, enableSwipeGesture, translateX, translateY, scale, initialTranslateX, initialTranslateY, startScale]);
|
|
151
151
|
const dismissGesture = useMemo(() => {
|
|
152
|
-
return Gesture.Pan().minDistance(10).averageTouches(true).activeOffsetY([-10, 10]).failOffsetX([-10, 10]).enabled(!isZoomed).onUpdate(event => {
|
|
152
|
+
return Gesture.Pan().minDistance(10).averageTouches(true).activeCursor('grabbing').activeOffsetY([-10, 10]).failOffsetX([-10, 10]).enabled(!isZoomed).onUpdate(event => {
|
|
153
153
|
translateY.value = event.translationY / resistance;
|
|
154
154
|
}).onEnd(event => {
|
|
155
155
|
if (event.translationY > dismissThreshold && enableDismissGesture && onDismiss) {
|
|
@@ -212,7 +212,7 @@ export const useGestureViewer = ({
|
|
|
212
212
|
});
|
|
213
213
|
}, [scale, enableZoomGesture, maxZoomScale, translateX, translateY, startScale, initialTranslateX, initialTranslateY, width, screenHeight, constrainToBounds]);
|
|
214
214
|
const zoomPanGesture = useMemo(() => {
|
|
215
|
-
return Gesture.Pan().enabled(enableZoomPanGesture && isZoomed).averageTouches(true).onBegin(() => {
|
|
215
|
+
return Gesture.Pan().enabled(enableZoomPanGesture && isZoomed).activeCursor('grabbing').averageTouches(true).onBegin(() => {
|
|
216
216
|
initialTranslateX.value = translateX.value;
|
|
217
217
|
initialTranslateY.value = translateY.value;
|
|
218
218
|
}).onUpdate(event => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useMemo","useRef","useState","InteractionManager","useWindowDimensions","Gesture","Easing","interpolate","runOnJS","useAnimatedReaction","useAnimatedStyle","useSharedValue","withSpring","withTiming","registry","useGestureViewer","data","initialIndex","onIndexChange","onDismiss","width","customWidth","dismissThreshold","resistance","animateBackdrop","enableDismissGesture","enableSwipeGesture","enableZoomGesture","enableDoubleTapGesture","enableZoomPanGesture","maxZoomScale","itemSpacing","useSnap","id","screenWidth","height","screenHeight","isZoomed","setIsZoomed","currentIndex","setCurrentIndex","manager","setManager","unsubscribeRef","initialTranslateY","initialTranslateX","startScale","translateY","translateX","scale","backdropOpacity","listRef","dataLength","length","constrainToBounds","x","y","maxTranslateX","maxTranslateY","Math","max","min","value","currentScale","handleManagerChange","current","getState","subscribe","state","unsubscribeFromRegistry","subscribeToManager","setDataLength","setEnableSwipeGesture","setWidth","notifyStateChange","setListRef","runAfterInteractions","scrollToIndex","index","animated","scrollTo","cancel","onMomentumScrollEnd","event","contentOffset","nativeEvent","newIndex","round","dismissGesture","Pan","minDistance","averageTouches","activeOffsetY","failOffsetX","enabled","onUpdate","translationY","onEnd","damping","stiffness","zoomPinchGesture","Pinch","onBegin","newScale","deltaScale","centerX","focalX","centerY","focalY","newTranslateX","newTranslateY","constrained","duration","easing","bezier","finalConstrained","zoomPanGesture","translationX","doubleTapGesture","Tap","numberOfTaps","nextScale","zoomGesture","Race","Exclusive","animatedStyle","transform","backdropStyle","opacity"],"sourceRoot":"../../src","sources":["useGestureViewer.ts"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useMemo","useRef","useState","InteractionManager","useWindowDimensions","Gesture","Easing","interpolate","runOnJS","useAnimatedReaction","useAnimatedStyle","useSharedValue","withSpring","withTiming","registry","useGestureViewer","data","initialIndex","onIndexChange","onDismiss","width","customWidth","dismissThreshold","resistance","animateBackdrop","enableDismissGesture","enableSwipeGesture","enableZoomGesture","enableDoubleTapGesture","enableZoomPanGesture","maxZoomScale","itemSpacing","useSnap","id","screenWidth","height","screenHeight","isZoomed","setIsZoomed","currentIndex","setCurrentIndex","manager","setManager","unsubscribeRef","initialTranslateY","initialTranslateX","startScale","translateY","translateX","scale","backdropOpacity","listRef","dataLength","length","constrainToBounds","x","y","maxTranslateX","maxTranslateY","Math","max","min","value","currentScale","handleManagerChange","current","getState","subscribe","state","unsubscribeFromRegistry","subscribeToManager","setDataLength","setEnableSwipeGesture","setWidth","notifyStateChange","setListRef","runAfterInteractions","scrollToIndex","index","animated","scrollTo","cancel","onMomentumScrollEnd","event","contentOffset","nativeEvent","newIndex","round","dismissGesture","Pan","minDistance","averageTouches","activeCursor","activeOffsetY","failOffsetX","enabled","onUpdate","translationY","onEnd","damping","stiffness","zoomPinchGesture","Pinch","onBegin","newScale","deltaScale","centerX","focalX","centerY","focalY","newTranslateX","newTranslateY","constrained","duration","easing","bezier","finalConstrained","zoomPanGesture","translationX","doubleTapGesture","Tap","numberOfTaps","nextScale","zoomGesture","Race","Exclusive","animatedStyle","transform","backdropStyle","opacity"],"sourceRoot":"../../src","sources":["useGestureViewer.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -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;AAElD,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,yQAoBvC,qBAAqB,CAAC,CAAC,CAAC;;;;;;;;iCAqIf,oBAAoB,CAAC,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;
|
|
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;AAElD,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,yQAoBvC,qBAAqB,CAAC,CAAC,CAAC;;;;;;;;iCAqIf,oBAAoB,CAAC,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;CAmPlD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-gesture-image-viewer",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
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",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"lib",
|
|
17
|
+
"src",
|
|
17
18
|
"android",
|
|
18
19
|
"ios",
|
|
19
20
|
"cpp",
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo } from 'react';
|
|
2
|
+
import { type FlatList, Platform, type ScrollViewProps, StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
3
|
+
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
4
|
+
import Animated from 'react-native-reanimated';
|
|
5
|
+
import { registry } from './GestureViewerRegistry';
|
|
6
|
+
import type { GestureViewerProps } from './types';
|
|
7
|
+
import { useGestureViewer } from './useGestureViewer';
|
|
8
|
+
import { isFlashListLike, isFlatListLike, isScrollViewLike } from './utils';
|
|
9
|
+
import WebPagingFixStyle from './WebPagingFixStyle';
|
|
10
|
+
|
|
11
|
+
export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
12
|
+
id = 'default',
|
|
13
|
+
data,
|
|
14
|
+
renderItem: renderItemProp,
|
|
15
|
+
renderContainer,
|
|
16
|
+
ListComponent,
|
|
17
|
+
width: customWidth,
|
|
18
|
+
listProps,
|
|
19
|
+
backdropStyle: backdropStyleProps,
|
|
20
|
+
containerStyle,
|
|
21
|
+
initialIndex = 0,
|
|
22
|
+
itemSpacing = 0,
|
|
23
|
+
useSnap = false,
|
|
24
|
+
...props
|
|
25
|
+
}: GestureViewerProps<T, LC>) {
|
|
26
|
+
const Component = ListComponent as React.ComponentType<any>;
|
|
27
|
+
|
|
28
|
+
const { width: screenWidth } = useWindowDimensions();
|
|
29
|
+
|
|
30
|
+
const width = useSnap ? customWidth || screenWidth : screenWidth;
|
|
31
|
+
|
|
32
|
+
const { listRef, isZoomed, dismissGesture, zoomGesture, onMomentumScrollEnd, animatedStyle, backdropStyle } =
|
|
33
|
+
useGestureViewer({
|
|
34
|
+
id,
|
|
35
|
+
data,
|
|
36
|
+
width,
|
|
37
|
+
initialIndex,
|
|
38
|
+
itemSpacing,
|
|
39
|
+
useSnap,
|
|
40
|
+
...props,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const renderItem = useCallback(
|
|
44
|
+
({ item, index }: { item: T; index: number }) => {
|
|
45
|
+
return (
|
|
46
|
+
<View
|
|
47
|
+
key={typeof item === 'string' ? item : index}
|
|
48
|
+
style={[
|
|
49
|
+
{
|
|
50
|
+
width,
|
|
51
|
+
height: '100%',
|
|
52
|
+
justifyContent: 'center',
|
|
53
|
+
alignItems: 'center',
|
|
54
|
+
marginHorizontal: itemSpacing / 2,
|
|
55
|
+
},
|
|
56
|
+
]}
|
|
57
|
+
>
|
|
58
|
+
{renderItemProp(item, index)}
|
|
59
|
+
</View>
|
|
60
|
+
);
|
|
61
|
+
},
|
|
62
|
+
[width, itemSpacing, renderItemProp],
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const getItemLayout = useCallback(
|
|
66
|
+
(_: ArrayLike<T> | null | undefined, index: number) => ({
|
|
67
|
+
length: width + itemSpacing,
|
|
68
|
+
offset: (width + itemSpacing) * index,
|
|
69
|
+
index,
|
|
70
|
+
}),
|
|
71
|
+
[width, itemSpacing],
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const keyExtractor = useCallback(
|
|
75
|
+
(item: T, index: number) => (typeof item === 'string' ? item : `image-${index}`),
|
|
76
|
+
[],
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const gesture = useMemo(() => {
|
|
80
|
+
return Gesture.Race(dismissGesture, zoomGesture);
|
|
81
|
+
}, [zoomGesture, dismissGesture]);
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
registry.createManager(id);
|
|
85
|
+
|
|
86
|
+
return () => registry.deleteManager(id);
|
|
87
|
+
}, [id]);
|
|
88
|
+
|
|
89
|
+
const commonProps: ScrollViewProps = useMemo(
|
|
90
|
+
() => ({
|
|
91
|
+
horizontal: true,
|
|
92
|
+
scrollEnabled: !isZoomed,
|
|
93
|
+
showsHorizontalScrollIndicator: false,
|
|
94
|
+
onMomentumScrollEnd: onMomentumScrollEnd,
|
|
95
|
+
...(useSnap
|
|
96
|
+
? {
|
|
97
|
+
snapToInterval: width + itemSpacing,
|
|
98
|
+
snapToAlignment: 'center',
|
|
99
|
+
decelerationRate: 'fast',
|
|
100
|
+
}
|
|
101
|
+
: {
|
|
102
|
+
pagingEnabled: true,
|
|
103
|
+
}),
|
|
104
|
+
scrollEventThrottle: 16,
|
|
105
|
+
removeClippedSubviews: true,
|
|
106
|
+
}),
|
|
107
|
+
[width, itemSpacing, isZoomed, onMomentumScrollEnd, useSnap],
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const listComponent = (
|
|
111
|
+
<GestureHandlerRootView>
|
|
112
|
+
<GestureDetector gesture={gesture}>
|
|
113
|
+
<View style={[styles.container, containerStyle]}>
|
|
114
|
+
<Animated.View style={[styles.background, backdropStyleProps, backdropStyle]} />
|
|
115
|
+
<Animated.View
|
|
116
|
+
style={[styles.content, animatedStyle]}
|
|
117
|
+
{...(Platform.OS === 'web' &&
|
|
118
|
+
isFlashListLike(Component) && { dataSet: { 'flash-list-paging-enabled-fix': true } })}
|
|
119
|
+
>
|
|
120
|
+
{isScrollViewLike(Component) ? (
|
|
121
|
+
<Component ref={listRef} {...commonProps} {...listProps}>
|
|
122
|
+
{data.map((item, index) => renderItem({ item, index }))}
|
|
123
|
+
</Component>
|
|
124
|
+
) : (
|
|
125
|
+
isFlatListLike(Component) && (
|
|
126
|
+
<Component
|
|
127
|
+
ref={listRef}
|
|
128
|
+
{...commonProps}
|
|
129
|
+
data={data}
|
|
130
|
+
renderItem={renderItem}
|
|
131
|
+
initialScrollIndex={initialIndex}
|
|
132
|
+
keyExtractor={keyExtractor}
|
|
133
|
+
windowSize={3}
|
|
134
|
+
maxToRenderPerBatch={3}
|
|
135
|
+
getItemLayout={getItemLayout}
|
|
136
|
+
{...(isFlashListLike(Component) && { estimatedItemSize: width + itemSpacing })}
|
|
137
|
+
// NOTE - https://github.com/necolas/react-native-web/issues/1299
|
|
138
|
+
{...(Platform.OS === 'web' &&
|
|
139
|
+
isFlatListLike(Component) && { dataSet: { 'flat-list-paging-enabled-fix': true } })}
|
|
140
|
+
{...listProps}
|
|
141
|
+
/>
|
|
142
|
+
)
|
|
143
|
+
)}
|
|
144
|
+
</Animated.View>
|
|
145
|
+
<WebPagingFixStyle Component={Component} />
|
|
146
|
+
</View>
|
|
147
|
+
</GestureDetector>
|
|
148
|
+
</GestureHandlerRootView>
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
return renderContainer ? renderContainer(listComponent) : listComponent;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const styles = StyleSheet.create({
|
|
155
|
+
container: {
|
|
156
|
+
flex: 1,
|
|
157
|
+
},
|
|
158
|
+
content: {
|
|
159
|
+
flex: 1,
|
|
160
|
+
width: '100%',
|
|
161
|
+
height: '100%',
|
|
162
|
+
},
|
|
163
|
+
background: {
|
|
164
|
+
position: 'absolute',
|
|
165
|
+
top: 0,
|
|
166
|
+
left: 0,
|
|
167
|
+
right: 0,
|
|
168
|
+
bottom: 0,
|
|
169
|
+
backgroundColor: 'black',
|
|
170
|
+
},
|
|
171
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export type GestureViewerManagerState = {
|
|
2
|
+
currentIndex: number;
|
|
3
|
+
dataLength: number;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
class GestureViewerManager {
|
|
7
|
+
private currentIndex = 0;
|
|
8
|
+
private dataLength = 0;
|
|
9
|
+
private width = 0;
|
|
10
|
+
private listRef: any | null = null;
|
|
11
|
+
private enableSwipeGesture = true;
|
|
12
|
+
private listeners = new Set<(state: GestureViewerManagerState) => void>();
|
|
13
|
+
|
|
14
|
+
// private updateState(newState: Partial<any>) {
|
|
15
|
+
// Object.assign(this, newState);
|
|
16
|
+
// this.notifyListeners();
|
|
17
|
+
// }
|
|
18
|
+
|
|
19
|
+
private notifyListeners() {
|
|
20
|
+
const state = this.getState();
|
|
21
|
+
|
|
22
|
+
this.listeners.forEach((listener) => listener(state));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
subscribe(listener: (state: GestureViewerManagerState) => void) {
|
|
26
|
+
this.listeners.add(listener);
|
|
27
|
+
|
|
28
|
+
return () => {
|
|
29
|
+
this.listeners.delete(listener);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
getState() {
|
|
34
|
+
return {
|
|
35
|
+
currentIndex: this.currentIndex,
|
|
36
|
+
dataLength: this.dataLength,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
setWidth(width: number) {
|
|
41
|
+
this.width = width;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
setListRef(ref: any) {
|
|
45
|
+
this.listRef = ref;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
setDataLength(length: number) {
|
|
49
|
+
this.dataLength = length;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
setEnableSwipeGesture(enabled: boolean) {
|
|
53
|
+
this.enableSwipeGesture = enabled;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setCurrentIndex(index: number) {
|
|
57
|
+
if (index !== this.currentIndex) {
|
|
58
|
+
this.currentIndex = index;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
notifyStateChange() {
|
|
63
|
+
this.notifyListeners();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
goToIndex = (index: number) => {
|
|
67
|
+
if (index < 0 || index >= this.dataLength || !this.enableSwipeGesture || !this.listRef) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this.currentIndex = index;
|
|
72
|
+
|
|
73
|
+
if (this.listRef.scrollToIndex) {
|
|
74
|
+
this.listRef.scrollToIndex({ index, animated: true });
|
|
75
|
+
} else if (this.listRef.scrollTo) {
|
|
76
|
+
this.listRef.scrollTo({ x: index * this.width, animated: true });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this.notifyListeners();
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
goToPrevious = () => {
|
|
83
|
+
if (this.currentIndex > 0) {
|
|
84
|
+
this.goToIndex(this.currentIndex - 1);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
goToNext = () => {
|
|
89
|
+
if (this.currentIndex < this.dataLength - 1) {
|
|
90
|
+
this.goToIndex(this.currentIndex + 1);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
cleanUp() {
|
|
95
|
+
this.listeners.clear();
|
|
96
|
+
this.listRef = null;
|
|
97
|
+
this.enableSwipeGesture = true;
|
|
98
|
+
this.currentIndex = 0;
|
|
99
|
+
this.dataLength = 0;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export default GestureViewerManager;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import GestureViewerManager from './GestureViewerManager';
|
|
2
|
+
|
|
3
|
+
class GestureViewerRegistry {
|
|
4
|
+
private managers = new Map<string, GestureViewerManager>();
|
|
5
|
+
private subscribers = new Map<string, Set<(manager: GestureViewerManager | null) => void>>();
|
|
6
|
+
|
|
7
|
+
subscribeToManager(id: string, callback: (manager: GestureViewerManager | null) => void) {
|
|
8
|
+
if (!this.subscribers.has(id)) {
|
|
9
|
+
this.subscribers.set(id, new Set());
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
this.subscribers.get(id)?.add(callback);
|
|
13
|
+
|
|
14
|
+
const manager = this.managers.get(id) || null;
|
|
15
|
+
|
|
16
|
+
callback(manager);
|
|
17
|
+
|
|
18
|
+
return () => {
|
|
19
|
+
const subscribers = this.subscribers.get(id);
|
|
20
|
+
|
|
21
|
+
subscribers?.delete(callback);
|
|
22
|
+
|
|
23
|
+
if (subscribers && subscribers.size === 0) {
|
|
24
|
+
this.subscribers.delete(id);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
createManager(id: string): GestureViewerManager | null {
|
|
30
|
+
if (this.managers.has(id)) {
|
|
31
|
+
return this.managers.get(id) || null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const manager = new GestureViewerManager();
|
|
35
|
+
this.managers.set(id, manager);
|
|
36
|
+
|
|
37
|
+
this.notifySubscribers(id, manager);
|
|
38
|
+
|
|
39
|
+
return manager;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getManager(id: string): GestureViewerManager | null {
|
|
43
|
+
return this.managers.get(id) || null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
deleteManager(id: string) {
|
|
47
|
+
const manager = this.managers.get(id);
|
|
48
|
+
|
|
49
|
+
if (manager) {
|
|
50
|
+
manager.cleanUp();
|
|
51
|
+
this.managers.delete(id);
|
|
52
|
+
|
|
53
|
+
this.notifySubscribers(id, null);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
notifySubscribers(id: string, manager: GestureViewerManager | null) {
|
|
58
|
+
const listeners = this.subscribers.get(id);
|
|
59
|
+
|
|
60
|
+
if (listeners) {
|
|
61
|
+
[...listeners].forEach((callback) => callback(manager));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const registry = new GestureViewerRegistry();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import { isFlashListLike, isFlatListLike } from './utils';
|
|
3
|
+
|
|
4
|
+
type WebPagingFixStyleProps = {
|
|
5
|
+
Component: React.ComponentType<any>;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
function WebPagingFixStyle({ Component }: WebPagingFixStyleProps) {
|
|
9
|
+
if (Platform.OS !== 'web') {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (isFlashListLike(Component)) {
|
|
14
|
+
return <style>{`[data-flash-list-paging-enabled-fix] > div {height: 100%;}`}</style>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (isFlatListLike(Component)) {
|
|
18
|
+
return <style>{`[data-flat-list-paging-enabled-fix] > div > div > div {height: 100%;}`}</style>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default WebPagingFixStyle;
|
package/src/index.tsx
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { FlatList as RNFlatList, ScrollView as RNScrollView, StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import type { FlatList as GHFlatList, ScrollView as GHScrollView } from 'react-native-gesture-handler';
|
|
4
|
+
|
|
5
|
+
export type FlatListComponent = typeof RNFlatList | typeof GHFlatList;
|
|
6
|
+
export type ScrollViewComponent = typeof RNScrollView | typeof GHScrollView;
|
|
7
|
+
|
|
8
|
+
type GetComponentProps<T> = T extends React.ComponentType<infer P> ? P : never;
|
|
9
|
+
|
|
10
|
+
type ConditionalListProps<LC> = LC extends FlatListComponent
|
|
11
|
+
? React.ComponentProps<LC>
|
|
12
|
+
: LC extends ScrollViewComponent
|
|
13
|
+
? React.ComponentProps<LC>
|
|
14
|
+
: GetComponentProps<LC>;
|
|
15
|
+
|
|
16
|
+
export interface GestureViewerProps<T = any, LC = typeof RNFlatList> {
|
|
17
|
+
/**
|
|
18
|
+
* When you want to efficiently manage multiple `GestureViewer` instances, you can use the `id` prop to use multiple `GestureViewer` components.
|
|
19
|
+
* @remark `GestureViewer` automatically removes instances from memory when components are unmounted, so no manual memory management is required.
|
|
20
|
+
* @default 'default'
|
|
21
|
+
*/
|
|
22
|
+
id?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The data to display in the `GestureViewer`.
|
|
25
|
+
*/
|
|
26
|
+
data: T[];
|
|
27
|
+
/**
|
|
28
|
+
* The index of the item to display in the `GestureViewer` when the component is mounted.
|
|
29
|
+
* @default 0
|
|
30
|
+
*/
|
|
31
|
+
initialIndex?: number;
|
|
32
|
+
/**
|
|
33
|
+
* A callback function that is called when the index of the item changes.
|
|
34
|
+
*/
|
|
35
|
+
onIndexChange?: (index: number) => void;
|
|
36
|
+
/**
|
|
37
|
+
* A callback function that is called when the `GestureViewer` is dismissed.
|
|
38
|
+
*/
|
|
39
|
+
onDismiss?: () => void;
|
|
40
|
+
/**
|
|
41
|
+
* A callback function that is called to render the item.
|
|
42
|
+
*/
|
|
43
|
+
renderItem: (item: T, index: number) => React.ReactElement;
|
|
44
|
+
/**
|
|
45
|
+
* A callback function that is called to render the container.
|
|
46
|
+
*/
|
|
47
|
+
renderContainer?: (children: React.ReactElement) => React.ReactElement;
|
|
48
|
+
/**
|
|
49
|
+
* Support for any list component like `ScrollView`, `FlatList`, `FlashList` through the `ListComponent` prop.
|
|
50
|
+
*/
|
|
51
|
+
ListComponent: LC;
|
|
52
|
+
/**
|
|
53
|
+
* The width of the `GestureViewer`.
|
|
54
|
+
* @remark If you don't set this prop, the width of the `GestureViewer` will be the same as the width of the screen.
|
|
55
|
+
* @default screen width
|
|
56
|
+
*/
|
|
57
|
+
width?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Enables snap scrolling mode.
|
|
60
|
+
*
|
|
61
|
+
* @remark
|
|
62
|
+
* **`false` (default)**: Paging mode (`pagingEnabled: true`)
|
|
63
|
+
* - Scrolls by full screen size increments
|
|
64
|
+
*
|
|
65
|
+
* **`true`**: Snap mode (`snapToInterval` auto-calculated)
|
|
66
|
+
* - `snapToInterval` is automatically calculated based on `width` and `itemSpacing` values
|
|
67
|
+
* - Use this option when you need item spacing
|
|
68
|
+
* @default false
|
|
69
|
+
*
|
|
70
|
+
*/
|
|
71
|
+
useSnap?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* `dismissThreshold` controls when `onDismiss` is called by applying a threshold value during vertical gestures.
|
|
74
|
+
* @default 80
|
|
75
|
+
*/
|
|
76
|
+
dismissThreshold?: number;
|
|
77
|
+
// swipeThreshold?: number;
|
|
78
|
+
// velocityThreshold?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Calls `onDismiss` function when swiping down.
|
|
81
|
+
* @remark Useful for closing modals with downward swipe gestures.
|
|
82
|
+
* @default true
|
|
83
|
+
*/
|
|
84
|
+
enableDismissGesture?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Controls left/right swipe gestures.
|
|
87
|
+
* @remark When `false`, horizontal gestures are disabled.
|
|
88
|
+
* @default true
|
|
89
|
+
*/
|
|
90
|
+
enableSwipeGesture?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* `resistance` controls the range of vertical movement by applying resistance during vertical gestures.
|
|
93
|
+
* @default 2
|
|
94
|
+
*/
|
|
95
|
+
resistance?: number;
|
|
96
|
+
/**
|
|
97
|
+
* The props to pass to the list component.
|
|
98
|
+
* @remark The `listProps` provides **type inference based on the selected list component**, ensuring accurate autocompletion and type safety in your IDE.
|
|
99
|
+
*/
|
|
100
|
+
listProps?: Partial<ConditionalListProps<LC>>;
|
|
101
|
+
/**
|
|
102
|
+
* The style of the backdrop.
|
|
103
|
+
*/
|
|
104
|
+
backdropStyle?: StyleProp<ViewStyle>;
|
|
105
|
+
/**
|
|
106
|
+
* The style of the container.
|
|
107
|
+
*/
|
|
108
|
+
containerStyle?: StyleProp<ViewStyle>;
|
|
109
|
+
/**
|
|
110
|
+
* By default, the background `opacity` gradually decreases from 1 to 0 during downward swipe gestures.
|
|
111
|
+
* @remark When `false`, this animation is disabled.
|
|
112
|
+
* @default true
|
|
113
|
+
*/
|
|
114
|
+
animateBackdrop?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Only works when zoom is active, allows moving item position when zoomed.
|
|
117
|
+
* @remark When `false`, gesture movement is disabled during zoom.
|
|
118
|
+
* @default true
|
|
119
|
+
*/
|
|
120
|
+
enableZoomPanGesture?: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Controls two-finger pinch gestures.
|
|
123
|
+
* @remark When `false`, two-finger zoom gestures are disabled.
|
|
124
|
+
* @default true
|
|
125
|
+
*/
|
|
126
|
+
enableZoomGesture?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Controls double-tap zoom gestures.
|
|
129
|
+
* @remark When `false`, double-tap zoom gestures are disabled.
|
|
130
|
+
* @default true
|
|
131
|
+
*/
|
|
132
|
+
enableDoubleTapGesture?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* The maximum zoom scale.
|
|
135
|
+
* @default 2
|
|
136
|
+
*/
|
|
137
|
+
maxZoomScale?: number;
|
|
138
|
+
/**
|
|
139
|
+
* The spacing between items in pixels.
|
|
140
|
+
* @remark Only applied when `useSnap` is `true`.
|
|
141
|
+
* @default 0
|
|
142
|
+
*/
|
|
143
|
+
itemSpacing?: number;
|
|
144
|
+
}
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
InteractionManager,
|
|
4
|
+
type NativeScrollEvent,
|
|
5
|
+
type NativeSyntheticEvent,
|
|
6
|
+
useWindowDimensions,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import { Gesture } from 'react-native-gesture-handler';
|
|
9
|
+
import {
|
|
10
|
+
Easing,
|
|
11
|
+
interpolate,
|
|
12
|
+
runOnJS,
|
|
13
|
+
useAnimatedReaction,
|
|
14
|
+
useAnimatedStyle,
|
|
15
|
+
useSharedValue,
|
|
16
|
+
withSpring,
|
|
17
|
+
withTiming,
|
|
18
|
+
} from 'react-native-reanimated';
|
|
19
|
+
import type GestureViewerManager from './GestureViewerManager';
|
|
20
|
+
import { registry } from './GestureViewerRegistry';
|
|
21
|
+
import type { GestureViewerProps } from './types';
|
|
22
|
+
|
|
23
|
+
type UseGestureViewerProps<T = any> = Omit<
|
|
24
|
+
GestureViewerProps<T>,
|
|
25
|
+
'renderItem' | 'renderContainer' | 'ListComponent' | 'listProps' | 'containerStyle' | 'backdropStyle'
|
|
26
|
+
>;
|
|
27
|
+
|
|
28
|
+
export const useGestureViewer = <T = any>({
|
|
29
|
+
data,
|
|
30
|
+
initialIndex = 0,
|
|
31
|
+
onIndexChange,
|
|
32
|
+
onDismiss,
|
|
33
|
+
width: customWidth,
|
|
34
|
+
dismissThreshold = 80,
|
|
35
|
+
resistance = 2,
|
|
36
|
+
// swipeThreshold = 0.5,
|
|
37
|
+
// velocityThreshold = 200,
|
|
38
|
+
animateBackdrop = true,
|
|
39
|
+
enableDismissGesture = true,
|
|
40
|
+
enableSwipeGesture = true,
|
|
41
|
+
enableZoomGesture = true,
|
|
42
|
+
enableDoubleTapGesture = true,
|
|
43
|
+
enableZoomPanGesture = true,
|
|
44
|
+
maxZoomScale = 2,
|
|
45
|
+
itemSpacing = 0,
|
|
46
|
+
useSnap = false,
|
|
47
|
+
id = 'default',
|
|
48
|
+
}: UseGestureViewerProps<T>) => {
|
|
49
|
+
const { width: screenWidth, height: screenHeight } = useWindowDimensions();
|
|
50
|
+
const width = useSnap ? customWidth || screenWidth : screenWidth;
|
|
51
|
+
|
|
52
|
+
const [isZoomed, setIsZoomed] = useState(false);
|
|
53
|
+
|
|
54
|
+
const [currentIndex, setCurrentIndex] = useState(initialIndex);
|
|
55
|
+
const [manager, setManager] = useState<GestureViewerManager | null>(null);
|
|
56
|
+
|
|
57
|
+
const unsubscribeRef = useRef<(() => void) | null>(null);
|
|
58
|
+
|
|
59
|
+
const initialTranslateY = useSharedValue(0);
|
|
60
|
+
const initialTranslateX = useSharedValue(0);
|
|
61
|
+
const startScale = useSharedValue(1);
|
|
62
|
+
|
|
63
|
+
const translateY = useSharedValue(0);
|
|
64
|
+
const translateX = useSharedValue(0);
|
|
65
|
+
const scale = useSharedValue(1);
|
|
66
|
+
const backdropOpacity = useSharedValue(1);
|
|
67
|
+
|
|
68
|
+
const listRef = useRef<any>(null);
|
|
69
|
+
|
|
70
|
+
const dataLength = data?.length || 0;
|
|
71
|
+
|
|
72
|
+
const constrainToBounds = useCallback(
|
|
73
|
+
(translateX: number, translateY: number, scale: number) => {
|
|
74
|
+
'worklet';
|
|
75
|
+
if (scale <= 1) {
|
|
76
|
+
return {
|
|
77
|
+
x: translateX,
|
|
78
|
+
y: translateY,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const maxTranslateX = (width * scale - width) / 2;
|
|
83
|
+
const maxTranslateY = (screenHeight * scale - screenHeight) / 2;
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
x: Math.max(-maxTranslateX, Math.min(maxTranslateX, translateX)),
|
|
87
|
+
y: Math.max(-maxTranslateY, Math.min(maxTranslateY, translateY)),
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
[width, screenHeight],
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
useAnimatedReaction(
|
|
94
|
+
() => scale.value,
|
|
95
|
+
(currentScale) => {
|
|
96
|
+
runOnJS(setIsZoomed)(currentScale > 1);
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
const handleManagerChange = (manager: GestureViewerManager | null) => {
|
|
102
|
+
unsubscribeRef.current?.();
|
|
103
|
+
unsubscribeRef.current = null;
|
|
104
|
+
|
|
105
|
+
setManager(manager);
|
|
106
|
+
|
|
107
|
+
if (manager) {
|
|
108
|
+
setCurrentIndex(manager.getState().currentIndex);
|
|
109
|
+
unsubscribeRef.current = manager.subscribe((state) => {
|
|
110
|
+
setCurrentIndex(state.currentIndex);
|
|
111
|
+
});
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
setCurrentIndex(0);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const unsubscribeFromRegistry = registry.subscribeToManager(id, handleManagerChange);
|
|
119
|
+
|
|
120
|
+
return () => {
|
|
121
|
+
unsubscribeFromRegistry();
|
|
122
|
+
unsubscribeRef.current?.();
|
|
123
|
+
};
|
|
124
|
+
}, [id]);
|
|
125
|
+
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
if (!manager) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
manager.setDataLength(dataLength);
|
|
132
|
+
manager.setEnableSwipeGesture(enableSwipeGesture);
|
|
133
|
+
manager.setCurrentIndex(initialIndex);
|
|
134
|
+
manager.setWidth(width + itemSpacing);
|
|
135
|
+
manager.notifyStateChange();
|
|
136
|
+
}, [dataLength, enableSwipeGesture, initialIndex, manager, width, itemSpacing]);
|
|
137
|
+
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
if (!manager || !listRef.current) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
manager.setListRef(listRef.current);
|
|
144
|
+
}, [manager]);
|
|
145
|
+
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
onIndexChange?.(currentIndex);
|
|
148
|
+
}, [currentIndex, onIndexChange]);
|
|
149
|
+
|
|
150
|
+
useEffect(() => {
|
|
151
|
+
translateY.value = 0;
|
|
152
|
+
translateX.value = 0;
|
|
153
|
+
scale.value = 1;
|
|
154
|
+
backdropOpacity.value = 1;
|
|
155
|
+
startScale.value = 1;
|
|
156
|
+
|
|
157
|
+
if (initialIndex <= 0 || !listRef.current) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const runAfterInteractions = InteractionManager.runAfterInteractions(() => {
|
|
162
|
+
if (listRef.current.scrollToIndex) {
|
|
163
|
+
listRef.current.scrollToIndex({
|
|
164
|
+
index: initialIndex,
|
|
165
|
+
animated: false,
|
|
166
|
+
});
|
|
167
|
+
} else if (listRef.current.scrollTo) {
|
|
168
|
+
listRef.current.scrollTo({
|
|
169
|
+
x: initialIndex * (width + itemSpacing),
|
|
170
|
+
animated: false,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return () => {
|
|
176
|
+
runAfterInteractions?.cancel();
|
|
177
|
+
};
|
|
178
|
+
}, [initialIndex, translateY, backdropOpacity, translateX, scale, startScale, width, itemSpacing]);
|
|
179
|
+
|
|
180
|
+
const onMomentumScrollEnd = useCallback(
|
|
181
|
+
(event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
182
|
+
if (!enableSwipeGesture) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const contentOffset = event.nativeEvent.contentOffset;
|
|
187
|
+
const newIndex = Math.round(contentOffset.x / (width + itemSpacing));
|
|
188
|
+
|
|
189
|
+
if (newIndex !== currentIndex && newIndex >= 0 && newIndex < dataLength) {
|
|
190
|
+
if (manager) {
|
|
191
|
+
manager.setCurrentIndex(newIndex);
|
|
192
|
+
setCurrentIndex(newIndex);
|
|
193
|
+
manager.notifyStateChange();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
translateX.value = withTiming(0);
|
|
197
|
+
translateY.value = withTiming(0);
|
|
198
|
+
initialTranslateX.value = withTiming(0);
|
|
199
|
+
initialTranslateY.value = withTiming(0);
|
|
200
|
+
startScale.value = withTiming(1);
|
|
201
|
+
scale.value = withTiming(1);
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
[
|
|
205
|
+
manager,
|
|
206
|
+
currentIndex,
|
|
207
|
+
dataLength,
|
|
208
|
+
width,
|
|
209
|
+
itemSpacing,
|
|
210
|
+
enableSwipeGesture,
|
|
211
|
+
translateX,
|
|
212
|
+
translateY,
|
|
213
|
+
scale,
|
|
214
|
+
initialTranslateX,
|
|
215
|
+
initialTranslateY,
|
|
216
|
+
startScale,
|
|
217
|
+
],
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
const dismissGesture = useMemo(() => {
|
|
221
|
+
return Gesture.Pan()
|
|
222
|
+
.minDistance(10)
|
|
223
|
+
.averageTouches(true)
|
|
224
|
+
.activeCursor('grabbing')
|
|
225
|
+
.activeOffsetY([-10, 10])
|
|
226
|
+
.failOffsetX([-10, 10])
|
|
227
|
+
.enabled(!isZoomed)
|
|
228
|
+
.onUpdate((event) => {
|
|
229
|
+
translateY.value = event.translationY / resistance;
|
|
230
|
+
})
|
|
231
|
+
.onEnd((event) => {
|
|
232
|
+
if (event.translationY > dismissThreshold && enableDismissGesture && onDismiss) {
|
|
233
|
+
runOnJS(onDismiss)();
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
translateY.value = withSpring(0, {
|
|
238
|
+
damping: 15,
|
|
239
|
+
stiffness: 150,
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
}, [translateY, dismissThreshold, enableDismissGesture, onDismiss, resistance, isZoomed]);
|
|
243
|
+
|
|
244
|
+
const zoomPinchGesture = useMemo(() => {
|
|
245
|
+
return Gesture.Pinch()
|
|
246
|
+
.enabled(enableZoomGesture)
|
|
247
|
+
.onBegin(() => {
|
|
248
|
+
startScale.value = scale.value;
|
|
249
|
+
initialTranslateX.value = translateX.value;
|
|
250
|
+
initialTranslateY.value = translateY.value;
|
|
251
|
+
})
|
|
252
|
+
.onUpdate((event) => {
|
|
253
|
+
const newScale = startScale.value * event.scale;
|
|
254
|
+
|
|
255
|
+
const deltaScale = newScale - startScale.value;
|
|
256
|
+
const centerX = event.focalX - width / 2;
|
|
257
|
+
const centerY = event.focalY - screenHeight / 2;
|
|
258
|
+
|
|
259
|
+
scale.value = newScale;
|
|
260
|
+
// NOTE 새로운 이동값 = 기존 이동값 - (중심점 거리 × 스케일 변화량) / 원래 스케일 (중심점이 화면 중심에서 멀수록, 확대 배율이 클수록 더 많이 이동)
|
|
261
|
+
const newTranslateX = initialTranslateX.value - (centerX * deltaScale) / startScale.value;
|
|
262
|
+
const newTranslateY = initialTranslateY.value - (centerY * deltaScale) / startScale.value;
|
|
263
|
+
|
|
264
|
+
const constrained = constrainToBounds(newTranslateX, newTranslateY, newScale);
|
|
265
|
+
|
|
266
|
+
if (newScale <= 1) {
|
|
267
|
+
translateX.value = withTiming(0);
|
|
268
|
+
translateY.value = withTiming(0);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
translateX.value = constrained.x;
|
|
273
|
+
translateY.value = constrained.y;
|
|
274
|
+
})
|
|
275
|
+
.onEnd(() => {
|
|
276
|
+
if (scale.value > maxZoomScale) {
|
|
277
|
+
scale.value = withTiming(maxZoomScale, {
|
|
278
|
+
duration: 300,
|
|
279
|
+
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
const constrained = constrainToBounds(translateX.value, translateY.value, maxZoomScale);
|
|
283
|
+
|
|
284
|
+
translateX.value = withTiming(constrained.x);
|
|
285
|
+
translateY.value = withTiming(constrained.y);
|
|
286
|
+
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (scale.value < 1) {
|
|
291
|
+
scale.value = withTiming(1, {
|
|
292
|
+
duration: 300,
|
|
293
|
+
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
|
|
294
|
+
});
|
|
295
|
+
translateX.value = withTiming(0);
|
|
296
|
+
translateY.value = withTiming(0);
|
|
297
|
+
initialTranslateX.value = withTiming(0);
|
|
298
|
+
initialTranslateY.value = withTiming(0);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const finalConstrained = constrainToBounds(translateX.value, translateY.value, scale.value);
|
|
303
|
+
translateX.value = withTiming(finalConstrained.x);
|
|
304
|
+
translateY.value = withTiming(finalConstrained.y);
|
|
305
|
+
});
|
|
306
|
+
}, [
|
|
307
|
+
scale,
|
|
308
|
+
enableZoomGesture,
|
|
309
|
+
maxZoomScale,
|
|
310
|
+
translateX,
|
|
311
|
+
translateY,
|
|
312
|
+
startScale,
|
|
313
|
+
initialTranslateX,
|
|
314
|
+
initialTranslateY,
|
|
315
|
+
width,
|
|
316
|
+
screenHeight,
|
|
317
|
+
constrainToBounds,
|
|
318
|
+
]);
|
|
319
|
+
|
|
320
|
+
const zoomPanGesture = useMemo(() => {
|
|
321
|
+
return Gesture.Pan()
|
|
322
|
+
.enabled(enableZoomPanGesture && isZoomed)
|
|
323
|
+
.activeCursor('grabbing')
|
|
324
|
+
.averageTouches(true)
|
|
325
|
+
.onBegin(() => {
|
|
326
|
+
initialTranslateX.value = translateX.value;
|
|
327
|
+
initialTranslateY.value = translateY.value;
|
|
328
|
+
})
|
|
329
|
+
.onUpdate((event) => {
|
|
330
|
+
if (scale.value > 1) {
|
|
331
|
+
const newTranslateX = initialTranslateX.value + event.translationX;
|
|
332
|
+
const newTranslateY = initialTranslateY.value + event.translationY;
|
|
333
|
+
|
|
334
|
+
const constrained = constrainToBounds(newTranslateX, newTranslateY, scale.value);
|
|
335
|
+
|
|
336
|
+
translateX.value = constrained.x;
|
|
337
|
+
translateY.value = constrained.y;
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
}, [
|
|
341
|
+
translateX,
|
|
342
|
+
translateY,
|
|
343
|
+
enableZoomPanGesture,
|
|
344
|
+
isZoomed,
|
|
345
|
+
scale,
|
|
346
|
+
initialTranslateX,
|
|
347
|
+
initialTranslateY,
|
|
348
|
+
constrainToBounds,
|
|
349
|
+
]);
|
|
350
|
+
|
|
351
|
+
const doubleTapGesture = useMemo(() => {
|
|
352
|
+
return Gesture.Tap()
|
|
353
|
+
.enabled(enableDoubleTapGesture)
|
|
354
|
+
.numberOfTaps(2)
|
|
355
|
+
.onEnd((event) => {
|
|
356
|
+
const nextScale = scale.value > 1 ? 1 : maxZoomScale;
|
|
357
|
+
|
|
358
|
+
if (nextScale > 1) {
|
|
359
|
+
const centerX = event.x - width / 2;
|
|
360
|
+
const centerY = event.y - screenHeight / 2;
|
|
361
|
+
|
|
362
|
+
// NOTE 확대로 밀려난 거리만큼 반대로 이동해서 탭 지점을 제자리에 유지
|
|
363
|
+
translateX.value = withTiming(-centerX * (nextScale - 1), {
|
|
364
|
+
duration: 300,
|
|
365
|
+
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
|
|
366
|
+
});
|
|
367
|
+
translateY.value = withTiming(-centerY * (nextScale - 1), {
|
|
368
|
+
duration: 300,
|
|
369
|
+
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
|
|
370
|
+
});
|
|
371
|
+
} else {
|
|
372
|
+
translateX.value = withTiming(0, {
|
|
373
|
+
duration: 300,
|
|
374
|
+
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
|
|
375
|
+
});
|
|
376
|
+
translateY.value = withTiming(0, {
|
|
377
|
+
duration: 300,
|
|
378
|
+
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
scale.value = withTiming(nextScale, {
|
|
383
|
+
duration: 300,
|
|
384
|
+
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
}, [scale, enableDoubleTapGesture, maxZoomScale, translateX, translateY, width, screenHeight]);
|
|
388
|
+
|
|
389
|
+
const zoomGesture = useMemo(() => {
|
|
390
|
+
return Gesture.Race(zoomPinchGesture, Gesture.Exclusive(zoomPanGesture, doubleTapGesture));
|
|
391
|
+
}, [zoomPinchGesture, zoomPanGesture, doubleTapGesture]);
|
|
392
|
+
|
|
393
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
394
|
+
return {
|
|
395
|
+
transform: [{ translateY: translateY.value }, { translateX: translateX.value }, { scale: scale.value }],
|
|
396
|
+
};
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
const backdropStyle = useAnimatedStyle(() => {
|
|
400
|
+
if (!animateBackdrop || scale.value !== 1) {
|
|
401
|
+
return { opacity: 1 };
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const opacity = interpolate(translateY.value, [0, 200], [1, 0], 'clamp');
|
|
405
|
+
|
|
406
|
+
return { opacity };
|
|
407
|
+
}, [animateBackdrop]);
|
|
408
|
+
|
|
409
|
+
return {
|
|
410
|
+
currentIndex,
|
|
411
|
+
dataLength,
|
|
412
|
+
translateY,
|
|
413
|
+
listRef,
|
|
414
|
+
isZoomed,
|
|
415
|
+
|
|
416
|
+
dismissGesture,
|
|
417
|
+
zoomGesture,
|
|
418
|
+
|
|
419
|
+
onMomentumScrollEnd,
|
|
420
|
+
|
|
421
|
+
animatedStyle,
|
|
422
|
+
backdropStyle,
|
|
423
|
+
};
|
|
424
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import type GestureViewerManager from './GestureViewerManager';
|
|
3
|
+
import type { GestureViewerManagerState } from './GestureViewerManager';
|
|
4
|
+
import { registry } from './GestureViewerRegistry';
|
|
5
|
+
|
|
6
|
+
export const useGestureViewerController = (id = 'default') => {
|
|
7
|
+
const [state, setState] = useState<GestureViewerManagerState>({
|
|
8
|
+
currentIndex: 0,
|
|
9
|
+
dataLength: 0,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const [manager, setManager] = useState<GestureViewerManager | null>(null);
|
|
13
|
+
const unsubscribeRef = useRef<(() => void) | null>(null);
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const handleManagerChange = (newManager: GestureViewerManager | null) => {
|
|
17
|
+
unsubscribeRef.current?.();
|
|
18
|
+
unsubscribeRef.current = null;
|
|
19
|
+
|
|
20
|
+
setManager(newManager);
|
|
21
|
+
|
|
22
|
+
if (newManager) {
|
|
23
|
+
setState(newManager.getState());
|
|
24
|
+
unsubscribeRef.current = newManager.subscribe(setState);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
setState({ currentIndex: 0, dataLength: 0 });
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const unsubscribeFromRegistry = registry.subscribeToManager(id, handleManagerChange);
|
|
32
|
+
|
|
33
|
+
return () => {
|
|
34
|
+
unsubscribeFromRegistry();
|
|
35
|
+
unsubscribeRef.current?.();
|
|
36
|
+
};
|
|
37
|
+
}, [id]);
|
|
38
|
+
|
|
39
|
+
const noopFunction = useMemo(() => () => {}, []);
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
goToIndex: manager?.goToIndex || noopFunction,
|
|
43
|
+
goToPrevious: manager?.goToPrevious || noopFunction,
|
|
44
|
+
goToNext: manager?.goToNext || noopFunction,
|
|
45
|
+
currentIndex: state.currentIndex,
|
|
46
|
+
totalCount: state.dataLength,
|
|
47
|
+
};
|
|
48
|
+
};
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FlatList as RNFlatList, ScrollView as RNScrollView } from 'react-native';
|
|
2
|
+
import { FlatList as GestureFlatList, ScrollView as GestureScrollView } from 'react-native-gesture-handler';
|
|
3
|
+
import type { FlatListComponent, ScrollViewComponent } from './types';
|
|
4
|
+
|
|
5
|
+
export const isScrollViewLike = (component: any): component is ScrollViewComponent => {
|
|
6
|
+
return component === RNScrollView || component === GestureScrollView;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const isFlatListLike = (component: any): component is FlatListComponent => {
|
|
10
|
+
if (component === RNFlatList || component === GestureFlatList || isFlashListLike(component)) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return false;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const isFlashListLike = (component: any): component is any => {
|
|
18
|
+
try {
|
|
19
|
+
const FlashList = require('@shopify/flash-list')?.FlashList;
|
|
20
|
+
|
|
21
|
+
if (FlashList && component === FlashList) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
// do nothing
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return component?.name === 'FlashList';
|
|
29
|
+
};
|