move a horizontal line to the center in StyledSheets - javascript

I have drawn a horizontal line like this. However, it appears towards the left side of the screen. I don't want to increase the width. How else can I move it to the center? I tried wrapping it with another view along with alignContent: 'center' etc but it didn't work for me.
<View style={styles.horizontalLine}></View>
horizontalLine: {
marginTop: 25,
width: '80%',
height: 1,
//alignContent: 'center',
//width: 1,
backgroundColor: '#E0E0E0',
},

Add an alignSelf:'center' like below
horizontalLine: {
marginTop: 25,
width: '80%',
height: 1,
//alignContent: 'center',
//width: 1,
alignSelf: 'center',
backgroundColor: '#E0E0E0',
}

You can give horizontal margin: auto
horizontalLine: {
// ...
marginLeft: 'auto',
marginRight: 'auto',
// ...
},

Try this...
horizontalLine: {
margin: 'auto',
marginTop: 25,
width: '80%',
height: 1,
backgroundColor: '#E0E0E0',
}

Related

Create an expanding line from a point in react native

im trying to create a personality picker as seen in the image below. The intended use of it is that depending on the score of each personality from 0 to 5 a black line will be drawn and expand to each of the five circles to indicate the score.
Here is my code so far to create this, I have gotten the circles in line and I am currently creating the black lines however I am unable to do them dynamically and I am having to plot each point specifically which may be a problem for different screensizes. I am hoping there is a better way than what I am doing right now as it is a tonne of nested Views forming shapes. Any help would be great on how to make this simpiler / more dynamic!
Thanks :)
return (
<View style={{margin: 32}}>
<Text style={{fontFamily: 'Roboto_400Regular', fontSize: 36}}>Plot your{"\n"}personality</Text>
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={{
fontFamily: 'Roboto_400Regular',
fontSize: 14,
color: '#878787',
paddingTop: 4,
alignSelf: 'flex-end'
}}>Use this to match with similar people?</Text>
<Switch
trackColor={{false: "#878787", true: "#5BF675"}}
thumbColor="#f4f3f4"
ios_backgroundColor="#878787"
onValueChange={toggleSwitch}
value={isEnabled}
/>
</View>
<View style={{alignItems: 'center', justifyContent: 'center', marginTop: 32}}>
<View style={{
borderColor: '#DBDBDB',
borderWidth: 1,
height: 275,
width: 275,
borderRadius: 275 / 2,
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{
borderColor: '#DBDBDB',
borderWidth: 1,
height: 225,
width: 225,
borderRadius: 225 / 2,
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{
borderColor: '#DBDBDB',
borderWidth: 1,
height: 175,
width: 175,
borderRadius: 175 / 2,
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{
borderColor: '#DBDBDB',
borderWidth: 1,
height: 125,
width: 125,
borderRadius: 125 / 2,
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{
borderColor: '#DBDBDB',
borderWidth: 1,
height: 75,
width: 75,
borderRadius: 75 / 2,
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{position: 'absolute', justifyContent: 'center', alignItems: 'center'}}>
<View
style={{
borderColor: '#DBDBDB',
borderWidth: 1,
width: 275,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '45deg'}],
position: 'absolute',
}}
/>
<View
style={{
borderColor: '#DBDBDB',
borderWidth: 1,
width: 275,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '90deg'}],
position: 'absolute',
}}
/>
<View
style={{
borderColor: '#DBDBDB',
borderWidth: 1,
width: 275,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '135deg'}],
position: 'absolute',
}}
/>
<View
style={{
borderColor: '#DBDBDB',
borderWidth: 1,
width: 275,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '180deg'}],
position: 'absolute',
}}
/>
<View style={{position: 'absolute', justifyContent: 'center', alignItems: 'center'}}>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: 90.5,
bottom: -3,
left: 0,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '0deg'}],
position: 'absolute',
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: 137.5,
bottom: -52,
right: -116,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '45deg'}],
position: 'absolute',
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: 137.5,
alignItems: 'center',
justifyContent: 'center',
bottom: -72,
left: -70,
transform: [{ rotate: '90deg'}],
position: 'absolute',
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: 137.5,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '135deg'}, {translateX: 68}],
position: 'absolute',
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: 137.5,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '180deg'}, {scaleX: 0}],
position: 'absolute',
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: 137.5,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '225deg'}, {translateX: 68}],
position: 'absolute',
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: 137.5,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '270deg'}, {translateX: 68}],
position: 'absolute',
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: (137.5),
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '315deg'}, {translateX: 68}],
position: 'absolute',
}}
/>
</View>
</View>
</View>
</View>
</View>
</View>
</View>
</View>
</View>
);
I have found an answer, although I am not 100% satisfied and believe it may fall over when screens resize.
import React from 'react';
import {View} from "react-native";
interface PersonalityPlotterDialProps {
value: number
}
function PersonalityPlotterDial(props: PersonalityPlotterDialProps) {
const {value} = props;
const widthCalculator = (value: number) => {
switch (value) {
case 0:
return 0;
case 1:
return 37.5;
case 2:
return 62.5;
case 3:
return 87.5;
case 4:
return 112.5;
case 5:
return 137.5;
default:
return 0;
}
};
const translateCalculator = (value: number) => {
switch (value) {
case 0:
return 0;
case 1:
return 1.05;
case 2:
return 1.75;
case 3:
return 2.5;
case 4:
return 3.2;
case 5:
return 3.95;
default:
return 0;
}
}
const displayCalculator = () => {
if (widthCalculator(value) === 0) {
return 'none'
}
}
return (
<View style={{alignItems: 'center', justifyContent: 'center', marginTop: 32, marginBottom: 64}}>
<View style={{
borderColor: '#DBDBDB',
borderWidth: 1,
height: 275,
width: 275,
borderRadius: 275 / 2,
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{
borderColor: '#DBDBDB',
borderWidth: 1,
height: 225,
width: 225,
borderRadius: 225 / 2,
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{
borderColor: '#DBDBDB',
borderWidth: 1,
height: 175,
width: 175,
borderRadius: 175 / 2,
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{
borderColor: '#DBDBDB',
borderWidth: 1,
height: 125,
width: 125,
borderRadius: 125 / 2,
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{
borderColor: '#DBDBDB',
borderWidth: 1,
height: 75,
width: 75,
borderRadius: 75 / 2,
alignItems: 'center',
justifyContent: 'center',
position: 'relative'
}}>
<View style={{position: 'absolute', justifyContent: 'center', alignItems: 'center'}}>
<View
style={{
borderColor: '#DBDBDB',
borderWidth: 1,
width: 275,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '45deg'}],
position: 'absolute',
}}
/>
<View
style={{
borderColor: '#DBDBDB',
borderWidth: 1,
width: 275,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '90deg'}],
position: 'absolute',
}}
/>
<View
style={{
borderColor: '#DBDBDB',
borderWidth: 1,
width: 275,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '135deg'}],
position: 'absolute',
}}
/>
<View
style={{
borderColor: '#DBDBDB',
borderWidth: 1,
width: 275,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '180deg'}],
position: 'absolute',
}}
/>
<View style={{position: 'absolute', justifyContent: 'center', alignItems: 'center'}}>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: widthCalculator(value),
bottom: -3,
left: 0,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '0deg'}],
position: 'absolute',
display: displayCalculator(),
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: widthCalculator(value),
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '45deg'}, {translateX: (translateCalculator(value)) * 17.5}],
position: 'absolute',
display: displayCalculator(),
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: widthCalculator(value),
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '90deg'}, {translateX: (translateCalculator(value)) * 17.5}],
position: 'absolute',
display: displayCalculator(),
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: widthCalculator(value),
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '135deg'}, {translateX: (translateCalculator(value)) * 17.5}],
position: 'absolute',
display: displayCalculator(),
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: widthCalculator(value),
alignItems: 'center',
justifyContent: 'center',
bottom: -3,
right: 0,
transform: [{ rotate: '180deg'}],
position: 'absolute',
display: displayCalculator(),
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: widthCalculator(value),
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '225deg'}, {translateX: (translateCalculator(value)) * 17.5}],
position: 'absolute',
display: displayCalculator(),
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: widthCalculator(value),
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '270deg'}, {translateX: (translateCalculator(value)) * 17.5}],
position: 'absolute',
display: displayCalculator(),
}}
/>
<View
style={{
backgroundColor: '#000',
borderWidth: 3,
width: widthCalculator(value),
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate: '315deg'}, {translateX: (translateCalculator(value)) * 17.5}],
position: 'absolute',
display: displayCalculator(),
}}
/>
</View>
</View>
</View>
</View>
</View>
</View>
</View>
</View>
);
}
export default PersonalityPlotterDial;
In general, there is a cleaner solution for this (maybe I will add one later), but for now, lets try and make your code work.
You can have dynamic line size by passing the width to each View component with a math formula. meaning, think of a way to represent the size of each line. for example:
0: 0px,
1: 50px,
2: 100px
and so on... (the 50px should be the radius divided by 5)
Now, for each View tag, you can just set the width by multiplying 50px with the value of the size of it(0-5: 0-250px).
This should do the trick.
(I assume you have a state or a way to keep the values of each label, and by that you multiply this value with 50px for each line)
Hey, sorry for taking so long I wasn't available so much. anyway, I wrote a small piece of code that does the behavior you want. the design isn't amazing but it does the trick. I used styled-components just for fun, you can run it easily by installing styled-component or just converting it to regular form:
App.js
import { useState } from 'react';
import styled from 'styled-components';
import Line from './components/line';
function App() {
const [values, setValues] = useState(config);
return (
<Container>
<Circle>
<Center/>
<Lines>{values.map((value) => <Line {...value} />)}</Lines></Circle>
<Menu>
{values.map((line, index) =>
<SizeButtons>
<Button onClick={() => {
const copyValues = [...values];
copyValues[index].value = line.value - 1 > 0 ? line.value - 1 : 0;
setValues(copyValues);
}}>-</Button>
<Button onClick={() => {
const copyValues = [...values];
copyValues[index].value = line.value + 1 < 5 ? line.value + 1 : 5;
setValues(copyValues);
}}>+</Button>
</SizeButtons>
)}
</Menu>
</Container>
);
}
export default App;
const Container = styled.div`
position: relative;
margin-top: 200px;
margin-left: 200px;
`;
const Circle = styled.div`
position: relative;
width: 250px;
height: 250px;
border: 1px solid black;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
`;
const Center = styled.div`
position: absolute;
top: 116px;
left: 116px;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: black;
`;
const Lines = styled.div`
position: absolute;
top: 125px;
left: 125px;
`;
const SizeButtons = styled.div``;
const Menu = styled.div`
position: absolute;
top: 0;
right: 0;
`;
const Button = styled.button``;
const config = [
{ value: 1, degree: 0 },
{ value: 1, degree: 45, },
{ value: 1, degree: 90, left: '2px' },
{ value: 1, degree: 135, top: '2px', left: '1px' },
{ value: 1, degree: 181, top: '2px' },
{ value: 1, degree: 225, top: '0px' },
{ value: 1, degree: 270, top: '0px' },
{ value: 1, degree: 315, top: '0px' },
]
line.js:
import React from 'react';
import styled from 'styled-components'
const Line = (props) => {
return (
<Container {...props}/>
);
};
export default Line;
const Container = styled.div`
width: ${props => props.value * 25 }px;
background: black;
height: 2px;
transform: rotate(${props => props.degree}deg);
transform-origin: top left;
position: absolute;
top: ${props => props.top};
left: ${props => props.left}
`;
let me know if something is unclear.

How to make an element to be always in the top right corner of the screen

I am trying to make an element with style={styles.settingsButtonContainer} not to depend on position of other elements on the view, but to be always in the top right corner of the screen. I am trying in this way:
<View style={styles.container}>
<RCActivityIndicator animating={showActivityIndicator} />
<RCModal title={alertTitle} visible={alertVisible} onButtonPress={alertOnPress} />
<ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }}>
<Text style={styles.title}>Noughts and Crosses</Text>
<Text style={styles.tip}>Get {winCondition()} in row, column or diagonal</Text>
<TouchableHighlight underlayColor="#000000" style={[styles.button, styles.newGameButton]} onPress={setInitialFieldState}>
<Text style={styles.buttonText}>New game</Text>
</TouchableHighlight>
<Text style={styles.turnContainer}>Turn: <Text style={[styles.turn, { color: turn === 'X' ? '#2E86C1' : '#E74C3C'}]}>{turn}</Text></Text>
<Field state={fieldState} size={fieldSize} winner={winCombination} onCellPress={onCellPress} />
</ScrollView>
<View style={styles.settingsButtonContainer}>
<TouchableHighlight underlayColor={theme.colors.secondary} style={styles.settingsButton} onPress={onSettingsPress}>
<Image source={require('../img/settings.png')} style={styles.settingsIcon} />
</TouchableHighlight>
</View>
</View>
const styles = StyleSheet.create({
container: {
flex: 1
},
title: {
textAlign: 'center',
fontSize: 33,
fontFamily: theme.fonts.primary,
color: theme.colors.text
},
button: {
alignItems: 'center',
padding: 5,
margin: 5,
marginLeft: 10,
marginRight: 10,
borderRadius: 20,
height: 35,
justifyContent: 'center'
},
newGameButton: {
backgroundColor: theme.colors.primary,
paddingLeft: 15,
paddingRight: 15,
},
buttonText: {
fontSize: 25,
fontFamily: theme.fonts.primary,
color: theme.colors.text
},
tip: {
textAlign: 'center',
fontSize: 25,
marginLeft: 10,
marginRight: 10,
fontFamily: theme.fonts.primary,
color: theme.colors.text
},
turnContainer: {
textAlign: 'center',
fontSize: 33,
fontFamily: theme.fonts.primary,
color: theme.colors.text,
marginLeft: 10,
},
turn: {
fontSize: 30,
fontFamily: theme.fonts.noughtsAndCrosses,
},
privacy: {
textAlign: 'center',
color: theme.colors.secondaryText,
fontSize: 15,
textDecorationLine: "underline",
marginTop: 20
},
settingsButtonContainer: {
position: 'absolute',
top: 5,
right: 5,
height: 50,
width: 50,
alignSelf: 'flex-end',
},
settingsButton: {
height: 50,
width: 50,
borderRadius: 25,
},
settingsIcon: {
height: 50,
width: 50
},
settings: {
marginTop: 30
},
buttonsContainer: {
flexDirection: 'row',
alignItems: 'center'
}
});
But it just takes a full row for itself, so the ScrollView doesn't take 100% height. How to make it work?
try to wrap the settingsButtonContainer
and use
settingButtonContainerWrapped: {
alignItem: 'flex-end',
flexDirection : 'row',
},
Actually the issue was in another element, that was on top of the ScrollView - it was RCActivityIndicator who took this place. I styled it, and it worked.
Use css:
[eleSelector] {
position: absolute;
right: 0;
top: 0;
}
Check HTML element Selector in CSS

Add text in splash screen React Native Bootsplash

Splash Screen works fine, but i need to add text at the bottom and not able to achieve it, is it possible to add Text at the bottom
PS I am using react native bootsplash library
You could modify the App.tsx file. (Maybe another name in your project).
Below are extracted from its example:
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF",
},
text: {
fontSize: 24,
fontWeight: "700",
margin: 20,
lineHeight: 30,
color: "#333",
textAlign: "center",
},
bootsplash: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF",
},
logo: {
height: 89,
width: 100,
},
});
So to align the text to the bottom of the page, you could change the text style properties, such as:
text: {
fontSize: 24,
fontWeight: "700",
lineHeight: 30,
color: "#333",
textAlign: "center",
position: fixed,
bottom: 0,
margin-bottom: 2%, /* Add some space before the border */
}

react native absolute positioning not working

My button in the code below is positioned absolutely but it isn't working. It is taking up space in its containing view and it is not allowing the image to be below it.
<View style={{
justifyContent: 'flex-end',
alignItems: 'center',
flexDirection: 'row',
flex: 0.5,
borderRadius: 8
}}>
<Image
style={mapStyles.avatar}
source={props.image} />
<Button
small
icon
style={{
positon: 'absolute',
right: -5,
top: -5,
width: 20,
height: 20,
zIndex: 50,
elevation: 10,
borderRadius: 10,
backgroundColor: '#FF3B3F',
shadowColor: '#000000',
shadowOffset: {
width: 0,
height: 1
},
shadowRadius: 1,
shadowOpacity: 1.0
}}
onPress={() => props.updateImage(null)}>
<Icon style={locationStyle.deleteLocationButtonIcon}
name="close-o" size={22} color="#9E9E9E" />
</Button>
</View>
The button is the pink bit:
The button needs to be in the top right corner of the image, It is a cancel button. The image should be to the far right where the button is. I have experienced absolute positioning not working in react native before. Is this a bug or am I doing it wrong?
image styles:
avatar: {
width: 100,
height: 100
}
Try nesting your button inside of the Image like
<Image>
<Button />
</Image

Get same effect as ...StyleSheet.absoluteFillObject without taking up more height

I have to add location from this stylesheet:
const mapStyles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
height: 400,
width: 400,
justifyContent: 'flex-end',
alignItems: 'center',
},
location: {
...StyleSheet.absoluteFillObject,
width: 400,
alignItems: 'center',
}
})
to my autocomplete (<Location />) so that on Android the autocomplete list will overflow the other components.
E.G.:
<Container style={mapStyles.location}>
<Location />
</Container>
However it seems to push the elements below the <Location /> down to about the device screen height below it (so there is a full blank screen under the <Location /> and then the other components appear. How do I get the same effect as ...StyleSheet.absoluteFillObject withought moving components below it further down the screen?
StyleSheet.absoluteFillObject will be replaced with this properties (source):
const absoluteFillObject = {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
};
It works for your <Location /> component (it needs to be absolute to "overflow" the other elements), but not for your container.
Makes your container full height with flex: 1, the other element in your container and it should work.
const mapStyles = StyleSheet.create({
container: {
flex: 1,
width: 400,
justifyContent: 'flex-end',
alignItems: 'center',
},
location: {
...StyleSheet.absoluteFillObject,
width: 400,
alignItems: 'center',
}
})

Categories

Resources