React-native animated: после переворачивания карты, пытаясь заставить ее отображаться поверх другого контента - PullRequest
0 голосов
/ 16 июня 2019

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

Вот начальный экран:

enter image description here

Вот экран после анимации:

enter image description here

Вот код:

import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  Text,
  Animated,
  Button,
  Dimensions,
  TouchableWithoutFeedback,
} from 'react-native';

const { width, height } = Dimensions.get('window');

export default class App extends Component {
  state = {
    animation: new Animated.ValueXY(),
    scaleAnimation: new Animated.Value(1),
    box1RotateAnimation: new Animated.Value(0),
  };

  startAnimation = () => {
    Animated.parallel([
      Animated.timing(this.state.animation.y, {
        toValue: height / 2 - this._height / 2,
        duration: 500,
        useNativeDriver: true,
      }),
      Animated.timing(this.state.animation.x, {
        toValue: width / 2 + this._width * 0.14,
        duration: 500,
        useNativeDriver: true,
      }),
      Animated.timing(this.state.scaleAnimation, {
        toValue: 2,
        duration: 500,
        useNativeDriver: true,
      }),
    ]).start(() => {
      Animated.sequence([
        Animated.timing(this.state.box1RotateAnimation, {
          toValue: 180,
          duration: 500,
          useNativeDriver: true,
        })
      ]).start();
    });
  };

  goBack = () => {
    Animated.sequence([
      Animated.timing(this.state.box1RotateAnimation, {
        toValue: 0,
        duration: 500,
        useNativeDriver: true,
      })
    ]).start(() => {
      Animated.parallel([
        Animated.timing(this.state.animation.y, {
          toValue: 0,
          duration: 500,
          useNativeDriver: true,
        }),
        Animated.timing(this.state.animation.x, {
          toValue: 0,
          duration: 500,
          useNativeDriver: true,
        }),
        Animated.timing(this.state.scaleAnimation, {
          toValue: 1,
          duration: 500,
          useNativeDriver: true,
        }),
      ]).start();
    });
  }

  saveDimensions = e => {
    this._width = e.nativeEvent.layout.width;
    this._height = e.nativeEvent.layout.height;
  };

  render() {
    const frontInterpolate = this.state.box1RotateAnimation.interpolate({
      inputRange: [0, 180],
      outputRange: ['0deg', '180deg'],
    });

    const backInterpolate = this.state.box1RotateAnimation.interpolate({
      inputRange: [0, 180],
      outputRange: ['180deg', '360deg'],
    });

    const parentAnimation = {
      transform: [
        {
          translateX: this.state.animation.x
        },
        {
          translateY: this.state.animation.y
        },
        {
          scale: this.state.scaleAnimation
        },
      ],
    };

    const box1Animation = {
      transform: [
        {
          rotateY: frontInterpolate,
        },
      ],
    };

    const box2Animation = {
      transform: [
        {
          rotateY: backInterpolate,
        },
      ],
    };

    return (
      <View style={styles.container}>
        <View style={{zIndex: 2}}>
          <TouchableWithoutFeedback onPress={this.startAnimation}>
            <Animated.View style={parentAnimation} onLayout={this.saveDimensions}>
              <Animated.View style={[styles.box, box1Animation]}>
                <Text>Front</Text>
              </Animated.View>
              <Animated.View style={[box2Animation, styles.box, styles.box2]}>
                <Text>Back</Text>
                <View>
                  <Button
                    onPress={() => this.goBack()}
                    title="Go Back"
                  />
                </View>
              </Animated.View>
            </Animated.View>
          </TouchableWithoutFeedback>
        </View>
        <View style={{alignItems: 'flex-end', justifyContent: 'center', zIndex: 1}}>
          <View style={styles.box3}>
            <Text>Test Box</Text>
          </View>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  container2: {
    alignItems: 'flex-end',
    justifyContent: 'center',
  },
  box: {
    width: 150,
    height: 150,
    backgroundColor: 'tomato',
    alignItems: 'center',
    justifyContent: 'center',
    top: 0,
    left: 0,
    backfaceVisibility: 'hidden',
  },
  box2: {
    backgroundColor: 'green',
    position: 'absolute',
  },
  box3: {
    width: width / 2,
    height: 400,
    backgroundColor: 'brown',
  },
});

Есть идеи, почему анимированная коробка находится под коричневой рамкой справа?Насколько я понимаю, оба эти представления являются дочерними элементами основного внешнего элемента представления, поэтому они являются братьями и сестрами друг друга.То есть тот, у которого zIndex (анимированный прямоугольник) выше, должен появиться сверху, верно?

...