diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 2017962b5e83..45cfe8c6c35a 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -23,7 +23,6 @@ class ImageView extends PureComponent { this.onContainerLayoutChanged = this.onContainerLayoutChanged.bind(this); this.onContainerPressIn = this.onContainerPressIn.bind(this); this.onContainerPress = this.onContainerPress.bind(this); - this.onContainerPressOut = this.onContainerPressOut.bind(this); this.imageLoadingStart = this.imageLoadingStart.bind(this); this.imageLoadingEnd = this.imageLoadingEnd.bind(this); this.state = { @@ -40,10 +39,6 @@ class ImageView extends PureComponent { imgWidth: 0, imgHeight: 0, zoomScale: 0, - imageLeft: 0, - imageTop: 0, - imageRight: 0, - imageBottom: 0, }; } @@ -98,85 +93,51 @@ class ImageView extends PureComponent { * @param {SyntheticEvent} e */ onContainerPress(e) { - if (this.state.isZoomed && !this.state.isDragging) { + let scrollX; + let scrollY; + if (!this.state.isZoomed && !this.state.isDragging) { const {offsetX, offsetY} = e.nativeEvent; - const delta = this.getScrollOffset(offsetX, offsetY); - const sX = delta.offsetX; - const sY = delta.offsetY; - this.scrollableRef.scrollTop = sY * this.state.zoomScale; - this.scrollableRef.scrollLeft = sX * this.state.zoomScale; + + // Dividing clicked positions by the zoom scale to get coordinates + // so that once we zoom we will scroll to the clicked location. + const delta = this.getScrollOffset(offsetX / this.state.zoomScale, offsetY / this.state.zoomScale); + scrollX = delta.offsetX; + scrollY = delta.offsetY; } if (this.state.isZoomed && this.state.isDragging && this.state.isMouseDown) { this.setState({isDragging: false, isMouseDown: false}); + } else { + // We first zoom and once its done then we scroll to the location the user clicked. + this.setState(prevState => ({ + isZoomed: !prevState.isZoomed, + isMouseDown: false, + }), () => { + this.scrollableRef.scrollTop = scrollY; + this.scrollableRef.scrollLeft = scrollX; + }); } } - onContainerPressOut() { - if (this.state.isDragging) { - return; - } - - this.setState(prevState => ({ - isZoomed: !prevState.isZoomed, - isMouseDown: false, - })); - } - /** - * When open image, set image left/right/top/bottom point and width, height + * When open image, set image width, height and zoomScale. * @param {Number} imageWidth * @param {Number} imageHeight */ setImageRegion(imageWidth, imageHeight) { - let width = imageWidth; - let height = imageHeight; - const containerHeight = this.state.containerHeight; - const containerWidth = this.state.containerWidth; - - // return if image not loaded yet - if (imageHeight <= 0 || containerHeight <= 0) { + if (imageHeight <= 0) { return; } - - // Fit the image to container size if image small than container. - const aspectRatio = Math.min(containerHeight / imageHeight, containerWidth / imageWidth); - if (aspectRatio > 1) { - width *= (aspectRatio); - height *= (aspectRatio); - } - let imgLeft = (this.props.windowWidth - width) / 2; - let imgRight = ((this.props.windowWidth - width) / 2) + width; - let imgTop = (this.props.windowHeight - height) / 2; - let imgBottom = ((this.props.windowHeight - height) / 2) + height; - const isScreenWiderThanImage = (this.props.windowWidth / width) > 1; - const isScreenTallerThanImage = (this.props.windowHeight / height) > 1; - const aspect = width / height; - if (aspect > 1 && !isScreenWiderThanImage) { - // In case Width fit Screen width and Height not fit the Screen height - const fitRate = this.props.windowWidth / width; - imgLeft = 0; - imgRight = this.props.windowWidth; - imgTop = (this.props.windowHeight - (fitRate * height)) / 2; - imgBottom = imgTop + (fitRate * height); - } else if (aspect <= 1 && !isScreenTallerThanImage) { - // In case Height fit Screen height and Width not fit the Screen width - const fitRate = this.props.windowHeight / height; - imgTop = 0; - imgBottom = this.props.windowHeight; - imgLeft = (this.props.windowWidth - (fitRate * width)) / 2; - imgRight = imgLeft + (fitRate * width); - } - + const containerHeight = this.state.containerHeight; + const containerWidth = this.state.containerWidth; + const width = imageWidth; + const height = imageHeight; const newZoomScale = Math.min(containerWidth / width, containerHeight / height); + this.setState({ imgWidth: width, - zoomScale: newZoomScale, imgHeight: height, - imageLeft: imgLeft, - imageTop: imgTop, - imageRight: imgRight, - imageBottom: imgBottom, + zoomScale: newZoomScale, }); } @@ -187,31 +148,23 @@ class ImageView extends PureComponent { * @returns {Object} converted touch point */ getScrollOffset(x, y) { - let fitRatio = 1; - if (this.state.imageTop === 0) { - // Fit Height - fitRatio = this.props.windowHeight / this.state.imgHeight; - } else if (this.state.imageLeft === 0) { - // Fit Width - fitRatio = this.props.windowWidth / this.state.imgWidth; - } - let sx = (x - this.state.imageLeft) / fitRatio; - let sy = (y - this.state.imageTop) / fitRatio; + let offsetX; + let offsetY; - // White blank touch - if (x < this.state.imageLeft) { - sx = 0; - } - if (x > this.state.imageRight) { - sx = this.state.imgWidth; - } - if (y < this.state.imageTop) { - sy = 0; + // Container size bigger than clicked position offset + if (x <= this.state.containerWidth / 2) { + offsetX = 0; + } else if (x > this.state.containerWidth / 2) { + // Minus half of container size because we want to be center clicked position + offsetX = x - (this.state.containerWidth / 2); } - if (y > this.state.imageBottom) { - sy = this.state.imgHeight; + if (y <= this.state.containerHeight / 2) { + offsetY = 0; + } else if (y > this.state.containerHeight / 2) { + // Minus half of container size because we want to be center clicked position + offsetY = y - (this.state.containerHeight / 2); } - return {offsetX: sx, offsetY: sy}; + return {offsetX, offsetY}; } trackMovement(e) { @@ -284,7 +237,6 @@ class ImageView extends PureComponent { }} onPressIn={this.onContainerPressIn} onPress={this.onContainerPress} - onPressOut={this.onContainerPressOut} >