@@ -10,28 +10,83 @@ import {
1010import { Surface } from 'gl-react-native'
1111const { Image : GLImage } = require ( "gl-react-image" ) ;
1212
13+ const imageDimensionsAfterZoom = ( viewport , dimensions , zoom ) => {
14+ const ImageRatio = dimensions . width / dimensions . height
15+ const ViewportRatio = viewport . width / viewport . height
16+ if ( ImageRatio > ViewportRatio ) {
17+ return {
18+ height : Math . floor ( viewport . height / zoom ) ,
19+ width : Math . floor ( ( viewport . height * ImageRatio ) / zoom )
20+ }
21+ }
22+ else
23+ return {
24+ height : Math . floor ( ( viewport . width / ImageRatio ) / zoom ) ,
25+ width : Math . floor ( viewport . width / zoom )
26+ }
27+ }
28+
29+ const movementFromZoom = ( gestureState , viewport , dimensions , offsets , zoom ) => {
30+ // X-axis
31+ var widthOffset = dimensions . width - viewport . width
32+ var pxVsMovX = ( 1 / dimensions . width )
33+ var moveX = ( gestureState . dx * pxVsMovX ) * zoom
34+ newPosX = ( parseFloat ( offsets . x ) - parseFloat ( moveX ) )
35+
36+ // Y-axis
37+ var heightOffset = dimensions . height - viewport . height
38+ var pxVsMovY = ( 1 / dimensions . height )
39+ var moveY = ( gestureState . dy * pxVsMovY ) * zoom
40+ newPosY = ( parseFloat ( offsets . y ) - parseFloat ( moveY ) )
41+ return {
42+ x : newPosX ,
43+ y : newPosY ,
44+ }
45+ }
46+
47+
1348class ImageCrop extends Component {
1449 constructor ( props ) {
1550 super ( props ) ;
1651 this . state = {
1752 zoom : 1 ,
53+
1854 //pan settings
1955 centerX : 0.5 ,
2056 centerY : 0.5 ,
57+
2158 //Image sizes
2259 imageHeight : 300 ,
2360 imageWidth : 300 ,
61+ imageDimHeight : 0 ,
62+ imageDimWidth : 0 ,
2463 currentCapture : '' ,
2564 } ;
2665 }
2766 componentWillMount ( ) {
28- var zoom = ( 100 - this . props . zoom ) / 100 ;
29- this . setState ( { zoom : zoom } )
67+ Image . getSize ( this . props . image , ( width , height ) => {
68+ //update state
69+ this . setState ( {
70+ imageHeight : height ,
71+ imageWidth : width ,
72+ } ) ;
73+ } )
3074
31- this . _panOffsetX = 0 ;
32- this . _panOffsetY = 0 ;
33- this . _panResponder = PanResponder . create ( {
75+ //
76+ //get dimensions after crop
77+ //
78+ this . _dimensionAfterZoom = imageDimensionsAfterZoom (
79+ { height : this . props . cropHeight , width : this . props . cropWidth } ,
80+ { height : this . state . imageHeight , width : this . state . imageWidth } ,
81+ this . state . zoom
82+ )
3483
84+ this . setState ( {
85+ imageDimHeight : this . _dimensionAfterZoom . height ,
86+ imageDimWidth : this . _dimensionAfterZoom . width
87+ } )
88+
89+ this . _panResponder = PanResponder . create ( {
3590 onStartShouldSetPanResponder : ( evt , gestureState ) => true ,
3691 onStartShouldSetPanResponderCapture : ( evt , gestureState ) => true ,
3792 onMoveShouldSetPanResponder : ( evt , gestureState ) => true ,
@@ -52,76 +107,84 @@ class ImageCrop extends Component {
52107 onPanResponderMove : ( evt , gestureState ) => {
53108 //We are moving the image
54109 if ( evt . nativeEvent . changedTouches . length <= 1 ) {
55- if ( this . props . panToMove ) {
56-
57- var trackX = ( gestureState . dx / this . props . cropWidth ) * this . state . zoom ;
58- var trackY = ( gestureState . dy / this . props . cropHeight ) * this . state . zoom ;
59- var newPosX = ( Number ( this . offsetX ) - Number ( trackX ) ) ;
60- var newPosY = ( Number ( this . offsetY ) - Number ( trackY ) ) ;
61- if ( newPosX > 1 ) newPosX = Number ( 1 ) ;
62- if ( newPosY > 1 ) newPosY = Number ( 1 ) ;
63- if ( newPosX < 0 ) newPosX = Number ( 0 ) ;
64- if ( newPosY < 0 ) newPosY = Number ( 0 ) ;
65-
66- this . setState ( { centerX : newPosX } )
67- this . setState ( { centerY : newPosY } )
68- this . _panOffsetX = gestureState . dx * this . state . zoom ;
69- this . _panOffsetY = gestureState . dy * this . state . zoom ;
70- }
110+ var trackX = ( gestureState . dx / this . props . cropWidth ) * this . state . zoom ;
111+ var trackY = ( gestureState . dy / this . props . cropHeight ) * this . state . zoom ;
112+ var newPosX = ( Number ( this . offsetX ) - Number ( trackX ) ) ;
113+ var newPosY = ( Number ( this . offsetY ) - Number ( trackY ) ) ;
114+ if ( newPosX > 1 ) newPosX = Number ( 1 ) ;
115+ if ( newPosY > 1 ) newPosY = Number ( 1 ) ;
116+ if ( newPosX < 0 ) newPosX = Number ( 0 ) ;
117+ if ( newPosY < 0 ) newPosY = Number ( 0 ) ;
118+
119+ var movement = movementFromZoom (
120+ gestureState ,
121+ { width : this . props . cropWidth , height : this . props . cropHeight } ,
122+ { width : this . state . imageDimWidth , height : this . state . imageDimHeight } ,
123+ { x : this . offsetX , y : this . offsetY } ,
124+ this . state . zoom
125+ )
126+ this . setState ( { centerX : movement . x } )
127+ this . setState ( { centerY : movement . y } )
71128 } else {
72129 //We are zooming the image
73- if ( this . props . pinchToZoom ) {
74- //Pinch activated
75- if ( this . zoomLastDistance == 0 ) {
76- let a = evt . nativeEvent . changedTouches [ 0 ] . locationX - evt . nativeEvent . changedTouches [ 1 ] . locationX
77- let b = evt . nativeEvent . changedTouches [ 0 ] . locationY - evt . nativeEvent . changedTouches [ 1 ] . locationY
78- let c = Math . sqrt ( a * a + b * b ) ;
79- this . zoomLastDistance = c . toFixed ( 1 ) ;
80- } else {
81- let a = evt . nativeEvent . changedTouches [ 0 ] . locationX - evt . nativeEvent . changedTouches [ 1 ] . locationX
82- let b = evt . nativeEvent . changedTouches [ 0 ] . locationY - evt . nativeEvent . changedTouches [ 1 ] . locationY
83- let c = Math . sqrt ( a * a + b * b ) ;
84- this . zoomCurrentDistance = c . toFixed ( 1 ) ;
85-
86- //what is the zoom level
87- var screenDiagonal = Math . sqrt ( this . state . imageHeight * this . state . imageHeight + this . state . imageWidth * this . state . imageWidth ) ;
88- var distance = ( this . zoomCurrentDistance - this . zoomLastDistance ) / 400 ;
89- var zoom = this . state . zoom - distance ;
90-
91- if ( zoom < 0.3 ) zoom = 0.3 ;
92- if ( zoom > 1 ) zoom = 1 ;
93- this . setState ( {
94- zoom : zoom ,
95- } )
96- //Set last distance..
97- this . zoomLastDistance = this . zoomCurrentDistance ;
98- }
130+ if ( this . zoomLastDistance == 0 ) {
131+ let a = evt . nativeEvent . changedTouches [ 0 ] . locationX - evt . nativeEvent . changedTouches [ 1 ] . locationX
132+ let b = evt . nativeEvent . changedTouches [ 0 ] . locationY - evt . nativeEvent . changedTouches [ 1 ] . locationY
133+ let c = Math . sqrt ( a * a + b * b ) ;
134+ this . zoomLastDistance = c . toFixed ( 1 ) ;
135+ } else {
136+ let a = evt . nativeEvent . changedTouches [ 0 ] . locationX - evt . nativeEvent . changedTouches [ 1 ] . locationX
137+ let b = evt . nativeEvent . changedTouches [ 0 ] . locationY - evt . nativeEvent . changedTouches [ 1 ] . locationY
138+ let c = Math . sqrt ( a * a + b * b ) ;
139+ this . zoomCurrentDistance = c . toFixed ( 1 ) ;
140+
141+ //what is the zoom level
142+ var screenDiagonal = Math . sqrt ( this . state . imageHeight * this . state . imageHeight + this . state . imageWidth * this . state . imageWidth ) ;
143+ var distance = ( this . zoomCurrentDistance - this . zoomLastDistance ) / 400 ;
144+ var zoom = this . state . zoom - distance ;
145+
146+ if ( zoom < 0 ) zoom = 0.0000001 ;
147+ if ( zoom > 1 ) zoom = 1 ;
148+ this . setState ( {
149+ zoom : zoom ,
150+ } )
151+ //Set last distance..
152+ this . zoomLastDistance = this . zoomCurrentDistance ;
99153 }
100154 }
101- } ,
102- } ) ;
103- Image . getSize ( this . props . image , ( width , height ) => {
104- this . setState ( {
105- imageHeight : height ,
106- imageWidth : width ,
107- } ) ;
108- } ) ;
155+ }
156+ } )
109157 }
110158 componentWillReceiveProps ( nextProps ) {
111159 if ( this . props . zoom != nextProps . zoom ) {
112160 var zoom = ( 100 - nextProps . zoom ) / 100 ;
113161 this . setState ( { zoom : zoom } ) ;
114162 }
163+
164+ //
165+ //get dimensions after crop
166+ //
167+ this . _dimensionAfterZoom = imageDimensionsAfterZoom (
168+ { height : this . props . cropHeight , width : this . props . cropWidth } ,
169+ { height : this . state . imageHeight , width : this . state . imageWidth } ,
170+ this . state . zoom
171+ )
172+
173+ this . setState ( {
174+ imageDimHeight : this . _dimensionAfterZoom . height ,
175+ imageDimWidth : this . _dimensionAfterZoom . width
176+ } )
115177 }
116178 render ( ) {
117179 return (
118180 < View { ...this . _panResponder . panHandlers } >
119181 < Surface width = { this . props . cropWidth } height = { this . props . cropHeight } ref = "cropit" >
120182 < GLImage
121- source = { { uri : this . props . image , height : this . state . imageHeight , width : this . state . imageWidth } }
183+ source = { { uri : this . props . image } }
184+ imageSize = { { height : this . state . imageHeight , width : this . state . imageWidth } }
122185 resizeMode = "cover"
123186 zoom = { this . state . zoom }
124- center = { [ this . state . centerX , this . state . centerY ] }
187+ center = { [ this . state . centerX , this . state . centerY ] }
125188 />
126189 </ Surface >
127190 </ View >
0 commit comments