-
-
Save dutradotdev/50c82763fc621ab3c1bd5ba02180ce0d to your computer and use it in GitHub Desktop.
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; |
What does tw function do? Can you share example with native styles, please?
@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>
);
};
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
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;
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
<View style={{ borderRadius: 16, overFlow: "hidden" }}>
<BlurView />
</View>
how about use like this
@sayanMidknightStudio can you show me ur code?
Usage
In the same View, the first element will be behind of
BlurContainer
and the third will be overBlurContainer
.BlurContainer
has the size of parent View.About this approach
I did research to find out how to implement blur effects in View. React Native doesn’t have an easy way to do this, only for images.
Approach:
Use ImageBackground + transparent .png and blurRadius prop to create a blur container
Result: Do not work for both platforms.
Approach:
Use react-native-blur to do the blur
Cons: Lib with a lot of bugs, issues and build issues. Not a performatic approach.
Positioning elements do not work very well
References:
Kureev/react-native-blur#483
Kureev/react-native-blur#395
Approach:
Use expo-blur
Pros: Works very well for web and iOS
Cons: Do not work for android, it renders a semi-transparent View. We need to install an expo in the storybook in order to be able to build storybook
Approach:
Use react-native-skia
Result: Works only for images, you can’t use react-native elements inside
<Canvas>
Approach:
Use react-native-svg
Result: Do not work. we don’t have the tags Svg, Defs, Filter.
Approach:
Use react-native-reanimated
Result: We can’t play with blur w/ reanimated, the tag backdrop filter works only for some iOS devices.
Approach:
Use react-native-linear-gradient
Result: We can play only w/ transparency, not with blur
Approach:
Use react-native-webview and inject pure CSS to generate a View with blur
Result: Works on both platforms.