How to overlay text on card Image in React Native? - reactjs

I want to add text on Card Image and want to control the text position over the image of the Card.
When i use featuredSubtitle={"Helo"} that give the text over image but i cant control the position.
Here is the sample image from food Panda app. How can i add Flat 50 etc on my Card Image
<Card featuredSubtitle={"Helo"} image={{uri: 'https://www.papajohns.com.pk/binary_resources/10484676'}}>
<Text style={{ fontSize: 20,fontWeight: 'bold'}}>
{"Papa Jhon's - Johar Town"}
</Text>
<Text style={{}}>
{"$$$, Italian, Panda Picks, Thin Crust Pizza, Take Away"}
</Text>
<Text style={{textShadowColor: 'red', textShadowRadius: 3, textDecorationLine: 'line-through'}}>
{"Rs: 390 | Rs: 50 Delivery"}
</Text>
<Text style={{textShadowColor: '#88f549', textShadowRadius: 3,}}>
{"Rs: 290 minimum | Free Delivery"}
</Text>
</Card>

You can achieve it by absolute position. You specifically asked for Card component. but this approach works on all views. Here you can refer this snack. I built this with card component using react-native-card
import * as React from 'react';
import {
Text,
View,
StyleSheet,
Image,
Dimensions,
ImageBackground,
} from 'react-native';
import Constants from 'expo-constants';
import { Card } from 'react-native-paper';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Card style={{ width: '100%', height: '50%', borderRadius: 10 }}>
<ImageBackground
style={{
width: '100%',
height: '80%',
resizeMode: 'contain',
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
}}
source={{
uri:'https://images.unsplash.com/photo-1522057306606-8d84daa75e87?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=967&q=80',
}}
/>
{/** top-right corner */}
<View style={{ position: 'absolute', top: 0, right: 0 }}>
<Text
style={{
fontSize: 20,
color: 'black',
backgroundColor: 'white',
}}>
35 mins
</Text>
</View>
{/** top -left */}
<View style={{ position: 'absolute', top: 10, left: 0 }}>
<Text
style={{ fontSize: 20, color: 'white', backgroundColor: 'red' }}>
Flat 50%
</Text>
</View>
<View style={{ position: 'absolute', top: 40, left: 0 }}>
<Text
style={{ fontSize: 20, color: 'white', backgroundColor: 'red' }}>
Free delivery
</Text>
</View>
{/**Card text */}
<Text style={{ fontSize: 20, fontWeight: 'bold', paddingLeft: 8 }}>
Papa's john town
</Text>
<Text />
</Card>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
});

You can overlay your text using absolute position
import React, { Component } from "react";
import { Text, ImageBackground } from "react-native";
class App extends Component {
render() {
return (
<ImageBackground
source={{
uri:
"https://www.medicalnewstoday.com/content/images/articles/325/325466/man-walking-dog.jpg"
}}
style={{
height: 100,
width: 100,
position: "relative", // because it's parent
top: 2,
left: 2
}}
>
<Text
style={{
fontWeight: "bold",
color: "white",
position: "absolute", // child
bottom: 0, // position where you want
left: 0
}}
>
Hello World
</Text>
</ImageBackground>
);
}
}
export default App;

I solve this By position. Here is the Code
<Text style={{position: 'absolute', top: -150, right: 0 ,backgroundColor: '#fff', fontSize: 15}}>
{" 35 mins "}
</Text>
<Text style={{ position: 'absolute', top: -130, left: 0 ,backgroundColor: '#D60E64', fontSize: 15, color: '#fff'}}>
{" 30% OFF "}
</Text>
<Text style={{ position: 'absolute', top: -100, left: 0 ,backgroundColor: '#D60E64', fontSize: 15, color: '#fff'}}>
{" FREE DELIVERY "}
</Text>

Related

Multiple Flip Cards not able to scroll in Flatlist

native-card-flip" for creating flip cards and I need to have multiple flip cards so I have added that flip card in FlatList but the issue is that the list is not scrolling at all. I have tried it with ScrollView and .map() function but scrolling not working at all.
<FlatList
data={revision}
renderItem={({item, index}) => (
<CardFlip
style={{
width: width * 0.95,
height: height * 0.3,
marginBottom: height * 0.015,
marginTop: height * 0.015,
}}
duration={3000}
ref={card => (this['card' + index] = card)}>
<Card
style={{
width: width * 0.9,
borderRadius: 16,
backgroundColor: 'transparent',
height: height * 0.8,
}}>
<TouchableOpacity onPress={() => this['card' + index].flip()}>
<View
style={{
flexDirection: 'row',
backfaceVisibility: 'hidden',
height: '100%',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: Colors.lightGrey,
borderRadius: 22,
width: width * 0.95,
height: height * 0.3,
}}>
<Text
style={{
color: Colors.heading,
textAlign: 'center',
marginBottom: 1,
fontSize: 20,
width: '92%',
}}>
Lorem Ipsum
</Text>
</View>
<View
style={{
position: 'absolute',
bottom: 10,
right: 10,
}}>
{/* <TouchableOpacity
onPress={() => {
this.card.flip();
setIsFlipped(!isFlipped);
}}
style={{justifyContent: 'flex-end'}}> */}
<Image
source={require('../assets/images/flip-front.png')}
/>
{/* </TouchableOpacity> */}
</View>
</TouchableOpacity>
</Card>
<Card
style={{
width: width * 0.95,
borderRadius: 16,
backgroundColor: 'transparent',
height: height * 0.8,
alignSelf: 'center',
}}>
<TouchableOpacity
style={{
width: width * 0.95,
height: height * 0.3,
}}
onPress={() => this['card' + index].flip()}>
{/* Flip Back */}
<View
style={{
flexDirection: 'column',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
flex: 1,
paddingHorizontal: width * 0.05,
backgroundColor: Colors.white,
borderRadius: 22,
}}>
<Text
style={{
color: Colors.heading,
fontSize: 20,
marginBottom: '2%',
fontFamily: 'FiraSans-ExtraBold',
}}>
Lorem Ipsum
</Text>
<Text
style={{
color: Colors.heading,
fontSize: 16,
marginBottom: '2%',
textAlign: 'justify',
fontFamily: 'OpenSans-Regular',
}}>
{strings.dummyText}
</Text>
</View>
<View
style={{
position: 'absolute',
bottom: 10,
right: 10,
}}>
{/* <TouchableOpacity
onPress={() => {
this.card.flip();
setIsFlipped(!isFlipped);
}}
style={{justifyContent: 'flex-end'}}> */}
<Image source={require('../assets/images/flip-back.png')} />
{/* </TouchableOpacity> */}
</View>
</TouchableOpacity>
</Card>
</CardFlip>
)}
numColumns={1}
keyExtractor={(item, index) => index.toString()}
style={{marginTop: height * 0.01}}
showsVerticalScrollIndicator={false}
maxToRenderPerBatch={1}
/>
Please help me to figure out how can I achieve scrolling.

How to append new images to the array using react native image crop picker?

Hi, I am using react-native-image-crop-picker to overcome the above-shown module to select images from the gallery and display it in react native app, but I also want to click on add photo and again select images from the gallery and append them to the previous array of photos, am unable to figure that out.
This is the exact code that I have written to achieve the above-shown behavior, what should I change or add to perform the append feature?
import React, {useEffect, useState} from 'react';
import {
View,
Text,
StyleSheet,
ScrollView,
Image,
TouchableOpacity,
Dimensions,
FlatList,
} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import ImagePicker from 'react-native-image-crop-picker';
const deviceWidth = Dimensions.get('window').width;
const deviceHeight = Dimensions.get('window').height;
const App = () => {
const [photos, setAddPhotos] = useState(null);
const [photo, setAddphoto] = useState(null);
const handleChoosePhoto = () => {
ImagePicker.openPicker({
multiple: true,
waitAnimationEnd: false,
includeExif: true,
forceJpg: true,
})
.then((images) => {
setAddphoto(null);
setAddPhotos(
images.map((i) => {
console.log('recieved image', i);
return {
uri: i.path,
// width: i.width,
// height: i.height,
width: 185,
height: 128,
mime: i.mime,
};
}),
);
})
.catch((e) => alert(e));
};
const renderImage = (image) => {
return (
<Image
style={{
width: 185,
height: 128,
resizeMode: 'contain',
marginTop: 1,
}}
source={image}
/>
);
};
const renderAsset = (image) => {
return renderImage(image);
};
return (
<View style={{flex: 1}}>
{console.log('PHOTOS', photos)}
{photos === null ? (
<View style={{flex: 1}}>
<View style={Styles.headerWrapper}>
<View
style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Icon name="angle-left" size={30} />
<TouchableOpacity style={{right: '10%', top: '2%'}}>
<Text style={{fontSize: 15, fontWeight: 'bold'}}>
SAVE AND EXIT
</Text>
</TouchableOpacity>
</View>
</View>
<ScrollView>
<Text style={Styles.headerText}>Add photos to your listing</Text>
<Text style={Styles.subHeader}>
Photos help guests imagine staying in your place. You can start
with one and add more after you publish.
</Text>
<View style={Styles.container}>
<TouchableOpacity onPress={() => handleChoosePhoto()}>
<View
style={{
backgroundColor: '#20B2AA',
width: 150,
height: 40,
borderRadius: 5,
justifyContent: 'center',
}}>
<Text
style={{
color: '#fff',
textAlign: 'center',
fontSize: 15,
fontWeight: 'bold',
}}>
Add photos
</Text>
</View>
</TouchableOpacity>
</View>
</ScrollView>
<TouchableOpacity
style={{
alignSelf: 'flex-end',
right: '5%',
position: 'absolute',
bottom: 10,
}}>
<View
style={{
borderColor: '#20B2AA',
borderWidth: 1,
alignSelf: 'flex-end',
padding: 10,
}}>
<Text
style={{fontSize: 15, fontWeight: 'bold', color: '#20B2AA'}}>
Skip For Now
</Text>
</View>
</TouchableOpacity>
</View>
) : (
<>
<View style={{flex: 1}}>
<View style={Styles.headerWrapper}>
<View
style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Icon name="angle-left" size={30} />
<TouchableOpacity style={{right: '10%', top: '2%'}}>
<Text style={{fontSize: 15, fontWeight: 'bold'}}>
SAVE AND EXIT
</Text>
</TouchableOpacity>
</View>
</View>
<ScrollView>
<View style={{flex: 1, flexWrap: 'wrap', flexDirection: 'row'}}>
{photos
? photos.map((i) => (
<View
style={{
// width: 185, height: 128,
// width:'50%',
flexBasis: '33.33%',
}}
key={i.uri}>
{renderAsset(i)}
</View>
))
: null}
</View>
</ScrollView>
<TouchableOpacity
style={{
alignSelf: 'flex-end',
right: '5%',
position: 'absolute',
bottom: 10,
}}>
<View
style={{
backgroundColor: '#20B2AA',
alignSelf: 'flex-end',
padding: 10,
}}>
<Text style={{fontSize: 15, fontWeight: 'bold', color: '#FFF'}}>
NEXT
</Text>
</View>
</TouchableOpacity>
</View>
</>
)}
</View>
);
};
export default App;
const Styles = StyleSheet.create({
headerWrapper: {
width: deviceWidth,
paddingLeft: 24,
paddingTop: 10,
paddingBottom: 10,
},
headerText: {
fontWeight: 'bold',
fontSize: 28,
paddingLeft: 24,
},
container: {
padding: 24,
},
subHeader: {
paddingLeft: 24,
fontSize: 17,
paddingTop: 24,
paddingRight: 24,
},
});
Please let me know if anything else is required for better understanding, thank you.
You only need to take the prevState in setAddPhotos
setAddPhotos((lastPhotos) => {
const imagesMap = images.map((i) => {
return {
uri: i.path,
width: i.width,
height: i.height,
mime: i.mime,
};
});
return [...lastPhotos, ...imagesMap];
});

React native create rectangle bottom, plus half rectangle is cut by circle

Hello I am having task to create custom shape figure. On the bottom the shape of figure is rectangle and on half top of rectangle is cut by circle shape. Can anyone give me direction where to go from now?
import React, { Component } from 'react';
import { View } from 'react-native';
import { Icon} from 'react-native-elements'
class BottomNavigator extends Component {
render() {
return (
<View style={{
flex: 1,
flexDirection: 'column',
backgroundColor: '#f8f4f4'
}}>
<View style={{ position: 'absolute', alignSelf: 'center', backgroundColor: '#f8f4f4', width: 70, height: 70, borderRadius: 35, bottom: 25, zIndex: 10 }}>
<Icon
name='add'
type='material'
color='#f00'
containerStyle={{ alignSelf: 'center' }}
reverse
size={28}
onPress={() => {}}
/>
</View>
<View style={{ position: 'absolute', backgroundColor: '#2196F3', bottom: 0, zIndex: 1, width: '100%', height: 60, flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 15, paddingVertical: 10 }}>
<Icon
name='menu'
type='material'
color='#fff'
onPress={() => {}}
/>
<View style={{ flexDirection: 'row', justifyContent: 'center' }}>
<Icon
name='favorite'
type='material'
color='#fff'
onPress={() => {}}
containerStyle={{ marginHorizontal: 16 }}
/>
<Icon
name='search'
type='material'
color='#fff'
/>
</View>
</View>
</View>
);
}
}
export default BottomNavigator;

Aligning image over 2 background views

I have two background views with different colors. Both their own size.
Over these backgrounds, I need an image aligned on the left, over both other views.
how can i accomplish this?
export default class MainScreen extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.rectangle1}>
<Image
source={require('../assets/dame.png')}
style = {styles.image}/>
</View>
<View style={styles.rectangle2}>
</View>
</View>
)
}
}
Added sample image what to accomplish:
besides the use of absolute positioning, here is another tip to achieve a similar layout on most devices is the use of Dimensions and constants for the width and height of the devices that.
based on the information provided, here is how my design will look like:
////import { Dimensions } from react-native;
const { width: deviceWidth, height: deviceHeight } = Dimensions.get('window');
export default class MainScreen extends Component {
render() {
return (
<View style={{ backgroundColor: 'magenta', height: deviceHeight }}>
<View
style={{
width: deviceWidth * 0.44,
alignSelf: 'flex-start',
}}
>
<Image
source={{ uri: 'https://ui-avatars.com/api/?name=Alice' }}
style={{ width: '100%', height: '100%' }}
/>
</View>
<View
style={{
backgroundColor: 'black',
position: 'absolute',
width: deviceWidth * 0.56,
height: deviceWidth * 0.56,
alignSelf: 'flex-end',
opacity: 0.7
}}
/>
<View
style={{
backgroundColor: 'yellow',
width: deviceWidth * 0.7,
height: deviceWidth * 0.1,
position: 'absolute',
top: deviceHeight * 0.8,
alignSelf: 'center',
opacity: 0.8,
}}
/>
<View
style={{
backgroundColor: 'blue',
width: deviceWidth,
height: deviceWidth * 0.14,
position: 'absolute',
bottom: 0,
alignSelf: 'flex-end',
opacity: 0.8,
}}
/>
</View>
)
}
}
i suggest you keep experimenting to find out which method works best for your application.

Building Image Card in React Native

I'm trying to build a simple image card component in React Native and got some problems. This is my component now (It's available for you on snack):
I can't find a way to set border only on the top of the image on the card, keeping the bottom border flat.
Desired form:
The Image component doesn't seen to be rendered from the top showing the model's face, instead it's getting centered showing her body.
Here it's the original image for comparison:
Use this code. Added overflow: "hidden" to the View and removed borderRadius for Image. Tested in IOS.
import * as React from 'react';
import { Text, View, Image } from "react-native";
export default class RootComponent extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<View style={{ backgroundColor: "#eee", borderRadius: 10, overflow: "hidden" }}>
<View>
<Image
source={require("./assets/h4.jpg")}
style={{
height: 135,
width: 155
}}
/>
</View>
<View style={{ padding: 10, width: 155 }}>
<Text>Title</Text>
<Text style={{ color: "#777", paddingTop: 5 }}>
Description of the image
</Text>
</View>
</View>
</View>
);
}
}
By removing the height from the <Image> and setting it in its parent view, the image will be shown from the top.
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<View style={{ backgroundColor: "#eee", borderRadius: 10, overflow: 'hidden' }}>
<View style={{ height: 135, width: 155, overflow: 'hidden' }}>
<Image
source={require("./assets/h4.jpg")}
style={{
width: 155
}}
/>
</View>
<View style={{ padding: 10, width: 155 }}>
<Text>Title</Text>
<Text style={{ color: "#777", paddingTop: 5 }}>
Description of the image
</Text>
</View>
</View>
</View>
You can directly do it with borderTopLeftRadius and borderTopRightRadius in a Card.
<Card
containerStyle={styles.boxCon}
featuredTitle={title}
image={{
uri: urlToImage
}}
imageStyle={{ borderTopLeftRadius: 10, borderTopRightRadius: 10 }}
>
const styles = {
boxCon: {
margin: 15,
marginHorizontal: 10,
marginBottom: 17.5,
borderColor: '#FFFFFF',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.3,
shadowRadius: 5,
elevation: 5,
borderRadius: 10
}
};

Resources