diff --git a/README.md b/README.md index d030d7f..2c57d83 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ React Native Scalable Image =========================== -React Native `````` component [does not keep image aspect ratio](https://github.com/facebook/react-native/issues/858) which results in the image being stretched or cropped. ```react-native-scalable-image``` solves this problem by calculating the image size and resizing the image when rendering. +React Native `````` component [does not keep the image aspect ratio](https://github.com/facebook/react-native/issues/858), which results in the image being stretched or cropped. ```react-native-scalable-image``` solves this problem by calculating the image size and resizing the image when rendering. This library provides an `````` component which scales width or height automatically to keep the aspect ratio. It is useful when you don't know the aspect ratio in advance (e.g. user-uploaded content) but want to display the entire image and limit it only by width or height to fit the container component. @@ -38,12 +38,13 @@ Specify width or height which may be calculated dynamically like in the example | `width` | number | none | Maximum image width | | `background` | boolean | false | Set to true when used as a background | | `onPress` | function | none | onPress callback | -| `onSize` | function | none | Is called with ```{ width, height }``` as the arg when image size is calculated | +| `onSize` | function | none | Is called with ```{ width, height }``` as the first arg once image size is calculated | Versions ======== +The latest major version of `react-native-scalable-image` is implemented with hooks. If you are using a pre-hooks React version please use `react-native-scalable-image` version `0.5.1` -| React Native Version | Scalable Image Version | -| -------------------- | ---------------------- | -| <= 0.58 | <= 0.5.1 | -| >= 0.59 | 0.6.0 | +| React Version | Scalable Image Version | +| ------------- | ---------------------- | +| < 16.8 | 0.5.1 | +| >= 16.8 | > 1.0.0 | diff --git a/index.js b/index.js index 648afbc..3ca7cb6 100644 --- a/index.js +++ b/index.js @@ -1,67 +1,108 @@ -import React, { useState, useEffect, useRef } from 'react'; -import { Image, TouchableOpacity, ImageBackground } from 'react-native'; +import React, { + useState, + useEffect, + useRef +} from 'react'; + +import PropTypes from 'prop-types'; + +import { + Image, + TouchableOpacity, + ImageBackground +} from 'react-native'; + const resolveAssetSource = Image.resolveAssetSource; -export default (props) => { - const ImageComponent = props.background ? ImageBackground : Image; +const ScalableImage = props => { + const ImageComponent = props.background + ? ImageBackground + : Image; - const [scalableWidth, setScalableWidth] = useState(null); - const [scalableHeight, setScalableHeight] = useState(null); - const [image, setImage] = useState(); - const mounted = useRef(false); + const [scalableWidth, setScalableWidth] = useState(null); + const [scalableHeight, setScalableHeight] = useState(null); + const [image, setImage] = useState(); + const mounted = useRef(false); - useEffect(() => { - mounted.current = true; + useEffect(() => { + mounted.current = true; - return () => { - mounted.current = false; - } - }, []); - - useEffect(() => { - onProps(props); - }) - - useEffect(() => { - setImage(); - }, [props, scalableHeight, scalableWidth]); - - const onProps = (localProps) => { - const { source } = localProps; - if (source.uri) { - const sourceToUse = source.uri ? source.uri : source; - Image.getSize(sourceToUse, (width, height) => adjustSize(width, height, props), e => console.log(e)); - } else { - const sourceToUse = resolveAssetSource(source); - adjustSize(sourceToUse.width, sourceToUse.height, props); + return () => { + mounted.current = false; + } + }, []); + + useEffect(() => { + onProps(props); + }); + + useEffect(() => { + setImage( + + ); + }, [props, scalableHeight, scalableWidth]); + + const onProps = localProps => { + const { source } = localProps; + if (source.uri) { + const sourceToUse = source.uri + ? source.uri + : source; + + Image.getSize( + sourceToUse, + (width, height) => adjustSize(width, height, props), + console.err + ); + } + else { + const sourceToUse = resolveAssetSource(source); + adjustSize(sourceToUse.width, sourceToUse.height, props); + } + }; + + const adjustSize = (sourceWidth, sourceHeight, localProps) => { + const { width, height } = localProps; + + let ratio = 1; + + if (width && height) { + ratio = Math.min(width / sourceWidth, height / sourceHeight); + } + else if (width) { + ratio = width / sourceWidth; + } + else if (height) { + ratio = height / sourceHeight; + } + + if (mounted.current) { + const computedWidth = sourceWidth * ratio; + const computedHeight = sourceHeight * ratio; + + setScalableWidth(computedWidth); + setScalableHeight(computedHeight); + + props.onSize({ width: computedWidth, height: computedHeight }); + } + }; + + if (!props.onPress) { + return image; } - }; - - const adjustSize = (sourceWidth, sourceHeight, localProps) => { - const { width, height } = localProps; - - let ratio = 1; - - if (width && height) ratio = Math.min(width / sourceWidth, height / sourceHeight); - else if (width) ratio = width / sourceWidth; - else if (height) ratio = height / sourceHeight; - if (mounted.current) { - const computedWidth = sourceWidth * ratio; - const computedHeight = sourceHeight * ratio; - setScalableWidth(computedWidth); - setScalableHeight(computedHeight); - props.onSize({ width: computedWidth, height: computedHeight }); + else { + return ( + + {image} + + ); } - }; - - if (!props.onPress) return image; - else { - return ( - - {image} - - ) - }; }; ScalableImage.propTypes = { @@ -76,3 +117,5 @@ ScalableImage.defaultProps = { background: false, onSize: size => {} }; + +export default ScalableImage; diff --git a/package.json b/package.json index 670198e..d18b60b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-scalable-image", - "version": "0.6.0", + "version": "1.0.0", "license": "MIT", "description": "React Native Image component which scales width or height automatically to keep the aspect ratio", "keywords": [