Reputation: 1051
I just started learning React-Native, I have such a problem in my current project.
I am receiving Car part image from API, this image is png
format, each part number is numbered in the picture, I also getting coordinates (coordinates(x,y), width, height) of each number. My aim is to give border and border color each number inside part picture
The problem is that these coordinates are calculated on a full-sized image, and do not match the image on mobile devices. Also the problem arises when enlarging the image, the existing coordinates are almost useless.
I will accept any offer which will give me the right point, Thanks
I want to achieve same result, but I have no idea how they are solving this problem into an existing project: link here
Reproduction Link: link here
import React from "react";
import { Animated, Dimensions, View, Image, Text} from "react-native";
import ImageZoom from 'react-native-image-pan-zoom';
import {useState} from "react";
const PinchableBox = () => {
const [scale, setScale] = useState('')
/* Part number, coordinates(x,y, width,height) */
let partPosition = {number:1,coordinates:[327,18,12,22]}
let calculated = partPosition.coordinates[0] / scale
console.log(calculated)
return (
<View>
<View style={{position:'relative'}}>
<ImageZoom
cropWidth={350}
cropHeight={290}
panToMove={true}
minScale={1}
maxScale={4}
imageHeight={300}
onMove={(e)=>setScale(e.scale)}
imageWidth={300}
style={{marginTop:0}}
>
<Image style={{ width: '100%', height: 300}}
source={{ uri: `https://img.parts-catalogs.com/bmw_2020_01/data/JPG/209412.png` }}
resizeMode="contain"
/>
</ImageZoom>
<Text
style={{
color:'red',
borderWidth:2,
height:partPosition.coordinates[3],
width:partPosition.coordinates[2],
position:'absolute',
transform:[{translateX:327 * (scale / 2 )},{translateY:18 * scale}]
}}
>{partPosition.number}
</Text>
</View>
</View>
);
};
export default PinchableBox;
Upvotes: 4
Views: 3242
Reputation: 886
import React from 'react';
import { Animated, Dimensions, View, Image, Text } from 'react-native';
import ImageZoom from 'react-native-image-pan-zoom';
import { useState } from 'react';
const PinchableBox = () => {
const [scale, setScale] = useState('');
const transformScale = { width: 300/800, height: 300/500 };
// 800 is the actual image width and 300 is width shown in screen. Same for height.
/* Part number, coordinates(x,y, width,height) */
const [textPosition, setTextPosition] = useState({
x: 315*transformScale.width,
y: 80*transformScale.height,
});
const [showText, setShowText] = useState(false);
let partPosition = {
number: 1,
coordinates: [315, 80, 20, 20],
};
const checkIfClickLiesInAnyPart = ({ x, y }) => {
const tX = x/transformScale.width;
const tY =y/transformScale.height;
let c=partPosition.coordinates;
if(tX<=c[0]+2*c[2] && tX>=c[0]-2*c[2] && tY<=c[1]+c[3] && tY>=c[1]-c[3]) return {matchedWith:1};
return {matchedWith:false};
};
const handleClick = (e) => {
console.log('clicked', e);
const {matchedWith}=checkIfClickLiesInAnyPart({ x: e.locationX, y: e.locationY })
if (matchedWith) {
setShowText(true);
setTextPosition({ x: partPosition.coordinates[0]*transformScale.width, y: partPosition.coordinates[1]*transformScale.height });
} else {
setShowText(false);
}
};
return (
<View>
<View style={{ position: 'relative' }}>
<ImageZoom
cropWidth={300}
cropHeight={300}
panToMove={true}
minScale={1}
maxScale={4}
imageHeight={300}
onMove={(e) => setScale(e.scale)}
imageWidth={300}
style={{ marginTop: 0 }}
onClick={handleClick}>
<Image
style={{ width: '300px', height: '300px' }}
source={{
uri: `https://img.parts-catalogs.com/bmw_2020_01/data/JPG/209412.png`,
}}
resizeMode="contain"
/>
// put textbox inside ImageZoom so that it also zooms / moves with image
{showText && (
<Text
style={{
color: 'red',
borderWidth: 2,
height: '20px',
width: '20px',
position: 'absolute',
left: textPosition.x + 'px',
top: textPosition.y + 'px',
}}>
1
</Text>
)}
</ImageZoom>
</View>
</View>
);
};
export default PinchableBox;
updated demo: snack.expo.dev/i5IPPbFu4 [if you click near part1, the box will be highlighted else it'll be hidden...you can modify acceptable click area too]
I have left some comments too. The sample code is for 1 part only..for multiple parts modify checkIfClickLiesInAnyPart
to check for all plus some other modifications.
Upvotes: 3