1
1
import React , { useState , useMemo , useRef , useEffect } from 'react' ;
2
- import { StyleSheet , ViewProps , Dimensions , View , Image , Animated } from 'react-native' ;
2
+ import { StyleSheet , ViewProps , Dimensions , View , Image , Animated , Text , TouchableOpacity } from 'react-native' ;
3
3
import TransitionImage from '../TransitionImage' ;
4
4
import MaskLayer from '../MaskLayer' ;
5
5
import Swiper from '../Swiper' ;
6
+ import Icon from '../Icon' ;
6
7
import { ActivityIndicator } from 'react-native' ;
7
8
export let ImageMainWidth = Dimensions . get ( 'window' ) . width ;
8
9
export let ImageMainHeight = Dimensions . get ( 'window' ) . height ;
@@ -19,6 +20,7 @@ export interface ImageViewerDataSourceProps {
19
20
url : string ;
20
21
[ key : string ] : any ;
21
22
}
23
+
22
24
export interface ImageViewerProps extends ViewProps {
23
25
/** 图片宽度 */
24
26
width ?: number ;
@@ -40,6 +42,9 @@ function ImageViewer(props: ImageViewerProps) {
40
42
const scale = useRef ( new Animated . Value ( 1 ) ) . current ; // 初始缩放比例为 1
41
43
const lastScale = useRef ( 1 ) ; // 上一次的缩放比例
42
44
45
+ const rotateAngle = useRef ( new Animated . Value ( 0 ) ) . current ; // 初始化旋转角度为 0
46
+ const lastAngle = useRef ( 0 ) ; // 保存上次的旋转角度
47
+
43
48
const onPinchGestureEvent = ( event : PinchGestureHandlerGestureEvent ) => {
44
49
if ( event . nativeEvent . scale ) {
45
50
// 更新缩放比例
@@ -55,6 +60,15 @@ function ImageViewer(props: ImageViewerProps) {
55
60
}
56
61
} ;
57
62
63
+ const onRotate = ( ) => {
64
+ lastAngle . current += 90 ; // 旋转 90 度
65
+ Animated . timing ( rotateAngle , {
66
+ useNativeDriver : true ,
67
+ toValue : lastAngle . current ,
68
+ duration : 250 ,
69
+ } ) . start ( ) ;
70
+ } ;
71
+
58
72
useEffect ( ( ) => {
59
73
if ( ! visible ) {
60
74
fadeAnim . setValue ( 0 ) ;
@@ -74,17 +88,25 @@ function ImageViewer(props: ImageViewerProps) {
74
88
return src ;
75
89
} , [ src ] ) ;
76
90
77
- const PinchGestureHandlerChild = ( url : string ) =>
78
- useMemo (
79
- ( ) => (
80
- < PinchGestureHandler onGestureEvent = { onPinchGestureEvent } onHandlerStateChange = { onPinchHandlerStateChange } >
81
- < Animated . View style = { [ { transform : [ { scale } ] } ] } >
82
- < Image style = { { width : '100%' , height : '100%' , resizeMode : 'contain' } } source = { { uri : url } } />
83
- </ Animated . View >
84
- </ PinchGestureHandler >
85
- ) ,
86
- [ src , scale ] ,
87
- ) ;
91
+ const PinchGestureHandlerChild = ( url : string ) => (
92
+ < PinchGestureHandler onGestureEvent = { onPinchGestureEvent } onHandlerStateChange = { onPinchHandlerStateChange } >
93
+ < Animated . View
94
+ style = { [
95
+ {
96
+ transform : [
97
+ { scale } ,
98
+ { rotate : rotateAngle . interpolate ( { inputRange : [ 0 , 360 ] , outputRange : [ '0deg' , '360deg' ] } ) } ,
99
+ ] ,
100
+ } ,
101
+ styles . imageContainer ,
102
+ ] }
103
+ >
104
+ < Image style = { styles . image } source = { { uri : url } } />
105
+ </ Animated . View >
106
+ </ PinchGestureHandler >
107
+ ) ;
108
+
109
+ console . log ( 'src' , typeof src ) ;
88
110
89
111
return (
90
112
< View style = { { } } >
@@ -100,6 +122,15 @@ function ImageViewer(props: ImageViewerProps) {
100
122
} }
101
123
/>
102
124
< MaskLayer visible = { visible } onDismiss = { ( ) => setVisible ( false ) } opacity = { 0.9 } >
125
+ { typeof src === 'string' ? (
126
+ < View style = { { position : 'absolute' , top : 50 , right : 30 } } >
127
+ < TouchableOpacity onPress = { onRotate } >
128
+ < Icon color = "#fff" size = { 18 } name = "reload" />
129
+ </ TouchableOpacity >
130
+ </ View >
131
+ ) : (
132
+ < View />
133
+ ) }
103
134
< Animated . View style = { [ styles . content , { opacity : fadeAnim } ] } >
104
135
{ Array . isArray ( src ) ? (
105
136
< Swiper dataSource = { src } height = { 200 } autoplay = { false } index = { index } />
@@ -117,6 +148,16 @@ const styles = StyleSheet.create({
117
148
marginTop : ImageMainHeight / 3 - 20 ,
118
149
height : ImageMainHeight / 3 - 20 ,
119
150
} ,
151
+ imageContainer : {
152
+ flex : 1 ,
153
+ justifyContent : 'center' ,
154
+ alignItems : 'center' ,
155
+ } ,
156
+ image : {
157
+ width : '100%' ,
158
+ height : '100%' ,
159
+ resizeMode : 'contain' ,
160
+ } ,
120
161
} ) ;
121
162
122
163
export default ImageViewer ;
0 commit comments