Skip to content

Instantly share code, notes, and snippets.

@dutradotdev
Last active February 16, 2024 17:44
Show Gist options
  • Save dutradotdev/50c82763fc621ab3c1bd5ba02180ce0d to your computer and use it in GitHub Desktop.
Save dutradotdev/50c82763fc621ab3c1bd5ba02180ce0d to your computer and use it in GitHub Desktop.
BlurContainer in React Native
import React from 'react';
import WebView from 'react-native-webview';
export type RGBA = `rgba(${number}, ${number}, ${number}, ${number})`;
export interface BlurContainerProps {
backgroundColor: RGBA;
blurRadius: number;
}
const BlurContainer = ({ backgroundColor, blurRadius }: BlurContainerProps) => {
return (
<WebView
style={[
tw('absolute inset-0 bg-white/0'),
{ backgroundColor: '#00000000' },
]}
source={{
html: `
<div style="position: absolute;
top: 0;
right:0;
bottom: 0;
left: 0;
background: ${backgroundColor};
-webkit-backdrop-filter: blur(${blurRadius}px);
backdrop-filter: blur(${blurRadius}px);"
/>
`,
}}
/>
);
};
export default BlurContainer;
@DinoZenka
Copy link

What does tw function do? Can you share example with native styles, please?

@dutradotdev
Copy link
Author

@DinoZenka the tw function is for tailwind. Using native styles:

Blur container component:

<WebView
      style={[
        { position: 'absolute', top: 0, bottom:0, left:0, right: 0, backgroundColor: '#00000000' },
      ]}
      source={{
        html: `
            <div style="position: absolute;
            top: 0;
            right:0;
            bottom: 0;
            left: 0;
            background: ${backgroundColor};
            -webkit-backdrop-filter: blur(${blurRadius}px);
            backdrop-filter: blur(${blurRadius}px);"
            />
      `,
      }}
    />
  );

usage:

import BlurContainer from '<your-path>';
import { Dimensions, Image, View, Text } from 'react-native';

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

  return (
    <View style={{ height: 306 }}>
      <Image
        source={{ uri: 'https://picsum.photos/id/237/200/300' }}
        style={{ width: windowWidth, height: 400, position: 'absolute', top:0, bottom:0, left:0, right: 0, zIndex:0 }
      />
      <BlurContainer backgroundColor="rgba(240, 68, 56, 0.1)" blurRadius={10} />
      <View style={{position: 'absolute', top:0, bottom:0, left:0, right: 0, borderWidth: 1}}>
        <Text style={{ textColor: 'white' ]}>testing 01</Text>
        <Text style={{ textColor: 'white' ]}>testing 02</Text>
      </View>
    </View>
  );
};

@crank-chips
Copy link

crank-chips commented Mar 15, 2023

Great solution. Though there is an issue with Android. The blurred background is flickering on scrolling (see attachment). Is there a way to fix it?
iOS works perfectly fine.

UPD:
Also, it doesn't work on the physical device, it only works on Android Emulator for some reason.

Screen.Recording.2023-03-14.at.5.04.34.PM.mov

@Aboa123
Copy link

Aboa123 commented Mar 17, 2023

If the height is too small on Android 13, the blur effect does not apply.

import BlurContainer from '<your-path>';
import { Dimensions, Image, View, Text } from 'react-native';

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

  return (
     <View style={{ height: 120  }}>
      <BlurContainer backgroundColor="rgba(240, 68, 56, 0.1)" blurRadius={10} />
     </View>
  );
};

In this code, the blur effect was ignored for Android.

import React from "react";
import { Dimensions, View } from "react-native";
import WebView from "react-native-webview";

export type RGBA = `rgba(${number}, ${number}, ${number}, ${number})`;

export interface BlurContainerProps {
	backgroundColor: RGBA;
	blurRadius: number;
}

const BlurContainer: React.FC<BlurContainerProps> = ({ backgroundColor, blurRadius }) => {
	return (
	<View
		style={{
			position: "absolute",
			top: 0,
			bottom: 0,
			left: 0,
			right: 0,
			backgroundColor: "#00000000",
			overflow: "hidden"
		}}
	>
		<WebView
			style={{
				width: "100%",
				height: "100%",
				backgroundColor: "#00000000"
			}}
			originWhitelist={["*"]}
			overScrollMode='never'
			scrollEnabled={false}
			source={{
				html: `
          <html>
            <head>
              <meta name="viewport" content="initial-scale=1.0 maximum-scale=1.0" />
              <style>
                .blur {
                  position: absolute;
                  top: 0;
                  right:0;
                  bottom: 0;
                  left: 0;
                  height: ${Dimensions.get("screen").height}px;
                  background: ${backgroundColor};
                  -webkit-backdrop-filter: blur(${blurRadius}px);
                  backdrop-filter: blur(${blurRadius}px);
                }
              </style>
            </head>
            <body>
              <div class="blur" />
            </body>
          </html>
        `
				}}
			/>
		</View>
	);
};

export default BlurContainer;

i'm sorry the code line.
the important thing is the height.

height: ${Dimensions.get("screen").height}px;

@sayanMidknightStudio
Copy link

Hi , can anyone help me ? There is a problem , when I using this this with border Radius , the blur does not appear.

Screenshot_20231012_215115_Talentverse
Screenshot_20231012_215213_Talentverse

@shav95
Copy link

shav95 commented Dec 9, 2023

@sayanMidknightStudio

import {View} from 'react-native';
import WebView from 'react-native-webview';

export type RGBA = rgba(${number}, ${number}, ${number}, ${number});

export interface BlurContainerProps {
backgroundColor: RGBA;
blurRadius: number;
borderRadius: number;
containerBorderWidth?: number;
}

const BlurContainer = ({
backgroundColor,
blurRadius,
borderRadius,
containerBorderWidth = 1,
}: BlurContainerProps) => {
return (
<View
style={{
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
}}>
<WebView
containerStyle={{}}
style={[
{
backgroundColor: '#00000000',
},
]}
originWhitelist={['*']}
overScrollMode="never"
scrollEnabled={false}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
source={{
html: `



<style>

            * {
              padding: 0;
              margin: 0;
            }
            .blur{
              position: absolute;
              width: calc(100% - ${containerBorderWidth}px);
              height: calc(100% - ${containerBorderWidth}px);
              background: ${backgroundColor};
              -webkit-backdrop-filter: blur(${blurRadius}px);
              backdrop-filter: blur(${blurRadius}px);
              border-radius: ${borderRadius}px;
            }
          </style>
        </head>
        <body>
          <div class="blur" />
        </body>
      </html>`,
    }}
  />
</View>

);
};

export default BlurContainer;

Try this solution. It helped me.

And also notice this containerBorderWidth property if you have border in your React Native View you should subtract it from div width and height

@Aboa123
Copy link

Aboa123 commented Dec 12, 2023

@sayanMidknightStudio

<View style={{ borderRadius: 16, overFlow: "hidden" }}>
   <BlurView />
</View>

how about use like this

@sayanMidknightStudio
Copy link

@Aboa123 @shav95 i did the same and all types of modification.... but every time i add borderRadious the is vanished

@Aboa123
Copy link

Aboa123 commented Dec 20, 2023

@sayanMidknightStudio can you show me ur code?

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