You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 }],
  },
});

关键说明

  1. 拆分遮罩结构:将整体遮罩拆分为顶部、左右两侧、底部四个独立的半透明区域,中间扫码框位置无遮罩,直接显示相机画面。
  2. 扫码框仅保留边框:移除深色背景,改用白色边框标识扫描范围,同时设置backgroundColor: transparent确保完全透明。
  3. 适配不同屏幕:左右遮罩使用flex:1填充剩余宽度,中间行高度与扫码框一致,保证布局在不同设备上的一致性。

内容的提问来源于stack exchange,提问作者BloddyHell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 06:00:11