React Native FlatList中的卡片堆栈动画

时间:2019-02-01 12:45:11

标签: react-native

我正在尝试在React Native中实现以下纸牌堆栈动画。

https://streamable.com/ba8z4

目前,我正在使用FlatList并根据列表translateY对每个卡片scrollPosition的位置进行动画处理。

不幸的是,它仍然无法按预期工作,因为当我只希望最上面的卡片移动到堆栈外时,所有卡片都在移动。

任何帮助将不胜感激!

这是我的实现方式

小吃:https://snack.expo.io/@tijp/flatlist-animations-card-stack

import * as React from 'react';
import { Animated, Dimensions, FlatList, Text, View, StyleSheet } from 'react-native';

const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
const cards = [{
  key: 'Card 1',
  color: '#3498db',
}, {
  key: 'Card 2',
  color: '#2ecc71',
}, {
  key: 'Card 3',
  color: '#e74c3c',
}, {
  key: 'Card 4',
  color: '#f1c40f',
}]

const HEIGHT = Dimensions.get('window').height;
const CARD_HEIGHT = 200;
const TRANSLATE_Y = [
  HEIGHT - 280, // TranslateY of first card
  HEIGHT - CARD_HEIGHT - 245, // TranslateY of second card
  HEIGHT - CARD_HEIGHT - CARD_HEIGHT - 210, // TranslateY of third card
  HEIGHT - CARD_HEIGHT - CARD_HEIGHT - CARD_HEIGHT - 175, // TranslateY of fourth card
];

export default class App extends React.Component {
  state = { scroll: new Animated.Value(0) };

  renderCard = (index, card) => (
    <Animated.View style={{
      height: CARD_HEIGHT,
      backgroundColor: card.color,
      marginVertical: 10,
      borderRadius: 6,
      transform: [{
        translateY: this.state.scroll.interpolate({
          inputRange: [-1, 0, 900],
          outputRange: [TRANSLATE_Y[index], TRANSLATE_Y[index], 0],
        }),
      }],
    }}>
      <Text style={styles.cardTitle}>{card.key}</Text>
    </Animated.View>
  );

  render() {
    const { scroll } = this.state;

    return (
      <View style={styles.container}>
        <AnimatedFlatList
          data={cards}
          style={{ width: '100%' }}
          renderItem={({ index, item }) => this.renderCard(index, item)}
          onScroll={Animated.event(
            [{ nativeEvent: { contentOffset: { y: scroll }}}],
            { useNativeDriver: true },
          )}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: 40,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  cardTitle: {
    textAlign: 'center',
    color: '#fff',
    marginTop: 12,
    fontSize: 20,
    fontWeight: '800',
  }
});

0 个答案:

没有答案