Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to cut a hole in a view using a mask #147

Open
MarioUnlam opened this issue Jan 31, 2022 · 4 comments
Open

How to cut a hole in a view using a mask #147

MarioUnlam opened this issue Jan 31, 2022 · 4 comments

Comments

@MarioUnlam
Copy link

I need to make an inverted mask. This means making a "hole" in the rendered view, instead of rendering inside the hole. Since this plugin uses alpha to define the mask, I cannot use a transparent view inside an opaque view, otherwise it will only use the opaque view as the mask. It would be better to use white instead of alpha to change the mask opacity. Is there a way to do this? Here's an example of what I want to do:

image

I want to remove the bottom part of that rectangle, using another view with rounded corners. But I'm unable to "remove" a piece of the mask. Is there any workaround?

@pedrogarciyalopez
Copy link

@MarioUnlam hello!

i need exactly the same! did you find solution?

@MarioUnlam
Copy link
Author

@pedrogarciyalopez Nope. I ended up using a squared header, and created a page wrapper component that has two backgrounds (one blue, and one white with rounded corners). A better solution would be to create a custom header with that rounded shape, using react-native-svg.

@MarioUnlam
Copy link
Author

MarioUnlam commented Feb 10, 2022

@pedrogarciyalopez The approach I used (two backgrounds in a page wrapper) didn't work well with iOS transitions, so I used an SVG header instead. Here's my implementation:

Place this code in a helper file:

import { getDefaultHeaderHeight } from '@react-navigation/elements';
import Svg, { Defs, LinearGradient, Path, Stop } from 'react-native-svg';
import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context';

const windowWidth = Dimensions.get('window').width;

const RoundedHeader = (props: any) => {
    const frame = useSafeAreaFrame();
    const insets = useSafeAreaInsets();
    const headerHeight = getDefaultHeaderHeight(frame, false, insets.top);
    const headerRoundness = 20;

    return (
        <View style={[{ width: windowWidth }, { height: headerHeight + headerRoundness }]}>
            <Svg
                preserveAspectRatio="none"
                height="100%"
                width="100%"
                viewBox={`0 0 ${windowWidth} ${headerHeight + headerRoundness}`}>
                <Defs>
                    <LinearGradient id="grad" x1="0" y1="0" x2="0" y2="90%">
                        <Stop offset="0" stopColor="#0047E4" />
                        <Stop offset="1" stopColor="#1F65FF" />
                    </LinearGradient>
                </Defs>
                <Path
                    d={`M0 0 L${windowWidth} 0 L${windowWidth} ${
                        headerHeight + headerRoundness
                    } Q${windowWidth} ${headerHeight}, ${
                        windowWidth - headerRoundness
                    } ${headerHeight} L${headerRoundness} ${headerHeight} Q0 ${headerHeight}, 0 ${
                        headerHeight + headerRoundness
                    } Z`}
                    fill="url(#grad)"
                />
            </Svg>
        </View>
    );
};

export const getRoundedHeader= () => {
    return (props: any) => {
        return <RoundedHeader />;
    };
};

then in the options of your screen or navigator, add this:

screenOptions={{
  headerBackground: getRoundedHeader(),
}}

You can change the roundness, the colors of the (vertical) gradient, or remove the <Defs> section entirely and use a plain fill color instead.

Hope it helps :)

@zabojad
Copy link

zabojad commented Aug 25, 2022

@MarioUnlam I'm gonna give a try at this that seems to be answering this need...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants