Creating CSS circles in react-native - react-native

I'm having some trouble creating CSS circles in react-native. The following works in iPhone 6 Plus but in all the other iPhones, they become diamonds.
circle: {
height: 30,
width: 30,
borderRadius: 30,
}
Now if I use PixelRatio on borderRadius it works in everything but iPhone 6 plus. iPhone 6 plus renders it as boxes with rounded corners.
circle: {
height: 30,
width: 30,
borderRadius: 30 / PixelRatio.get(),
}

Your border radius should be a half of width and your height. like below:
circle: {
width: 44,
height: 44,
borderRadius: 44/2
}

None of these fit my needs, if you need a responsive circle you can try using my solution:
Step 1: Import Dimensions (and other used elements) from react native (or add to existing imports list)
import { Dimensions, TouchableHighlight, Text } from 'react-native';
Step 2: Add your touchable element (you can calculate width or height of a device)
<TouchableHighlight
style = {{
borderRadius: Math.round(Dimensions.get('window').width + Dimensions.get('window').height) / 2,
width: Dimensions.get('window').width * 0.5,
height: Dimensions.get('window').width * 0.5,
backgroundColor:'#f00',
justifyContent: 'center',
alignItems: 'center'
}}
underlayColor = '#ccc'
onPress = { () => alert('Yaay!') }
>
<Text> Mom, look, I am a circle! </Text>
</TouchableHighlight>
Step 3: Enjoy your responsive circled element

borderRadius should be half the side of the square. So 15 in your case - no matter what pixel ratio the device has.
It works with 30 / PixelRatio.get() only for 2x retina devices, cause the result is 15.
Then for iPhone 6 Plus, you indeed get a rounded box because the result is 10 (pixel ratio is 3).
I'm surprised your saying it worked on iPhone 6 Plus with 30 for a 30x30 square.

If you want to make a circle that will work on any device the only thing that you should do is to give the same height and width the same value and then give the borderRadius a really high value I personally give it 1000 so it will big enough for most of the cases
circle :{
height : 30 ,
width :30,
borderRadius: 1000,
}

Since borderRadius style expects number as a value you can't use borderRadius: 50%. To make circle all you have to do is use your image width/height and devide it with 2. Read more here:
https://github.com/refinery29/react-native-cheat-sheet

Basically just need to apply same height, width and in borderRadius have to divided by 2
E.g. height : 50, width :50 borderRadius : 50/2
Just Circle
var circle = {
height: 30,
width: 30,
borderRadius: 15
}
Responsive Circle with Device Height
var circle = {
height: Dimensions.get('window').height * 0.1,
width: Dimensions.get('window').height * 0.1,
borderRadius: Math.round((Dimensions.get('window').height + Dimensions.get('window').width) / 2)
}
Responsive Circle with Device Width
var circle = {
height: Dimensions.get('window').width * 0.1,
width: Dimensions.get('window').width * 0.1,
borderRadius: Math.round((Dimensions.get('window').height + Dimensions.get('window').width) / 2)
}
Example Code
import React, { useEffect, useState, useRef } from 'react'
import { Dimensions, SafeAreaView, StyleSheet, Text, View } from 'react-native'
const { height, width } = Dimensions.get('window')
function roundOff(v) {
return Math.round(v)
}
function dimensions() {
var _borderRadius = roundOff((height + width) / 2),
_height = roundOff(height),
_width = roundOff(width)
return { _borderRadius, _height, _width }
}
export default function ResponsiveCircle() {
return (
<SafeAreaView style={styles.container}>
<View style={styles.circleView}>
<Text style={styles.text}>
Responsive{'\n'}Circle
</Text>
</View>
</SafeAreaView>
)
}
const commonStyles = { alignItems: 'center', justifyContent: 'center', }
const styles = StyleSheet.create({
container: { flex: 1, ...commonStyles },
circleView: { height: dimensions()._height * 0.2, width: dimensions()._height * 0.2, borderRadius: dimensions()._borderRadius, backgroundColor: 'tan', ...commonStyles },
text: { textAlign: 'center', lineHeight: 25, color: 'black', fontWeight: 'bold' }
})

I've been using the styled-components package to style my React Native components and the easiest solution I've found is to set the border radius to a size in px larger than half of the width that the circle will ever have. It'll then default to the equivalent of a 50% border-radius for any size smaller than that.

onLayout worked for me.
Calculate width and height to maintain 1:1 aspect ratio, then set borderRadius to width/2
const [circleSytle, setCircleStytle] = useState();
...
function calCircleStyle(layoutEvent) {
let {width, height} = layoutEvent.nativeEvent.layout;
let dim = width > height ? width : height;
setCircleStyle({width:dim, height:dim, borderRadius:dim/2});
}
Then apply it to your view like this:
<View onLayout={calCircleStyle} style={circleStyle}>
...
</View>
Btw, can anyone explain why borderRadius:1000 is bad?

Related

React Native Image component with "{width: 100%, height: auto}" gets dislocated when using margin

I have an Image component that has width from Dimensions.get('window').width,
and height that is calculated using this formula:
{ //not the real code, but it works exactly like this.
width: Dimensions.get('window').width,
height: actualImageHeight*(Dimensions.get('window').width/actualImageWidth)
}
It basically closely emulates how width: 100%, height: auto works in css.
and it works well until i added margins to it, which causes the image to get dislocated
like this:
Dislocated Bear
I have also tried to use PixelRatio.getPixelSizeForLayoutSize(margin*2) to try taking account the margin, which makes the new formula look like this:
{ //not the real code, but it works exactly like this.
width: Dimensions.get('window').width-PixelRatio.getPixelSizeForLayoutSize(margin*2),
height: actualImageHeight*((Dimensions.get('window').width-PixelRatio.getPixelSizeForLayoutSize(margin*2))/actualImageWidth)
}
and the result is almost, there, but still slightly dislocated: Slightly Dislocated Bear
Which makes me think that Dimensions isn't a good reference for width.
So how do I emulate width: 100%, height: auto that doesn't use Dimensions?
Is it possible to use width: 100% as a reference to use in the formula?
import React from 'react';
import {SafeAreaView,View,Dimensions,Image,} from 'react-native';
const {width, height} = Dimensions.get('window');
const actualImageHeight = 200;
const actualImageWidth = 300;
const Test = props => {
return (
<SafeAreaView style={{flex: 1}}>
<View
style={{
width: width,
height: actualImageHeight * (width / actualImageWidth),
borderRadius: 6,
borderWidth: 1,
borderColor: '#f1f1f1',
overflow: 'hidden',
backgroundColor: 'red',
padding: 12,
}}>
<Image
style={{flex: 1, width: null, height: null}}
source={{uri: 'https://picsum.photos/200/300'}}
/>
</View>
</SafeAreaView>
);
};
when you place calculated width and height to any view if you place margin in styles it will dislocated the view because while rendering the view margin also considered. Better to wrap image with view.
I still continued the idea of subtracting the width with the margins, and I managed to make it work. Simply by doing Dimensions.get('window').width-(margin*2) will make it work. So final code is:
{
width: Dimensions.get('window').width-(margin*2),
height: actualImageHeight*(Dimensions.get('window').width-(margin*2)/actualImageWidth)
}
The result: Bears
Full code of the component:
import React, { useState, useEffect } from "react";
import { Dimensions, Image } from "react-native";
interface AnotherCardProps {
thumbnail: string;
margin?: number;
column?: number;
maxHeight?: number;
minHeight?: number;
}
const AnotherCard: React.FC<AnotherCardProps> = (props) => {
const [imageSize, setImageSize] = useState({ width: 0, height: 0, ratio: 0 });
const margin = props.margin || 0;
const column = props.column || 1;
const newWidth = Dimensions.get("window").width / column - margin * 2;
const maxHeight = props.maxHeight || newWidth * 1.5;
const minHeight = props.minHeight || newWidth;
useEffect(() => {
Image.getSize(props.thumbnail, (w, h) =>
setImageSize({
width: w,
height: h,
ratio: newWidth / w,
})
);
});
return (
<Image
style={{
borderRadius: 20,
margin: margin,
flex: 1,
width: newWidth,
height:
imageSize.height * imageSize.ratio < minHeight
? minHeight
: imageSize.height * imageSize.ratio > maxHeight
? maxHeight
: imageSize.height * imageSize.ratio,
resizeMode: "cover",
}}
source={{
uri: props.thumbnail,
}}
/>
);
};
export default AnotherCard;

Not getting accurate screen height and width with Dimensions in react native

I am trying to use Dimensions to get device screen height and width.
Below is my code:
return (
<SafeAreaView style={styles.safeAreaView}>
<View style={styles.mainContainer}>
</View>
<View style={styles.footerContainer}>
<Text>Hello</Text>
</View>
</SafeAreaView>
);
And this the style which I am using:
const styles = StyleSheet.create({
mainContainer: {
height: (Dimensions.get('window').height / 100) * 80,
backgroundColor: "blue",
},
footerContainer: {
top: (Dimensions.get('window').height / 100) * 80,
height: (Dimensions.get('window').height / 100) * 20,
width: Dimensions.get('window').width / 100 * 100,
backgroundColor: "yellow",
position: "absolute",
justifyContent: "flex-end"
}
});
OUTPUT
As you can see I am not able to see the <Text>Hello</Text>.
I am doing basic mathematics with (Dimensions.get('window').height / 100) * 80. I am taking total height of the screen, dividing it by hundred and then multiplying the result with the required number: this will give me the percentage height of the screen. I don't want to use flex. I want to go forward with the process which I am following. I just want to know why my Hello text is going below the screen.
It works on some device but not on another. It works in Pixel4 emulator, but not on Pixel3 emulator. If my dimensions calculation is right, then why is it not working on all the devices??
"why is it not working on all the devices??" - this is because Dimensions.get('...').height is currently buggy in Android see this issue.
To get WINDOW_HEIGHT_NO_STATUS_BAR and STATUS_BAR_HEIGHT (so window full height = WINDOW_HEIGHT_NO_STATUS_BAR + STATUS_BAR_HEIGHT)
I used this code:
import { getStatusBarHeight } from 'react-native-status-bar-height'
import { initialWindowMetrics } from 'react-native-safe-area-context'
export const STATUS_BAR_HEIGHT = getStatusBarHeight()
export const WINDOW_HEIGHT_NO_STATUS_BAR = Platform.OS !== 'ios' && Dimensions.get('screen').height !== Dimensions.get('window').height && STATUS_BAR_HEIGHT > 24
? Dimensions.get('screen').height - STATUS_BAR_HEIGHT
: STATUS_BAR_HEIGHT > 24
? Dimensions.get('window').height - STATUS_BAR_HEIGHT
: Dimensions.get('window').height + initialWindowMetrics.insets.bottom === Dimensions.get('screen').height
? Dimensions.get('window').height - STATUS_BAR_HEIGHT
: Dimensions.get('window').height

get rid of border in Card Component React native element

In the Card Component for react native elements
I'm trying to get rid of the border by setting the border to 0 and borderColor to transparent but there's still a gray outline
<Card
containerStyle={{borderWidth: 0, borderColor: 'transparent', elevation: 0}}
title='HELLO WORLD'
image={require('../images/pic2.jpg')}>
<Text style={{marginBottom: 10}}>
The idea with React Native Elements is more about component structure than actual design.
</Text>
</Card>
Thought it might have been box shadow, but that's not it either
I've got the same issue, and I've found that border appears because the Card element has an elevation default setted to 1
You can override this (for android) :
<Card containerStyle={{elevation:0, backgroundColor:#123}}/>
and in IOS:
const styles = {
container: {
shadowColor: 'rgba(0,0,0, .2)',
shadowOffset: { height: 0, width: 0 },
shadowOpacity: 0, //default is 1
shadowRadius: 0//default is 1
}
}
<Card containerStyle={styles.container} />
Its late but it seems that a lot of people still searching for the Answer.
React Native Elements by default have set both borderWidth and shadow Props, so in order to remove border completely you need to remove both Border and Shadow.
<Card containerStyle={styles.cardCnt}>
<Text>Content</Text>
</Card>
const styles = {
cardCnt: {
borderWidth: 0, // Remove Border
shadowColor: 'rgba(0,0,0, 0.0)', // Remove Shadow for iOS
shadowOffset: { height: 0, width: 0 },
shadowOpacity: 0,
shadowRadius: 0,
elevation: 0 // Remove Shadow for Android
}
};
It looks like react native elements' Card component has a grey border in all of the examples I've seen. I'd suggest building your own card component. Start with something like this and then style it however you want. This one has a bit of shadow which you can turn off by passing it a noShadow prop.
import React from 'react';
import { View, StyleSheet } from 'react-native';
const Card = (props) => {
let shadowStyle = {
shadowColor: COLORS.grey3,
shadowOffset: { width: 0, height: 0 },
shadowOpacity: .5,
shadowRadius: 12,
elevation: 1,
}
if (props.noShadow) {
shadowStyle = {}
}
return (
<View style={[styles.containerStyle, props.style, shadowStyle]}>
{props.children}
</View>
);
};
const styles = StyleSheet.create({
containerStyle: {
padding: 10,
marginHorizontal: 10,
backgroundColor: COLORS.white,
borderRadius: 3,
}
})
export { Card };
Then when you want to use it just
import { Card } from './yourCustomCardFile'
Then in your render method
<Card>
<Text>Any content you want to include on the card</Text>
<Text>More content that you want on the card</Text>
</Card>
set elevation to 0 and borderColor to white like this
<Card containerStyle={{ elevation: 0, borderColor: "white" }}>
set to screen background color
Dirty but problem solved.

React-Native: How to add full screen Lottie animation

I am using linear gradient from lottie, the code is working fine with ios but in android its not fitting to full screen, there is some kind of padding between gradient and the view.
On ios its working fine...i tried many ways,
buy including padding to 0 and even margin to -20, but nothing worked...any solution?
import React, { Component } from 'react';
import {
Text,
StyleSheet,
View,
Platform,
Dimensions
} from 'react-native';
import SignInScreen from './src/screens/auth/SignInScreen';
import Animation from 'lottie-react-native';
import anim from './assets/gradient_animated_background.json';
const height = Dimensions.get('window').height + 20;
const width = Dimensions.get('window').width + 20;
export default class App extends Component {
componentDidMount() {
this.animation.play();
}
render() {
return (
<View style={styles.container}>
<Animation
ref={animation => {
this.animation = animation;
}}
style={{
backgroundColor: 'red',
height: '100%',
width: '100%'
}}
loop={true}
source={Platform.OS === 'ios' ? anim : 'gradient_animated_background.json'}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'blue',
flex: 1,
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
color: '#ffffff'
}
});
The animation, and when ever i keep changing the width and height..it forcefully tries to maintain the aspect radio...(not sure though)
{"v":"4.6.10","fr":15,"ip":0,"op":155,"w":1080,"h":1920,"nm":"background","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[540,960,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[1160,880]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect"},{"ty":"st","c":{"a":0,"k":[0.9960784,0.7843137,0.145098,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":6},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"gf","o":{"a":0,"k":100},"r":1,"g":{"p":3,"k":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,0.511,0.89,0.283,0.5,0.334,0.873,0.583,1,0.156,0.857,0.882],"e":[0,0.726,0.283,0.89,0.5,0.441,0.356,0.886,1,0.156,0.429,0.882]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[0,0.726,0.283,0.89,0.5,0.441,0.356,0.886,1,0.156,0.429,0.882],"e":[0,0.89,0.283,0.283,0.5,0.886,0.553,0.219,1,0.882,0.823,0.156]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[0,0.89,0.283,0.283,0.5,0.886,0.553,0.219,1,0.882,0.823,0.156],"e":[0,0,0.312,0.737,0.5,0.078,0.597,0.754,1,0.156,0.882,0.771]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":91,"s":[0,0,0.312,0.737,0.5,0.078,0.597,0.754,1,0.156,0.882,0.771],"e":[0,0.51,0.89,0.282,0.5,0.333,0.873,0.582,1,0.157,0.855,0.882]},{"t":120}]}},"s":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[-430.769,-404.573],"e":[23.726,-364.48],"to":[75.7491683959961,6.68213844299316],"ti":[-123.915840148926,-8.51547145843506]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[23.726,-364.48],"e":[312.726,-353.48],"to":[123.915840148926,8.51547145843506],"ti":[-1.00208830833435,-1.83333337306976]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[312.726,-353.48],"e":[29.739,-353.48],"to":[1.00208830833435,1.83333337306976],"ti":[120.055290222168,0.60746711492538]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":91,"s":[29.739,-353.48],"e":[-407.606,-357.125],"to":[-120.055290222168,-0.60746711492538],"ti":[72.8907089233398,0.60746711492538]},{"t":120}]},"e":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[374.412,342.611],"e":[22.822,357.191],"to":[-58.5984153747559,2.42986845970154],"ti":[132.520950317383,-7.89707231521606]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[22.822,357.191],"e":[-420.714,389.994],"to":[-132.520950317383,7.89707231521606],"ti":[-4.68509674072266,-7.89707231521606]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[-420.714,389.994],"e":[50.932,404.573],"to":[4.68509674072266,7.89707231521606],"ti":[-132.918350219727,4.25226974487305]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":91,"s":[50.932,404.573],"e":[376.797,364.48],"to":[132.918350219727,-4.25226974487305],"ti":[-54.3107261657715,6.68213844299316]},{"t":120}]},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[93.29,219.491],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":155,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":1,"nm":"Deep Red Solid 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[540,960,0]},"a":{"a":0,"k":[540,960,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"sw":1080,"sh":1920,"sc":"#be2a2a","ip":0,"op":155,"st":0,"bm":0,"sr":1}]}
What you are missing is the resizeMode, which is not specified on the documentation page, but if you look at the source you'll find it.
Here's something that works if you don't care to lose a few pixels:
import React, { Component } from 'react';
import {
StyleSheet,
View,
Dimensions
} from 'react-native';
import LottieView from 'lottie-react-native';
import { anim } from './assets/animation.json';
const { height, width } = Dimensions.get('window')
export default class App extends Component {
componentDidMount() {
this.animation.play();
}
render() {
return (
<View style={styles.container}>
<LottieView
ref={animation => {
this.animation = animation;
}}
style={{
width: width + 10,
height: height,
marginLeft: - 5
}}
resizeMode='cover'
loop={true}
source={anim}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'blue',
flex: 1,
},
});
Notice that I've exported the asset a bit differently since I tried this on https://snack.expo.io and for some reason they don't like JSON files 😁, so now the assets look something
/assets/animation.json.js
export const anim = {"v":"4.6.10","fr":15,"ip":0,"op":155,"w":1080,"h":1920,"nm":"background","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[540,960,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[1160,880]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect"},{"ty":"st","c":{"a":0,"k":[0.9960784,0.7843137,0.145098,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":6},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"gf","o":{"a":0,"k":100},"r":1,"g":{"p":3,"k":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,0.511,0.89,0.283,0.5,0.334,0.873,0.583,1,0.156,0.857,0.882],"e":[0,0.726,0.283,0.89,0.5,0.441,0.356,0.886,1,0.156,0.429,0.882]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[0,0.726,0.283,0.89,0.5,0.441,0.356,0.886,1,0.156,0.429,0.882],"e":[0,0.89,0.283,0.283,0.5,0.886,0.553,0.219,1,0.882,0.823,0.156]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[0,0.89,0.283,0.283,0.5,0.886,0.553,0.219,1,0.882,0.823,0.156],"e":[0,0,0.312,0.737,0.5,0.078,0.597,0.754,1,0.156,0.882,0.771]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":91,"s":[0,0,0.312,0.737,0.5,0.078,0.597,0.754,1,0.156,0.882,0.771],"e":[0,0.51,0.89,0.282,0.5,0.333,0.873,0.582,1,0.157,0.855,0.882]},{"t":120}]}},"s":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[-430.769,-404.573],"e":[23.726,-364.48],"to":[75.7491683959961,6.68213844299316],"ti":[-123.915840148926,-8.51547145843506]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[23.726,-364.48],"e":[312.726,-353.48],"to":[123.915840148926,8.51547145843506],"ti":[-1.00208830833435,-1.83333337306976]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[312.726,-353.48],"e":[29.739,-353.48],"to":[1.00208830833435,1.83333337306976],"ti":[120.055290222168,0.60746711492538]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":91,"s":[29.739,-353.48],"e":[-407.606,-357.125],"to":[-120.055290222168,-0.60746711492538],"ti":[72.8907089233398,0.60746711492538]},{"t":120}]},"e":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[374.412,342.611],"e":[22.822,357.191],"to":[-58.5984153747559,2.42986845970154],"ti":[132.520950317383,-7.89707231521606]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[22.822,357.191],"e":[-420.714,389.994],"to":[-132.520950317383,7.89707231521606],"ti":[-4.68509674072266,-7.89707231521606]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[-420.714,389.994],"e":[50.932,404.573],"to":[4.68509674072266,7.89707231521606],"ti":[-132.918350219727,4.25226974487305]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":91,"s":[50.932,404.573],"e":[376.797,364.48],"to":[132.918350219727,-4.25226974487305],"ti":[-54.3107261657715,6.68213844299316]},{"t":120}]},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[93.29,219.491],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":155,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":1,"nm":"Deep Red Solid 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[540,960,0]},"a":{"a":0,"k":[540,960,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"sw":1080,"sh":1920,"sc":"#be2a2a","ip":0,"op":155,"st":0,"bm":0,"sr":1}]}
So the first answer raised an important point (adding resizeMode="cover").
But that's not enough, If you test across several screens sizes, you might still find unwanted margins and spaces. I had this issue too,
Here's the simple solution:
Get the dimensions of the lottie file (e.g 300 X 600)
Set width only, then use aspectRatio to determine the height. (must)
Set flexGrow = 1 (must)
e.g
<LottieView
style={{
width: 300,
aspectRatio: 300 / 600,
flexGrow: 1,
alignSelf: 'center',
}}
resizeMode="cover"
ref={animation=> { this.animation = animation; }}
source={require ('./assets/animation.json')}
autoPlay={false}
loop={false}
/>
I guess the problem arises because you cant use width and height at the same time in the styling of the Lottie view.
So an easy workaround is to use the width and aspectRatio
Good luck!

how to create circle shape in react native with flex box

this is my component:
const styles = {
menuContainer: {
flex: 1,
flexDirection: 'column'
},
menuItem: {
flex: 1,
borderRadius: ??
}
}
<View style={styles.menuContainer}>
<TouchableOpacity {styles.menuItem}/>
<TouchableOpacity {styles.menuItem}/>
</View>
bordeRadius in react native doesn't work with percentage like 50% and in flex box i don't know the width of each flexItem. do you have any idea without calculate width of each flexItem?
Bad news, If you don't know the container's dimensions ahead of time, then I think you're only option is to use onLayout to calculate each flex container's dimensions.
{nativeEvent: { layout: {x, y, width, height}}}
If you can declare a fixed width & height, then it's easy, but sounds like this isn't going to be news to you.
circle: {
width: 100,
height: 100,
borderRadius: 100/2
}
There's a feature request submitted on this feature already. Show your support by up-voting it here...
https://react-native.canny.io/feature-requests/p/borderradius-percentages
Sorry!
I think that we cannot give border-radius to the flex so we can use width and height by getting device Dimensions and give the border-radius to the view.