Last active
February 5, 2024 08:46
-
-
Save dytra/db72996bf52de9fb169180b27268fb25 to your computer and use it in GitHub Desktop.
TouchableImageMapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { calculateAspectRatio } from "./forms/Upload"; | |
import { Dimensions } from "react-native"; | |
import ImageMapper from 'react-native-image-mapper'; | |
/** | |
* TouchableImageMapper Component Props. | |
* @interface | |
*/ | |
interface TouchableImageMapper { | |
/** | |
* Width of the original image. | |
* @type {number} | |
*/ | |
imageWidth: number; | |
/** | |
* Height of the original image. | |
* @type {number} | |
*/ | |
imageHeight: number; | |
/** | |
* Source of the image. | |
* @type {any} | |
*/ | |
imageSource: any; | |
/** | |
* Mapping of touchable areas on the image. | |
* @type {object} | |
*/ | |
mapping: object; | |
/** | |
* Callback function when a touchable area is pressed. | |
* @type {(item: any, idx: number, event: any) => void} | |
*/ | |
onPress?: (item: any, idx: number, event: any) => void; | |
/** | |
* Id of the initially selected touchable area. | |
* @type {string} | |
*/ | |
selectedAreaId?: string; | |
} | |
const TouchableImageMapper: React.FC<TouchableImageMapper> = ({ | |
imageWidth, | |
imageHeight, | |
mapping, | |
imageSource, | |
onPress, | |
selectedAreaId | |
}) => { | |
const { newImageWidth, newImageHeight } = useCalculateNewImageDimension(imageWidth, imageHeight); | |
const handlePress = (item: any, idx: number, event: any) => { | |
if (!onPress) return; | |
onPress(item, idx, event) | |
} | |
return ( | |
<> | |
<ImageMapper | |
imgWidth={"100%"} | |
imgHeight={newImageHeight} | |
imgSource={imageSource} | |
imgMap={mapping} | |
onPress={handlePress} | |
containerStyle={{ | |
width: "100%", | |
}} | |
selectedAreaId={selectedAreaId} | |
/> | |
</> | |
) | |
} | |
function useCalculateNewImageDimension(imageWidth: number, imageHeight: number) { | |
const aspectR = calculateAspectRatio(imageWidth, imageHeight); | |
const aspectRatioW = parseInt(aspectR.split(":")[0]); | |
const aspectRatioH = parseInt(aspectR.split(":")[1]); | |
let aspectRatioNum = aspectRatioW / aspectRatioH; | |
const windowWidth = Dimensions.get('window').width; | |
const newImageWidth = windowWidth; | |
const newImageHeight = newImageWidth / aspectRatioNum; | |
return { | |
newImageWidth, | |
newImageHeight, | |
} | |
} | |
export function calculateAspectRatio(width: number, height: number) { | |
if (width > 0 && height > 0) { | |
const gcd = function (a: number, b: number) { | |
return b === 0 ? a : gcd(b, a % b); | |
}; | |
const aspectRatio = `${width / gcd(width, height)}:${height / gcd(width, height)}`; | |
return aspectRatio; | |
} else { | |
return "Invalid dimensions. Width and height must be positive numbers."; | |
} | |
} | |
export default TouchableImageMapper; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment