Skip to content

Android does not render a Mask at all #241

Description

@lucksp

Description

I am using:

    "@react-native-masked-view/masked-view": "0.3.2",
    "expo": "~52.0.32",
    "react-native": "0.76.7", // new architecture is disabled

here is my code snippet:

return (
    <View
      style={{
        flex: 1,
        position: 'absolute',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: 'rgba(0, 0, 0, 0.7)',
      }}
    >
      <MaskedView
        maskElement={
          <View
            style={{
              flex: 1,
              backgroundColor: '#00000077',
            }}
          >
            <View
              style={{
                flex: 1,
                justifyContent: 'center',
                alignItems: 'center',
              }}
            >
              <View
                style={{
                  width: Dimensions.get('window').width / 1.25,
                  height: Dimensions.get('window').width / 1.25,
                  backgroundColor: 'black',
                  borderRadius: 20,
                }}
              />
            </View>
          </View>
        }
        style={{
          flex: 1,
        }}
      >
        <CaptureView
          disableActions={true}
          enableDeviceToggle={false}
          onCapturePhoto={capturePhoto}
          showViewFinder={false}
        />
      </MaskedView>

      {/* Corner Elements */}
      <View
        style={{
          position: 'absolute',
          top: 0,
          left: 0,
          right: 0,
          bottom: 0,
          justifyContent: 'center',
          alignItems: 'center',
          pointerEvents: 'none',
        }}
      >
        <View
          style={{
            width: Dimensions.get('window').width / 1.25,
            height: Dimensions.get('window').width / 1.25,
            position: 'relative',
          }}
        >
          {/* Top Left */}
          <View
            style={{
              position: 'absolute',
              top: -2,
              left: -2,
              width: 40,
              height: 40,
              borderColor: 'white',
              borderLeftWidth: 4,
              borderTopWidth: 4,
              borderTopLeftRadius: 20,
            }}
          />
          {/* Top Right */}
          <View
            style={{
              position: 'absolute',
              top: -2,
              right: -2,
              width: 40,
              height: 40,
              borderColor: 'white',
              borderRightWidth: 4,
              borderTopWidth: 4,
              borderTopRightRadius: 20,
            }}
          />
          {/* Bottom Left */}
          <View
            style={{
              position: 'absolute',
              bottom: -2,
              left: -2,
              width: 40,
              height: 40,
              borderColor: 'white',
              borderLeftWidth: 4,
              borderBottomWidth: 4,
              borderBottomLeftRadius: 20,
            }}
          />
          {/* Bottom Right */}
          <View
            style={{
              position: 'absolute',
              bottom: -2,
              right: -2,
              width: 40,
              height: 40,
              borderColor: 'white',
              borderRightWidth: 4,
              borderBottomWidth: 4,
              borderBottomRightRadius: 20,
            }}
          />
        </View>
      </View>
    </View>
  );

I saw some other issues that seem related: #226 and #233 but I don't believe it's quite the same or something new has been introduced to cause a break??

Results

  • on iOS it looks perfect: gray mask with center box
  • on Android, there is no mask, but the border box renders OK.

Screenshots:

Image
Image

Notes

  • I tried adding the androidRenderingMode to software and then the entire screen is gray, with no mask applied.
    Any ideas?

Activity

  1. pierroo commented on Jun 10, 2025

    @pierroo

    I am facing the same issue with RN 0.79 and new arch enabled; did you find a solution since? :)

  2. lucksp commented on Jun 10, 2025

    @lucksp
    Author

    I am facing the same issue with RN 0.79 and new arch enabled; did you find a solution since? :)

    Yes. Ditched this library

  3. pierroo commented on Jun 10, 2025

    @pierroo

    sounds like a solution indeed.
    did you find an alternative or just forgot the idea? I'm open to alternatives :D

  4. lucksp commented on Jun 10, 2025

    @lucksp
    Author

    Woops needs to be reopened

  5. lucksp commented on Jun 10, 2025

    @lucksp
    Author

    sounds like a solution indeed. did you find an alternative or just forgot the idea? I'm open to alternatives :D

    import React from 'react';
    import { Dimensions, StyleSheet, View } from 'react-native';
    
    import { ComponentWithChildren } from '@/types';
    
    const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
    const viewfinderSize = screenWidth / 1.25;
    const topAreaHeight = screenHeight * 0.75;
    
    // Calculate the center position
    const centerX = (screenWidth - viewfinderSize) / 2;
    const centerY = (topAreaHeight - viewfinderSize) / 2;
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
      },
      childrenContainer: {
        ...StyleSheet.absoluteFillObject,
      },
      maskContainer: {
        ...StyleSheet.absoluteFillObject,
      },
      topArea: {
        position: 'absolute',
        top: 0,
        left: 0,
        width: screenWidth,
        height: centerY,
        backgroundColor: 'black',
      },
      leftArea: {
        position: 'absolute',
        top: centerY,
        left: 0,
        width: centerX,
        height: viewfinderSize,
        backgroundColor: 'black',
      },
      rightArea: {
        position: 'absolute',
        top: centerY,
        left: centerX + viewfinderSize,
        width: centerX,
        height: viewfinderSize,
        backgroundColor: 'black',
      },
      bottomArea: {
        position: 'absolute',
        top: centerY + viewfinderSize,
        left: 0,
        width: screenWidth,
        height: screenHeight - (centerY + viewfinderSize),
        backgroundColor: 'black',
      },
      viewfinderBorder: {
        position: 'absolute',
        top: centerY,
        left: centerX,
        width: viewfinderSize,
        height: viewfinderSize,
        backgroundColor: 'transparent',
      },
    });
    
    export const Mask = ({ children }: ComponentWithChildren) => {
      return (
        <View style={styles.container}>
          {/* Camera/content layer */}
          <View style={styles.childrenContainer}>{children}</View>
    
          {/* Mask elements that cover everything except the viewfinder */}
          <View style={styles.maskContainer}>
            <View style={[styles.topArea, { opacity: 0.5 }]} />
            <View style={[styles.leftArea, { opacity: 0.5 }]} />
            <View style={[styles.rightArea, { opacity: 0.5 }]} />
            <View style={[styles.bottomArea, { opacity: 0.5 }]} />
            <View style={styles.viewfinderBorder} />
          </View>
        </View>
      );
    };
  6. juancholt commented on Aug 7, 2025

    @juancholt

    Had the same issue, what worked for me on android was adding height and width to the MaskedView.

    <MaskedView
          style={{ height: MASK_SIZE.height, width: MASK_SIZE.width }} maskElement={<YourMask />}>
    ...whatever
    </MaskedView>
    

    Apparently without it the mask isn't rendered at all but the contents are

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions