Skip to content

Commit 6aba9b5

Browse files
committed
feat(Algorithm): Changed to the better, movements impoved!
1 parent 500e6f4 commit 6aba9b5

File tree

1 file changed

+120
-57
lines changed

1 file changed

+120
-57
lines changed

src/ImageCrop.js

Lines changed: 120 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,83 @@ import {
1010
import {Surface} from 'gl-react-native'
1111
const {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+
1348
class 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

Comments
 (0)