Переход от исчезновения к черному

Есть ли способ, чтобы навигационный переход React Native исчезал до черного, а затем плавно переходил от черного к следующему экрану?

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


person Shio    schedule 30.12.2019    source источник
comment
У вас может быть полноэкранный Animated.View с абсолютным позиционированием и backgroundColor: 'black' на вашем компоненте, начиная с opacity: 0. Затем, когда пользователь нажимает кнопку для навигации, вы переходите к непрозрачности, равной 1, и ваш обратный вызов после завершения анимации - это переход к следующему экрану. Ваш следующий экран начинается с того же компонента, но с непрозрачностью: 1, а ваш componentDidMount анимирует непрозрачность до 0. Я думаю, это должно сработать ...   -  person James    schedule 30.12.2019
comment
Элементы на экране все еще можно было увидеть, например, синюю кнопку ‹Button›, хотя анимация все еще присутствовала. нет?   -  person Shio    schedule 31.12.2019
comment
Даже если выставить высокий zIndex? В качестве альтернативы можно было бы сделать обратное: черный полноэкранный вид должен располагаться позади всего остального, то есть более низкий zIndex, чем основной вид, а затем исчезнуть с основного вида до opacity: 0   -  person James    schedule 31.12.2019


Ответы (2)


Если вы используете последнюю версию react-navigation-stack, вы можете использовать _2 _ / _ 3_ для этого:

import * as React from 'react';
import { Animated, Button, View, StyleSheet } from 'react-native';
import { createAppContainer } from 'react-navigation';
import {
  createStackNavigator,
  CardStyleInterpolators,
  HeaderStyleInterpolators,
  useCardAnimation,
} from 'react-navigation-stack';

function ScreenA({ navigation }) {
  return (
    <View style={{ flex: 1 }}>
      <Button onPress={() => navigation.push('ScreenB')} title="Go to B" />
    </View>
  );
}

function ScreenB() {
  const { current } = useCardAnimation();

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Animated.View
        style={[
          StyleSheet.absoluteFill,
          { backgroundColor: 'black', opacity: current.progress },
        ]}
      />
    </View>
  );
}

const Stack = createStackNavigator({
  ScreenA,
  ScreenB,
});
person satya164    schedule 02.01.2020

Просто поместите черный <div> за этим экраном и

Спасибо @Prajwal, решение для перехода CSS:

document.getElementsByTagName(`main`)[0].style.opacity = `0`;
  main {
    position: fixed; /* place it before .black */
    background-color: white;
    width: 100%;
    height: 100%;
    transition-property: opacity; /* set opacity to one of the transition properties */
    transition-duration: 4s; /* set transition duration */
  }

  .black {
    position: fixed; /* place it behind main */
    background-color: black; /* make it black */
    width: 100%; /* make it fill available space */
    height: 100%; /* make it fill available space*/
  }

  body {
    margin: 0; /* make it fill available space*/
  }
<body>
<div class="black"></div>
<main>
  <p>lorem</p>
</main>
</body>

Вы также можете использовать функцию setInterval(), чтобы уменьшить непрозрачность по крупицам.

  const step = 0.05; // set the step of opacity change
  const timeInterval = 200; // set the sleep time of opacity change
  const times = 1 / step; // calculate times needed for opacity change
  document.getElementsByTagName(`main`)[0].style.opacity = `1`; // set initial opacity to make getting the float value of it work.
  let time = 0; // initially, the time of making changes is zero
  const lowerOpacity = window.setInterval(function() {
      if (time + 1 === times) {
        window.clearInterval(lowerOpacity);
      } // clearInterval() when the time of changes has reached the needed times
      document.getElementsByTagName(`main`)[0].style.opacity =
        `${parseFloat(document.getElementsByTagName(`main`)[0].style.opacity) -
        0.05}`; // set the opacity to make it dimmer
      time += 1; // increment time to match the changed times
    }
    , timeInterval);
  main {
    position: fixed; /* place it before .black */
    background-color: white;
    width: 100%;
    height: 100%;
  }

  .black {
    position: fixed; /* place it behind main */
    background-color: black; /* make it black */
    width: 100%; /* make it fill available space */
    height: 100%; /* make it fill available space*/
  }

  body {
    margin: 0; /* make it fill available space*/
  }
<body>
<div class="black"></div>
<main>
  <p>lorem</p>
</main>
</body>

person fakeinc    schedule 30.12.2019
comment
Или используйте переходы CSS. Что делает то же самое, стоит меньше. - person Prajwal; 30.12.2019
comment
@Prajwal Спасибо, я не думал об этом. Обновлю свой ответ. - person fakeinc; 30.12.2019
comment
OP хочет знать, как это сделать в React Native :) - person VilleKoo; 30.12.2019
comment
@VilleKoo Я считаю, что это то же самое. Возможно, потребуется несколько настроек, но OP подойдет. :) - person fakeinc; 30.12.2019
comment
Нет, это не так, потому что React Native на самом деле не работает с DOM. - person VilleKoo; 30.12.2019
comment
React Native отличается, может быть, с API анимации или чем-то еще? - person Shio; 31.12.2019
comment
@VilleKoo Извините за задержку. У меня не было опыта реагирования, и я думал, что потребуется лишь незначительная корректировка. Опять же, извините за ваше время. Я думаю, что эта идея все еще применима здесь, поэтому я не решаюсь удалить этот ответ. Стоит ли его удалить? - person fakeinc; 02.01.2020
comment
Не думаю, что вам стоит его удалять, ваш ответ все равно поможет кому-то, кто работает с React :) - person VilleKoo; 02.01.2020
comment
@VilleKoo Спасибо, я оставлю это здесь. - person fakeinc; 02.01.2020