在本地反应中创建 CSS 圆圈

我在创建反应原生 CSS 圈时遇到了一些麻烦。下面这些在 iPhone6 Plus 中可以使用,但在其他所有的 iPhone 中,它们变成了钻石。

circle: {
height: 30,
width: 30,
borderRadius: 30,
}

现在,如果我在 borderRadius上使用像素比率,除了 iPhone6 + ,它在其他任何地方都可以工作。IPhone6加上呈现为圆角的盒子。

circle: {
height: 30,
width: 30,
borderRadius: 30 / PixelRatio.get(),
}
146453 次浏览

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.

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

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

React-native circle button

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.

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

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?

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

Demo