Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed: small images for scaling problem #8761

Merged
merged 16 commits into from
Jul 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 31 additions & 21 deletions src/components/ImageView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ class ImageView extends PureComponent {
}

componentDidMount() {
if (this.canUseTouchScreen) {
return;
}
Image.getSize(this.props.url, (width, height) => {
this.setImageRegion(width, height);
});
if (this.canUseTouchScreen) {
return;
}
document.addEventListener('mousemove', this.trackMovement.bind(this));
}

Expand All @@ -65,13 +65,10 @@ class ImageView extends PureComponent {
*/
onContainerLayoutChanged(e) {
const {width, height} = e.nativeEvent.layout;
const imageWidth = this.state.imgWidth;
const imageHeight = this.state.imgHeight;
const scale = imageHeight && imageWidth ? Math.min(width / imageWidth, height / imageHeight) : 0;
this.setScale(width, height, this.state.imgWidth, this.state.imgHeight);
this.setState({
containerHeight: height,
containerWidth: width,
zoomScale: scale,
});
}

Expand Down Expand Up @@ -120,27 +117,36 @@ class ImageView extends PureComponent {
}

/**
* When open image, set image width, height and zoomScale.
* When open image, set image width, height.
* @param {Number} imageWidth
* @param {Number} imageHeight
*/
setImageRegion(imageWidth, imageHeight) {
if (imageHeight <= 0) {
return;
}
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.setScale(this.state.containerWidth, this.state.containerHeight, imageWidth, imageHeight);
this.setState({
imgWidth: width,
imgHeight: height,
zoomScale: newZoomScale,
imgWidth: imageWidth,
imgHeight: imageHeight,
});
}

/**
* @param {Number} containerWidth
* @param {Number} containerHeight
* @param {Number} imageWidth
* @param {Number} imageHeight
*/
setScale(containerWidth, containerHeight, imageWidth, imageHeight) {
if (!containerWidth || !imageWidth || !containerHeight || !imageHeight) {
return;
}
const newZoomScale = Math.min(containerWidth / imageWidth, containerHeight / imageHeight);
this.setState({zoomScale: newZoomScale});
}

/**
* Convert touch point to zoomed point
* @param {Boolean} x x point when click zoom
Expand Down Expand Up @@ -197,14 +203,18 @@ class ImageView extends PureComponent {
return (
<View
style={[styles.imageViewContainer, styles.overflowHidden]}
onLayout={this.onContainerLayoutChanged}
>
<Image
source={{uri: this.props.url}}
style={[
style={this.state.zoomScale === 0 ? undefined : [
styles.w100,
styles.h100,
]}
resizeMode="contain"
]} // Hide image until zoomScale calculated to prevent showing preview with wrong dimensions.

// When Image dimensions are lower than the container boundary(zoomscale <= 1), use `contain` to render the image with natural dimensions.
// Both `center` and `contain` keeps the image centered on both x and y axis.
resizeMode={this.state.zoomScale > 1 ? 'center' : 'contain'}
onLoadStart={this.imageLoadingStart}
onLoadEnd={this.imageLoadingEnd}
/>
Expand Down Expand Up @@ -240,10 +250,10 @@ class ImageView extends PureComponent {
>
<Image
source={{uri: this.props.url}}
style={[
style={this.state.zoomScale === 0 ? undefined : [
styles.h100,
styles.w100,
]}
]} // Hide image until zoomScale calculated to prevent showing preview with wrong dimensions.
resizeMode="contain"
onLoadStart={this.imageLoadingStart}
onLoadEnd={this.imageLoadingEnd}
Expand Down
20 changes: 3 additions & 17 deletions src/components/ImageView/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import ImageZoom from 'react-native-image-pan-zoom';
import ImageSize from 'react-native-image-size';
import _ from 'underscore';
import styles from '../../styles/styles';
import * as StyleUtils from '../../styles/StyleUtils';
import variables from '../../styles/variables';
import withWindowDimensions, {windowDimensionsPropTypes} from '../withWindowDimensions';
import FullscreenLoadingIndicator from '../FullscreenLoadingIndicator';
Expand All @@ -29,8 +28,6 @@ class ImageView extends PureComponent {

this.state = {
isLoading: false,
thumbnailWidth: 100,
thumbnailHeight: 100,
imageWidth: undefined,
imageHeight: undefined,
interactionPromise: undefined,
Expand Down Expand Up @@ -77,11 +74,7 @@ class ImageView extends PureComponent {

const aspectRatio = Math.min(containerHeight / imageHeight, containerWidth / imageWidth);

// Resize small images to fit the screen. Else resize the smaller dimension to avoid resize issue on Android - https://github.com/Expensify/App/pull/7660#issuecomment-1071622163
if (imageHeight < containerHeight && imageWidth < containerWidth) {
imageHeight *= aspectRatio;
imageWidth *= aspectRatio;
} else if (imageHeight > imageWidth) {
if (imageHeight > imageWidth) {
imageHeight *= aspectRatio;
} else {
imageWidth *= aspectRatio;
Expand Down Expand Up @@ -142,16 +135,9 @@ class ImageView extends PureComponent {
});
}}
>
<Image
source={{uri: this.props.url}}
style={StyleUtils.getWidthAndHeightStyle(this.state.thumbnailWidth, this.state.thumbnailHeight)}
resizeMode="contain"
<FullscreenLoadingIndicator
style={[styles.opacity1, styles.bgTransparent]}
/>
{this.state.isLoading && (
<FullscreenLoadingIndicator
style={[styles.opacity1, styles.bgTransparent]}
/>
)}
</View>
);
}
Expand Down