How to stretch a static image as background in React Native? - react-native

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',
},

Related

Add top corner image with react native and UI Kitten

I need to do add the green circles at the top left corner of my React Native APP:
But I don't know how to do this.
The green circles are technically a .png (I got the image)
I tried this:
<Layout style={styles.container}>
<Image source={require('../assets/style/images/Vector.png')} style={styles.topImg}/>
.......
</Layout>
const styles = StyleSheet.create({
topImg: {
position: 'absolute',
width: 200,
top: 50,
left: 50,
right: 0,
bottom: 0,
},
container: {
flex: 1,
flexDirection: 'column'
},
layout: {
justifyContent: 'center',
alignItems: 'center',
}
});
But It's not working, the green circles are not showns...
Working example: https://snack.expo.dev/#msbot01/vengeful-croissant
If you want to use image adjust the image as done for View
<View>
<View style={{backgroundColor:'green', height:100, width:100, borderRadius:100, marginTop:-50,position:'absolute', opacity:0.5}}>
</View>
<View style={{backgroundColor:'green', height:100, width:100, borderRadius:100, marginLeft:-50,position:'absolute', opacity:0.4}}>
</View>
</View>

Adding a overlaying shadow on an image

I am trying to create a shadow over the bottom part of an image like in the example I have provided. I was thinking about just overlaying a linear gradient and changing the opacity maybe, I am not even sure how accurately this would portray it but I am assuming there is a better way.
To be clear, I do NOT want to create a shadow on the outside of the image, I want it to overlay the image.
Thank you guys for any insight at all!
Linear Gradient to achieve using expo linear gradient
<View style={{borderBottomLeftRadius: 30, borderBottomRightRadius: 30, overflow: 'hidden', top: 125}}>
<LinearGradient
colors={['transparent', 'rgba(0,0,0,0.4)', ]}
style={{width: 300, height: 100,}}>
</LinearGradient>
</View>
I found a good library here to use, the usage in their example provided exactly what I am looking for with easy to use props.
https://www.npmjs.com/package/react-native-inset-shadow
import React from "react";
import { View, Image, } from "react-native";
const ShadowExample = (props) => {
const imageURL = "https://designpress-10674.kxcdn.com/wp-content/uploads/2012/10/funny-horse-pictures/happy-to-see-you.jpg"
const localStyles = {
withShadowStyle: {
justifyContent: "center",
alignItems: "center",
backgroundColor: "white",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.50,
shadowRadius: 4,
elevation: 3,
},
};
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<View style={{ ...localStyles.withShadowStyle, padding: 10, }}>
<Image source={{ uri: imageURL, }} style={{ width: 200, height: 200, }} />
</View>
</View>
)
}
P.S. Check out the React Native shadow generator:
https://ethercreative.github.io/react-native-shadow-generator/

React Native - Image inside Nested Text, Vertical Align not working

const styles = StyleSheet.create({
container: {
fontSize: 15,
alignItems: 'center',
justifyContent: 'center',
},
insideText: {
width: 30,
height: 30,
alignSelf: 'center',
},
})
<Text style={styles.container}>
<Image style={styles.insideText} source={myImage} />
test
</Text>
When I implement this functionality with Swift
Fixed by setting NSAttachment bounds.
But React Native does not know how to access those parameters.
The output of my code.
How do I center text and images?
can not divide a view into several.
Because the content is flexible, it is not known how many it will be.
Smaller image sizes will center them
The image is too small.
I want to keep the image size.
It's probably not the nicest way but you could do this:
const styles = StyleSheet.create({
container: {
fontSize: 15,
height: 30,
paddingTop: (30 - 15) / 2,
paddingLeft: 30
},
insideText: {
width: 30,
height: 30,
position: 'absolute',
left: 0,
top: 0,
},
})
Not exactly sure what you mean by the requirement of flexible content, but nesting an Image within a text does not seem like the way to go.
You'll have less styling flexibility, and are very limited.
To affect what you want without setting absolute positioning, just wrap it and have the icon and text as siblings of a parent View:
<View
style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
}}>
<Image style={styles.insideText} source={snackIcon} />
<Text style={styles.container}>test</Text>
</View>
Fortunately your styles for insideText and container are fine for this example :)
Here's a snack of the code:
https://snack.expo.io/#paullyfire/centered-image-text-container
Let me know if you have any issues.

borderRadius not working with Image uri tag in react native

I am adding a profile picture module in my app. I use borderRadius to make the image in the circle. It works fine with when I take an image from the assets folder but not working with when I render an image from URL. here is code
When image render from URL:
<View style={styles.MainContainer}>
<Image
source={{ uri: 'https://reactnativecode.com/wp-content/uploads/2018/01/2_img.png' }}
style={{ width: 150, height: 150, borderRadius: 150 / 2 }} />
</View>
When image renders from assets Folder:
<View style={styles.MainContainer}>
<Image source={require("../../assets/img/rupee.png")}
style={{ width: 150, height: 150, borderRadius: 150 / 2 }} />
</View>
Css code:
const styles = StyleSheet.create({
MainContainer:
{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
margin: 5,
paddingTop: (Platform.OS === 'ios') ? 20 : 0
}
});
After some trials, I found It was image URL problem. Image URL contains https. When I use an image URL with http instead https, It works fine and thanks guys for your effort and suggestions.
Try below code :
import React, { Component } from 'react';
import { Platform, StyleSheet, View, Image, Text } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.setFontSize}> Normal Image</Text>
<Image source={require('./images/logo.jpg')} style={styles.setBorder} />
<Text style={styles.setFontSize}> Border Radius Image</Text>
<Image source={require('./images/logo.jpg')} style={styles.setBorderRadius} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
setFontSize: {
fontSize: 20,
fontWeight : 'bold'
},
setBorder:
{
width: 170, // Setting up image width.
height: 170, // Setting up image height.
borderWidth: 3, // Set border width.
borderColor: '#F44336', // Set border Hex Color code here.
},
setBorderRadius:
{
width: 170, // Setting up image width.
height: 170, // Setting up image height.
borderWidth: 3, // Set border width.
borderColor: '#F44336', // Set border Hex Color code here.
borderRadius: 60, // Set border Radius.
}
});

React-Native: Mask image with a bottom radius

How do I make the border bottom radius in an image?
And how can I mask the image to the green area?
I've tried the following codes, but I can't get the radius ratio in the image I've shared above
View Code:
<View style={styles.wrapper}>
<View style={styles.welcomeWrapper}>
<View style={styles.welcomeImageWrapper}>
<Image style={{width:'100%'}} source={require('../assets/images/test-slide.jpg')}/>
</View>
</View>
<View style={{
height: 100,
backgroundColor: colors.white,
justifyContent: 'flex-end',
alignItems: 'center'
}}>
<Text style={{marginBottom:50,fontSize:18,fontFamily:'Montserrat-Regular'}}>Deneme Text </Text>
</View>
</View>
Style Code:
wrapper:{
flex:1,
display: 'flex',
backgroundColor:colors.white,
},
welcomeWrapper:{
flex:1,
justifyContent:'center',
backgroundColor:colors.green01,
overflow: 'hidden',
position:'relative',
width:'100%',
borderBottomRightRadius:Dimensions.get('window').width/100*50,
borderBottomLeftRadius:Dimensions.get('window').width/100*50,
},
Seeing the shape of your image mask, I think you should use something like react-native-svg to create a real image mask.
Steps:
Set the background image in a View with a position: absolute, so that your image is always in the background and can be masked
Add react-native-svg to your project, for instance with yarn add react-native-svg, and link the library using react-native link. Finally, re-launch the metro bundler and compile your app (run-android or run-ios).
Design the svg mask (I used inkscape) and add it to the container's View, the mask should have the same backgroundColor as your text container.
A bit of styling using react's flexbox layout to be able to have almost the same look on every device. In this example, the mask takes 5/6 of the screen height as my mask flex number is 5 and my text flex is 1
So, this is what I ended up with:
import * as React from 'react';
import { Dimensions, Image, StyleSheet, Text, View } from 'react-native';
import { Path, Svg } from 'react-native-svg';
const mask = {
width: Dimensions.get('window').width,
height: 50,
bgColor: '#ecf0f1',
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'flex-end',
},
image: {
position: 'absolute',
},
mask: {
flex: 5,
justifyContent: 'flex-end',
},
textContainer: {
flex: 1,
width: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: mask.bgColor,
},
text: {
fontSize: 50,
textAlign: 'center',
}
});
const App = () => (
<View style={styles.container}>
<Image style={styles.image} source={require('./assets/image.jpg')} />
<View style={styles.mask}>
<Svg width={mask.width} height={mask.height}>
<Path
fill={mask.bgColor}
d={`M 0 0 L 0 ${mask.height} L ${mask.width} ${mask.height} L ${mask.width} 0 A ${mask.width / 2} ${mask.height / 2} 0 0 1 ${mask.width / 2} ${mask.height / 2} A ${mask.width / 2} ${mask.height / 2} 0 0 1 0 0 z `} />
</Svg>
</View>
<View style={styles.textContainer}>
<Text style={styles.text}>Text</Text>
</View>
</View>
);
export default App;
And here is the result in an Android emulator
Hope this helps!
Link to snack: https://snack.expo.io/BJlZgpuB7 (but my image does not load on snack :( )