Наложение меньше, чем у родительских элементов в React Native - PullRequest
3 голосов
/ 09 апреля 2020

У меня следующая проблема со стилизованными компонентами. Я хочу скрыть фон с новым кругом, но тот, что находится спереди, меньше, даже если у меня те же значения для размера. Вот мой пример кода:

import React from "react";
import { StyleSheet, View } from "react-native";

const SIZE = 50;

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.layer1} />
      <View style={styles.layer2} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "white",
    alignItems: "center",
    justifyContent: "center",
  },
  layer1: {
    width: SIZE,
    height: SIZE,
    borderWidth: 3,
    borderRadius: SIZE / 2,
    borderColor: "black",
    position: "absolute",
  },
  layer2: {
    width: SIZE,
    height: SIZE,
    borderWidth: 3,
    borderRadius: SIZE / 2,
    borderColor: "white",
    position: "absolute",
  },
});

А вот скриншот:

Кто-нибудь знает, почему оверлей меньше, чем фоновый слой?

С уважением и благодарностью !!!

Ответы [ 3 ]

1 голос
/ 12 апреля 2020

Мне кажется, что это из-за css размера блока .
. По умолчанию в большинстве браузеров box-sizing: content-box; отступы и ширина границы добавляются к высоте и ширине. .
, но с box-sizing: border-box;, padding и border-width содержатся в пределах установленной ширины и высоты.
, поэтому ..
вы, вероятно, захотите добавить box-sizing: border-box;.

Обычно я добавляю его ко всему документу с помощью

html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}

Редактировать (после добавления скриншота)

Проблема не в том один круг меньше ... просто из-под него выглядывает более темная граница.

Вот пример, где вы можете изменить цвет и видимость, чтобы сделать то, что неправильно, очевидным. Запустите фрагмент и установите второй флажок, чтобы быстро увидеть его.

function colourChange(e) {
  var target = e.target.getAttribute('data-target');
  var style = e.target.getAttribute('data-style');
  var col = e.target.value;
  document.getElementById(target).style[style] = col;
}

function visChange(e) {
  var target = e.target.getAttribute('data-target');
  document.getElementById(target).style.display = (e.target.checked) ? 'block' : 'none';
}

function toFront(e) {
	var other = 'layer1';
	if (e.target.value == 'layer1') {
  	var other = 'layer2';
  }
  var otherz = document.getElementById(other).style.zIndex;
	var layer = document.getElementById(e.target.value);
	layer.style.zIndex = parseInt(otherz) + 1;
}

document.getElementById('border-col1').addEventListener('change', colourChange);
document.getElementById('border-col2').addEventListener('change', colourChange);
document.getElementById('background-col1').addEventListener('change', colourChange);
document.getElementById('background-col2').addEventListener('change', colourChange);
document.getElementById('vis1').addEventListener('change', visChange);
document.getElementById('vis2').addEventListener('change', visChange);
document.getElementById('front1').addEventListener('change', toFront);
document.getElementById('front2').addEventListener('change', toFront);
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}

#container {
    flex: 1;
    background-color: white;
    align-items: center;
    justify-content: center;
  }
  #layer1 {
    width: 50px;
    height: 50px;
    border-width: 3px;
    border-radius: 25px;
    border-color: black;
    position: absolute;
    border-style: solid;
  }
  #layer2 {
    width: 50px;
    height: 50px;
    border-width: 3px;
    border-radius: 25px;
    border-color: white;
    position: absolute;
    border-style: solid;
  }
  
#inputs {
  position: absolute;
  top: 0px;
  right: 0px;
  padding: 10px;
}
<div id="container">
  <div id="layer1" style="z-index:1;"></div>
  <div id="layer2" style="z-index:2;"></div>
</div>
<div id="inputs">
  <div>
    border colours  
  </div>
  <input type="color" id="border-col1" data-target="layer1" data-style="borderColor" value="#000000">
  <input type="color" id="border-col2" data-target="layer2" data-style="borderColor" value="#ffffff">
  <div>
    background colours  
  </div>
  <input type="color" id="background-col1" data-target="layer1" data-style="backgroundColor" value="#ffffff">
  <input type="color" id="background-col2" data-target="layer2" data-style="backgroundColor" value="#ffffff">
  <div>
    visibility<br/>(display block / none)  
  </div>
  <input type="checkbox" id="vis1" data-target="layer1" checked>
  <input type="checkbox" id="vis2" data-target="layer2" checked>
  <div>
    in front  
  </div>
  <input type="radio" id="front1" name="front" value="layer1">
  <input type="radio" id="front2" name="front" value="layer2">
</div>
0 голосов
/ 18 апреля 2020

Посмотрите этот код, вы можете сделать это без использования какой-либо внешней библиотеки: https://medium.com/@0saurabhgour /act-native-процент-на-основе-прогресс-круг-нет-внешняя-библиотека-e25b43e83888

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {StyleSheet, View, ViewPropTypes, I18nManager} from 'react-native';

// compatability for react-native versions < 0.44
const ViewPropTypesStyle = ViewPropTypes
  ? ViewPropTypes.style
  : View.propTypes.style;
let direction = I18nManager.isRTL ? 'right' : 'left';
const styles = StyleSheet.create({
  outerCircle: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  innerCircle: {
    overflow: 'hidden',
    justifyContent: 'center',
    alignItems: 'center',
  },
  leftWrap: {
    position: 'absolute',
    top: 0,
    [`${direction}`]: 0,
  },
  halfCircle: {
    position: 'absolute',
    top: 0,
    left: 0,
    borderTopRightRadius: 0,
    borderBottomRightRadius: 0,
  },
});

function percentToDegrees(percent) {
  return percent * 3.6;
}

export default class CircularProgress extends Component {
  static propTypes = {
    color: PropTypes.string,
    shadowColor: PropTypes.string,
    bgColor: PropTypes.string,
    radius: PropTypes.number.isRequired,
    borderWidth: PropTypes.number,
    percent: PropTypes.number.isRequired, // eslint-disable-line react/no-unused-prop-types
    children: PropTypes.node,
    containerStyle: ViewPropTypesStyle,
    outerCircleStyle: ViewPropTypesStyle,
  };

  static defaultProps = {
    color: '#f00',
    shadowColor: '#999',
    bgColor: '#e9e9ef',
    borderWidth: 2,
    children: null,
    containerStyle: null,
  };

  constructor(props) {
    super(props);
    this.state = this.getInitialStateFromProps(props);
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    this.setState(this.getInitialStateFromProps(nextProps));
  }

  getInitialStateFromProps(props) {
    const percent = Math.max(Math.min(100, props.percent), 0);
    const needHalfCircle2 = percent > 50;
    let halfCircle1Degree;
    let halfCircle2Degree;
    // degrees indicate the 'end' of the half circle, i.e. they span (degree - 180, degree)
    if (needHalfCircle2) {
      halfCircle1Degree = 180;
      halfCircle2Degree = percentToDegrees(percent);
    } else {
      halfCircle1Degree = percentToDegrees(percent);
      halfCircle2Degree = 0;
    }

    return {
      halfCircle1Degree,
      halfCircle2Degree,
      halfCircle2Styles: {
        // when the second half circle is not needed, we need it to cover
        // the negative degrees of the first circle
        backgroundColor: needHalfCircle2 ? props.color : props.shadowColor,
      },
    };
  }

  renderHalfCircle(rotateDegrees, halfCircleStyles) {
    const {radius, color} = this.props;
    const key = I18nManager.isRTL ? 'right' : 'left';
    return (
      <View
        style={[
          styles.leftWrap,
          {
            width: radius,
            height: radius * 2,
          },
        ]}>
        <View
          style={[
            styles.halfCircle,
            {
              width: radius,
              height: radius * 2,
              borderRadius: radius,
              overflow: 'hidden',
              transform: [
                {translateX: radius / 2},
                {rotate: `${rotateDegrees}deg`},
                {translateX: -radius / 2},
              ],
              backgroundColor: color,
              ...halfCircleStyles,
            },
          ]}
        />
      </View>
    );
  }

  renderInnerCircle() {
    const radiusMinusBorder = this.props.radius - this.props.borderWidth;
    return (
      <View
        style={[
          styles.innerCircle,
          {
            width: radiusMinusBorder * 2,
            height: radiusMinusBorder * 2,
            borderRadius: radiusMinusBorder,
            backgroundColor: this.props.bgColor,
            ...this.props.containerStyle,
          },
        ]}>
        {this.props.children}
      </View>
    );
  }

  render() {
    const {
      halfCircle1Degree,
      halfCircle2Degree,
      halfCircle2Styles,
    } = this.state;
    return (
      <View
        style={[
          styles.outerCircle,
          {
            width: this.props.radius * 2,
            height: this.props.radius * 2,
            borderRadius: this.props.radius,
            backgroundColor: this.props.shadowColor,
            ...this.props.outerCircleStyle,
          },
        ]}>
        {this.renderHalfCircle(halfCircle1Degree)}
        {this.renderHalfCircle(halfCircle2Degree, halfCircle2Styles)}
        {this.renderInnerCircle()}
      </View>
    );
  }
}
0 голосов
/ 17 апреля 2020

это способ, которым рендеринг движка рисует два перекрывающихся пути. они просто отчасти сглаживают. Вы можете решить эту проблему, немного увеличив ширину и высоту переднего круга, чтобы решить проблему, или вы можете скрыть тот, который стоит за

...