Reputation: 183
I was trying to make a QR code marker like this pic below.
So I'm wondering how to make those 4 corners instead of a full border marker.
I was currently using react-native-qrcode-scanner.
The default marker is like this:
and here is the code that I have:
<QRCodeScanner
// containerStyle={{ height: '100%' }}
// cameraStyle={{ height: '100%' }}
onRead={handleScan}
showMarker
markerStyle={{ borderColor: colors.primary, borderRadius: 20 }}
cameraProps={{
captureAudio: false,
flashMode: RNCamera.Constants.FlashMode.auto,
}}
But I want to change it to the first image I gave.
Appreciate it if someone could help. Thanks
Upvotes: 5
Views: 7682
Reputation: 386
For anyone using expo camera (which is the recommended way of doing QRCode reading in 2024) and needing the same result. I tried some of the answers previously answered and based on those I was able to achieve the style.
It might be helpful.
This is the jsx component:
<View style={styles.container}>
{isCameraViewOpen ? (
<>
<CameraView
mode="video"
onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
barcodeScannerSettings={{
barcodeTypes: ["qr", "pdf417"],
}}
style={StyleSheet.absoluteFillObject}
/>
<View style={[styles.border]}>
<View style={[styles.corner, styles.topLeft]} />
<View style={[styles.corner, styles.topRight]} />
<View style={[styles.corner, styles.bottomLeft]} />
<View style={[styles.corner, styles.bottomRight]} />
</View>
{scanned && (
<Button
title={"Tap to Scan Again"}
onPress={() => setScanned(false)}
/>
)}
</>
) : (
<View>
<Text>Camera nao visível</Text>
</View>
)}
</View>
and this is the stylesheet for the component above. Make the adjustments that you might need:
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
},
corner: {
width: 60, // Adjust the width of the corner dashes
height: 60, // Adjust the height of the corner dashes
borderWidth: 2,
borderColor: "red",
position: "absolute",
borderRadius: 2,
},
topLeft: {
top: -1,
left: -1,
borderRightWidth: 0,
borderBottomWidth: 0,
},
topRight: {
top: -1,
right: -1,
borderLeftWidth: 0,
borderBottomWidth: 0,
},
bottomLeft: {
bottom: -1,
left: -1,
borderRightWidth: 0,
borderTopWidth: 0,
},
bottomRight: {
bottom: -2,
right: -1,
borderLeftWidth: 0,
borderTopWidth: 0,
},
border: {
width: 300,
height: 300,
borderWidth: 0,
borderRadius: 10,
borderColor: "blue",
position: "relative",
},
})
Upvotes: 1
Reputation: 21
This is what I have recently used:
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>
</View>
<View style={[styles.border,
{
width: qrCodeDimensions.width || 250,
height: qrCodeDimensions.height || 250,
},
]}>
<View style={[styles.corner, styles.topLeft]} />
<View style={[styles.corner, styles.topRight]} />
<View style={[styles.corner, styles.bottomLeft]} />
<View style={[styles.corner, styles.bottomRight]} />
</View>
<View style={styles.tap}>
{scanned && (
<Button
title='Tap to Scan Again' onPress={() => setScanned(false)} />
)}
//style: frameContainer: { position: 'relative', flex: 1, justifyContent: 'center', alignItems: 'center',
},
corner: {
width: 30, // Adjust the width of the corner dashes
height: 30, // Adjust the height of the corner dashes
borderWidth: 5,
borderColor: color.primary,
position: 'absolute',
borderRadius: 2
},
topLeft: {
top: -1,
left: -1,
borderRightWidth: 0,
borderBottomWidth: 0,
},
topRight: {
top: -1,
right: -1,
borderLeftWidth: 0,
borderBottomWidth: 0,
},
bottomLeft: {
bottom: -1,
left: -1,
borderRightWidth: 0,
borderTopWidth: 0,
},
bottomRight: {
bottom: -2,
right: -1,
borderLeftWidth: 0,
borderTopWidth: 0,
},
border: {
width: 200,
height: 200,
borderWidth: 0,
borderRadius: 10,
borderColor: 'gray',
position: 'relative',
},
Upvotes: 1
Reputation: 390
QRCodeScanner
has a customMarker
prop which allows you to use any JSX.Element
as marker.
Here is what I am currently using myself:
function marker(color: string, size: string | number, borderLength: string | number, thickness: number = 2, borderRadius: number = 0): JSX.Element {
return <View style={{ height: size, width: size }}>
<View style={{ position: 'absolute', height: borderLength, width: borderLength, top: 0, left: 0, borderColor: color, borderTopWidth: thickness, borderLeftWidth: thickness, borderTopLeftRadius: borderRadius }}></View>
<View style={{ position: 'absolute', height: borderLength, width: borderLength, top: 0, right: 0, borderColor: color, borderTopWidth: thickness, borderRightWidth: thickness, borderTopRightRadius: borderRadius }}></View>
<View style={{ position: 'absolute', height: borderLength, width: borderLength, bottom: 0, left: 0, borderColor: color, borderBottomWidth: thickness, borderLeftWidth: thickness, borderBottomLeftRadius: borderRadius }}></View>
<View style={{ position: 'absolute', height: borderLength, width: borderLength, bottom: 0, right: 0, borderColor: color, borderBottomWidth: thickness, borderRightWidth: thickness, borderBottomRightRadius: borderRadius }}></View>
</View>
}
Which, in your case could be used like this:
<QRCodeScanner
...
customMarker={marker('white', '60%', '25%', 6, 20)}
/>
Upvotes: 9
Reputation: 12225
if it would have been a straight line, it would have been easy by putting border radius. But since its bit different , you can achieve this by using this library :
RN-svg , where you can provide the xml pattern and it will render acordingly, just you need to position beside the marker, that's it.
Hopeit helps. feel free for doubts
Upvotes: 3