React Native Camera Kit实现扫码框透明镂空遮罩UI问题
实现带透明扫码框的半透明遮罩(react-native-camera-kit)
我正在使用react-native-camera-kit组件,想要实现如下UI效果:页面整体为半透明遮罩(背景色设置为backgroundColor: 'rgba(249, 250, 251, 0.7)'),遮罩区域中间的二维码扫描框需为透明背景。尝试将扫码框背景设为transparent或rgba(0,0,0,0.0)时,扫码框会消失,目前只能用深色背景替代,寻求实现透明扫码框的可行方法。
当前效果:扫码框为深色背景,无法清晰露出下方相机画面
期望效果:中间扫码框区域完全透明,周围是半透明遮罩,可直接看到相机拍摄内容
现有实现代码
import React from 'react'; import { View, StyleSheet } from 'react-native'; import { Camera, CameraType } from 'react-native-camera-kit'; type Props = { cameraType: CameraType; }; QRScanner.defaultProps = { cameraType: CameraType.Front, }; export default function QRScanner({ cameraType, }: Props) { const renderMyCamera = () => ( <View style={styles.container}> <Camera testID="camera" cameraType={cameraType} style={{ flex: 1, width: '100%' }} torchMode="off" scanBarcode frameColor="white" onReadCode={() => () => {}} /> </View> ); const renderQRScanUI = () => ( <View style={styles.outerArea}> <View style={styles.frame} /> <View style={styles.maskCenter}> <View style={styles.frame} /> <View style={[styles.qrBox, styles.qrBoxPortrait]} /> <View style={styles.frame} /> </View> <View style={styles.frame} /> </View> ); return ( <> {renderMyCamera()} {renderQRScanUI()} </> ); }
现有样式表代码
const styles = StyleSheet.create({ container: { position: 'absolute', width: '100%', height: '100%', }, outerArea: { position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', alignItems: 'center', justifyContent: 'space-around', backgroundColor: 'rgba(249, 250, 251, 0.7)', }, frame: { flex: 1, }, maskCenter: { flexDirection: 'row', height: 350, }, qrBox: { width: 350, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.2)', borderRadius: 10, borderTopLeftRadius: 20, borderTopRightRadius: 20, borderBottomLeftRadius: 20, borderBottomRightRadius: 20, }, qrBoxPortrait: { transform: [{ translateY: -100 }], }, });
解决方案:拆分遮罩为独立区域
React Native不支持直接的“遮罩挖空”效果,换用拆分遮罩的思路:只给上下左右四个区域添加半透明背景,中间扫码框位置留空,自然露出下方相机画面。
修改后的组件代码
import React from 'react'; import { View, StyleSheet } from 'react-native'; import { Camera, CameraType } from 'react-native-camera-kit'; type Props = { cameraType: CameraType; }; QRScanner.defaultProps = { cameraType: CameraType.Front, }; export default function QRScanner({ cameraType, }: Props) { const renderMyCamera = () => ( <View style={styles.container}> <Camera testID="camera" cameraType={cameraType} style={{ flex: 1, width: '100%' }} torchMode="off" scanBarcode frameColor="white" onReadCode={() => () => {}} /> </View> ); const renderQRScanUI = () => ( <View style={styles.maskContainer}> {/* 顶部遮罩 */} <View style={styles.topMask} /> {/* 中间行:左右遮罩 + 扫码框区域(留空) */} <View style={styles.middleRow}> <View style={styles.sideMask} /> {/* 扫码框:仅保留边框,背景透明 */} <View style={[styles.qrBox, styles.qrBoxPortrait]} /> <View style={styles.sideMask} /> </View> {/* 底部遮罩 */} <View style={styles.bottomMask} /> </View> ); return ( <> {renderMyCamera()} {renderQRScanUI()} </> ); }
修改后的样式表代码
const styles = StyleSheet.create({ container: { position: 'absolute', width: '100%', height: '100%', }, maskContainer: { position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', }, topMask: { flex: 1, backgroundColor: 'rgba(249, 250, 251, 0.7)', }, middleRow: { flexDirection: 'row', height: 350, // 与扫码框高度保持一致 }, sideMask: { flex: 1, backgroundColor: 'rgba(249, 250, 251, 0.7)', }, bottomMask: { flex: 1, backgroundColor: 'rgba(249, 250, 251, 0.7)', }, qrBox: { width: 350, borderRadius: 20, borderWidth: 2, // 添加白色边框标识扫描区域 borderColor: 'white', backgroundColor: 'transparent', // 完全透明露出相机 }, qrBoxPortrait: { transform: [{ translateY: -100 }], }, });
关键说明
- 拆分遮罩结构:将整体遮罩拆分为顶部、左右两侧、底部四个独立的半透明区域,中间扫码框位置无遮罩,直接显示相机画面。
- 扫码框仅保留边框:移除深色背景,改用白色边框标识扫描范围,同时设置
backgroundColor: transparent确保完全透明。 - 适配不同屏幕:左右遮罩使用
flex:1填充剩余宽度,中间行高度与扫码框一致,保证布局在不同设备上的一致性。
内容的提问来源于stack exchange,提问作者BloddyHell
相关产品推荐
相关产品推荐

