I'm trying to create a 'focus' effect on images in React Native, but I'm unable to create this effect using Blur and Overlay.
Does anyone know how it might be done .. ?
Here's an example of what I had in mind:
You may checkout the react-native-blur library.
Their example shows a blurred background with buttons on top. You could easily place an image on the blur instead of buttons.
Hope that helps.
https://github.com/react-native-community/react-native-blur
npm i react-native-blur-overlay use this library and there are several properties to partially blur your images accordingly how you need it.
use MaskedView from #react-native-masked-view/masked-view along with BlurView from #react-native-community/blur to get this result
snack link
result:
code:
export default function App() {
const { width, height } = useWindowDimensions();
return (
<View style={styles.container}>
<MakedView
style={{ width, height, alignItems: 'center' }}
maskElement={
<BlurView
tint="dark"
intensity={54}
style={{
width,
height,
backgroundColor: 'transparent',
alignItems: 'center',
justifyContent: 'center',
}}>
<View
style={{
width: 200,
height: 200,
borderRadius: 100,
backgroundColor: '#fff',
}}></View>
</BlurView>
}>
<Image
style={{ width, height, backgroundColor: 'transparent' }}
source={{
uri: 'https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg',
}}
/>
</MakedView>
</View>
);
}
Related
I am making a react native app, and I'm having trouble getting an image to fade at the edges so that it blends into the background. I want it to look like the Netflix app, where the image doesn't end, but just fades into black Netflix image. I have tried wrapping my image component in a linear gradient, but that doesn't get rid of the hard edges of the image. I have to turn to opacity of the image all the way down to 0.1 to get that, which just destroys the quality of the image.
Here is the code for the component:
<LinearGradient
colors={["black", "white", "black"]}
locations={[0.2, 0.5, .8]}
>
<Image
key={image}
source={{ uri: image }}
style={styles.backgroundImage}
/>
</LinearGradient>
and the styles:
imageGradient: {
height: "70%",
marginTop: 150,
justifyContent: "center"
},
backgroundImage: {
height: "80%",
width: DEVICE_WIDTH,
opacity: 0.8
}
Rather than trying to make the Image partially transparent, you can make the LinearGradient on top of the Image transparent near the bottom.
For example:
import * as React from 'react';
import { Text, View, StyleSheet, Image } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import Constants from 'expo-constants';
export default function App() {
return (
<View style={styles.container}>
<View>
<Image style={{width: 300, height: 300}} source={require('./assets/snack-icon.png')} />
<LinearGradient
colors={['transparent','rgba(0,0,0,1.0)']}
style={{position: 'absolute', width: '100%', height: '100%'}}
/>
</View>
<Text style={styles.paragraph}>
Change code in the editor and watch it change on your phone! Save to get a shareable url.
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: 'black',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
color: 'white'
},
});
Snack link: https://snack.expo.dev/IWy50EQiX
Render Linear gradient absolutely above the image
also the colors should not be white, if you want the transparent color then use #00000000 to give transparent gradient
colors={['#000000', '#00000000', '#000000']}
Snack Link
code :
<View>
<Image
source={{
uri: 'https://miro.medium.com/max/1400/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg',
}}
style={styles.backgroundImage}
/>
<LinearGradient
style={{ ...StyleSheet.absoluteFillObject }}
colors={['#000000', '#00000000', '#000000']}
locations={[0.2, 0.5, 0.8]}
/>
</View>
I have a component that when called should display an image for the whole screen of the phone. The issue is I cannot get the image centered. It is mostly off screen to the right with some barely visible. If anyone knows what I am doing wrong your help would be much appreciated. I am using react-native-image-zoom so the image can be zoomed on and swiped down to go away.
My image component:
const FullPicture = (props) => {
return (
<View style={{ height: '100%', width: '100%' }}>
<ImageZoom
cropWidth={Dimensions.get('window').width}
cropHeight={Dimensions.get('window').height}
enableSwipeDown
onSwipeDown={() => props.closeImage()}
>
<Image
style={{ height: props.picture.height, width: props.picture.width }}
resizeMode={'cover'}
source={{ uri: props.picture.uri }}
/>
</ImageZoom>
</View>
);
};
You need to use a Flexbox. Try to add flex: 1 to your Image's container:
<View style={{ flex: 1, height: '100%', width: '100%' }}>
<ImageZoom> ... </ImageZoom>
</View>
Try these:
set flex: 1 in your container view
use justifyContent: 'center'
check this out.
I think this is the thing what you are looking for https://youtu.be/YRrji3BmHY4
you should use ImageBackground from react-native instead of react-native-image-zoom.
when you use ImageBackground don't forget resizeMode='contain' and styling the image, the image will not get off by any side.
I'm trying to make a clock component with a face image and a needle centered on the clock in React Native.
does not allow embedding other Images.
I found a few posts for centering text over images but cannot find any way do center Image over images.
Edit:
I'm trying to find a way that avoids giving absolute position so the component can be dynamically sized.
If i understood correctly, you want to show one image over other image. With one as a Parent image and other as a child image without using absolute postion.
For this you can use ImageBackground Component provided by react-native and by setting its height and width with percentage value.
Below is the example :
Parent Image : Clock.png is an ImageBackground Component
Child Image : Needle.png is an Image Component
import React, { Component } from 'react'
import { StyleSheet, View, Text, ImageBackground, Image } from 'react-native'
export default class ImageView extends Component {
render() {
return (
<View
style={{
flex: 1
}}
>
<View
style={{
flex: 0.25,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'red'
}}
>
<Text style={{ color: 'white', fontSize: 26 }}>I am Header</Text>
</View>
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
// backgroundColor: 'blue',
borderWidth: 1,
borderColor: 'red'
}}
>
<ImageBackground
source={require('#assets/Clock.png')}
style={{
height: '60%',
width: '100%'
}}
resizeMode="contain"
>
<Image
style={{
marginTop: '4.5%',
alignSelf: 'center',
height: '30%',
width: '100%'
}}
resizeMode="contain"
source={require('#assets/Needle.png')}
/>
</ImageBackground>
</View>
</View>
)
}
}
Same as you would handle this in regular old html,css.
Use position:absolute then align the items so that they match how you expect.
react-native : I have one View and the child of View is an Image , I applied opacity: 0.5 for View and opacity: 0.9 for an Image but it doesn't apply for Image ,the parent opacity is applying for child , the child doesn't take independent opacity
Try changing the opacity using alpha-value of the background color instead. Then it should be possible applying different opacities for children.
For example:
<View style={{backgroundColor: 'rgba(0,0,0,0.5)'}}/>
React-Native 0.60+
There is a new opacity prop that you can pass in:
<View style={{opacity: 0.5}} />
React-Native 0.59.x and lower
Like this (with 50% at the end of color hash):
<View style={{backgroundColor: '#FFFFFF50'}} />
Or RGBa way:
<View style={{backgroundColor: 'rgba(0,0,0,0.5)'}} />
In react-native 0.6, you can use the opacity prop on a View. Example:
<View opacity={1.0} />
<View opacity={0.5} />
1.0 = opaque (alpha == 1.0)
0.0 = clear (alpha == 0.0)
See https://facebook.github.io/react-native/docs/0.6/view-style-props#opacity
Snack: https://snack.expo.io/S1KjXqe6N
If you want to display some text with transparent alpha opacity then I have the best way, just try.
TransparentBG:{
backgroundColor: '#00000070',
color:'#FFFFFF'
}
here, "70" indicates opacity %.
-Thanks
You need to use needsOffscreenAlphaCompositing like this-
<View needsOffscreenAlphaCompositing>
...
<View/>
If you want to change the opacity of a view that doesn't recognize the opacity prop (such as a TouchableOpacity), wrap it in a View first and change the opacity prop of that.
<View opacity={0.3}>
<TouchableOpacity>
</TouchableOpacity>
</View>
You can't change parent opacity without affecting child, so you should have absolute positioned background. For proper child positioning, you should add an additional container. Check out this snack: snack.expo.io/SkaHLjzr8
...
<View style={styles.container}>
<View style={styles.card} >
<View style={styles.background} />
<View style={styles.imageContainer}>
<Image style={styles.image} source="..." />
</View>
</View>
</View>
...
...
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
background: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'blue',
opacity: .5,
zIndex: 1,
},
card: {
height: 400,
},
imageContainer: {
...StyleSheet.absoluteFillObject,
justifyContent: 'center',
alignItems: 'center',
zIndex: 2,
opacity: 0.8,
},
image: {
width: 200,
height: 200
}
...
HACK FOR BACKGROUNDS OPACITY
Use combination of 2 backgroundColor in order to imitate the opacity
After playing sometimes and be lost on the internet to find a simple solucion, I realized that at the current React-Native Version V 0.64 the opacity for the backgrounds, at least as it is commonly used for Web Dev just is not suited for React-Native.
APP
Use ImageBackground Component --> DOCS:
Set you background image on the ImageBackground
import React from 'react';
import { ImageBackground, View, Text, StyleSheet, ScrollView} from 'react-native';
const App = () => {
return (
<ImageBackground style={ mainStyle.background } source={ { uri: "https://reactjs.org/logo-og.png" } } resizeMode="cover">
<ScrollView style={ mainStyle.overlay }> // Here its style will be used as opacity
<View style={ mainStyle.containerCenter}>
<View style={ mainStyle.homeTitleWraper}>
<Text style={ mainStyle.homeTitle }> Hello WOrld</Text>
</View>
</View>
</ScrollView>
</ImageBackground>
);};
export default App;
Style
Style, Here the First Child of the Background has to take the whole
screen size, with style overlay it will lay down like a thin blanket on top of the Background, imitating the opacity.
const mainStyle = StyleSheet.create({
background: {
width: "100%",
height: "100%",
},
overlay: {
backgroundColor: 'rgba(255, 255, 255, .5)' // HERE USE THE LAST DIGIT AS IF IT WERE OPACITY
},
containerCenter : {
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
paddingHorizontal: 30,
marginVertical: 60,
},
homeTitleWraper: {
paddingHorizontal: 40,
paddingVertical: 100,
},
homeTitle: {
fontSize: 40,
fontWeight: "900",
textAlign: "center",
textTransform: "uppercase",
color: "white",
fontStyle: "italic",
},
containerSmall: {
marginVertical: 10,
width: "100%"
}
I'd like to use a background image in my react native app,
the image is smaller than the screen, so I have to stretch it.
but it doesn't work if the image is loaded from asset bundle
var styles = StyleSheet.create({
bgImage: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'stretch',
resizeMode: 'stretch',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
}
});
<Image source={require('image!background')} style={styles.bgImage}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
</Image>
it looks like this:
however, it works fine for a remote image, through source={{uri: 'background-image-uri'}}:
From Github issue: Image {require} is broken in React Native for Resizing, you could try <Image style={{width: null, height: null}}, hope that facebook would fix it soon.
The Image tag should generally not be treated as a container view.
Having an absolutely positioned wrapper containing your (stretched/contained) image appears to work well:
var styles = StyleSheet.create({
bgImageWrapper: {
position: 'absolute',
top: 0, bottom: 0, left: 0, right: 0
},
bgImage: {
flex: 1,
resizeMode: "stretch"
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10
}
});
<View style={{ flex: 1 }}>
<View style={styles.bgImageWrapper}>
<Image source={require('image!background')} style={styles.bgImage} />
</View>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
</View>
You could always use the Dimensions module to get the width of the screen and set your image's width style to that value:
var Dimensions = require('Dimensions');
var {width, height} = Dimensions.get('window');
It also seems strange that a remote image works fine...you can try loading up a local static image with the uri syntax by using source={{uri: 'local_image_file_name' isStatic: true}}.
for me use undefined instead of null value. on typescript environment, it will be prompted not assignable
bgImage: {
flex: 1,
width: undefined,
height: undefined,
resizeMode: 'stretch',
},