Как заставить Анимированный просмотр не превышать высоту экрана? - PullRequest
0 голосов
/ 14 марта 2020

Я реализую проигрыватель панели инструментов в React Native, используя PanResponder

, но у меня есть некоторые проблемы, когда я смахиваю панель инструментов вверх, она пересекает границу экрана и по-прежнему застревает в верхней части, но я не не хочу, чтобы это произошло, я хочу, чтобы пользователь проводил пальцем по верхней панели инструментов, заставляя его оставаться в исходных точках, таких как Soundcloud App, Google musi c Player и др. c.

GIF здесь

Как мне с этим справиться?

вот код или Закуска

class ToolbarPlayer extends Component {
  constructor(props) {
    super(props);
    this._animatedValue = new Animated.ValueXY({ x: 0, y: SCREEN_HEIGHT - 80 });
    this._panResponder = PanResponder.create({
      onMoveShouldSetPanResponder: () => true,
      onPanResponderGrant: (event, gestureState) => {
        this._animatedValue.extractOffset();
      },
      onPanResponderMove: (event, gestureState) => {
        this._animatedValue.setValue({ x: 0, y: gestureState.dy });
      },
      onPanResponderRelease: (event, gestureState) => {
        // Bottom player ' when user swipe player over bottom'
        if (gestureState.moveY > SCREEN_HEIGHT - 110) {
          Animated.spring(this._animatedValue.y, {
            toValue: 0,
            tension: 1,
          }).start();
        }
        //Bottom player ' when user swipe player over top' 
        else if (gestureState.moveY < 120) { // Not works :\
          Animated.spring(this._animatedValue.y, {
            toValue: 0,
            tension: 1,
          }).start();
        } else if (gestureState.dy < 0) {
          Animated.spring(this._animatedValue.y, {
            toValue: -SCREEN_HEIGHT + 120,
            tension: 1,
          }).start();
        } else if (gestureState.dy > 0) {
          Animated.spring(this._animatedValue.y, {
            toValue: SCREEN_HEIGHT - 120,
            tension: 1,
          }).start();
        }
      },
    });
  }

  render() {
    const animatedHeight = {
      transform: this._animatedValue.getTranslateTransform(),
    };

    const animatedImageHeight = this._animatedValue.y.interpolate({
      inputRange: [0, SCREEN_HEIGHT - 80],
      outputRange: [200, 32],
      extrapolate: 'clamp',
    });

    const animatedSongTitleOpacity = this._animatedValue.y.interpolate({
      inputRange: [0, SCREEN_HEIGHT / 2, SCREEN_HEIGHT - 80],
      outputRange: [0, 0, 1],
      extrapolate: 'clamp',
    });

    const animatedImageMarginLeft = this._animatedValue.y.interpolate({
      inputRange: [0, SCREEN_HEIGHT - 80],
      outputRange: [(SCREEN_WIDTH * 0.5) / 2, 5], //when image was in [Top =SCREEN_WIDTH / 2 - 100  , bottom = 5]
      extrapolate: 'clamp',
    });

    const animatedHeaderHeight = this._animatedValue.y.interpolate({
      inputRange: [0, SCREEN_HEIGHT - 80],
      outputRange: [SCREEN_HEIGHT / 2, 30],
      extrapolate: 'clamp',
    });

    const animatedBackgroundColor = this._animatedValue.y.interpolate({
      inputRange: [0, SCREEN_HEIGHT - 80],
      outputRange: ['rgba(0,0,0,0.5)', '#00fff0'],
      extrapolate: 'clamp',
    });
    // Content

    const animatedSongDetailsOpacity = this._animatedValue.y.interpolate({
      inputRange: [0, SCREEN_HEIGHT / 2, SCREEN_HEIGHT - 80],
      outputRange: [1, 0, 0],
      extrapolate: 'clamp',
    });
    return (
      <Animated.View
        style={{ flex: 1, backgroundColor: animatedBackgroundColor }}>
        <Animated.View
          {...this._panResponder.panHandlers}
          style={[
            animatedHeight,
            {
              position: 'absolute',
              left: 0,
              right: 0,
              zIndex: 999,
              backgroundColor: '#fff',
              height: SCREEN_HEIGHT,
            },
          ]}>
          <Animated.View
            style={{
              height: animatedHeaderHeight,
              borderTopWidth: 1,
              borderTopColor: '#fff',
              flexDirection: 'row',
              backgroundColor: '#f8f8f8',
              alignItems: 'center',
            }}>
            {/* Minie Player "image/title/icon 'pouse/play' " */}
            <View
              style={{
                flex: 4,
                flexDirection: 'row',
                alignItems: 'center',
              }}>
              <Animated.View
                style={{
                  height: animatedImageHeight,
                  width: animatedImageHeight,
                  marginLeft: animatedImageMarginLeft,
                }}>
                <Image
                  style={{ flex: 1, width: null, height: null }}
                  source={{
                    uri:
                      'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQCMYdRsaPP2LRTVc4FvvlbmHJH-BbkFhSZpmS-oovLiEP-dkAo',
                  }}
                />
              </Animated.View>

              <Animated.Text
                style={{
                  opacity: animatedSongTitleOpacity,
                  fontSize: 18,
                  paddingLeft: 10,
                }}>
                Hello World(Live)
              </Animated.Text>
            </View>
            <Animated.View
              style={{
                opacity: animatedSongTitleOpacity,
                flexDirection: 'row',
                flex: 1,
                justifyContent: 'space-around',
              }}>
              <Ionicons name="ios-play" size={25} />
              <Ionicons name="ios-pause" size={25} />
            </Animated.View>
          </Animated.View>

          {/* When View is open -Content  */}
          <Animated.View
            style={{
              height: animatedHeaderHeight,
              opacity: animatedSongDetailsOpacity,
            }}>
            {/* Song details */}
            <View
              style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'flex-end',
              }}>
              <Text style={{ fontWeight: 'bold', fontSize: 22 }}>
                Hello World (Live)
              </Text>
              <Text style={{ color: '#fa995f', fontSize: 18 }}>
                Without Me - Album (Live)
              </Text>
            </View>

            {/* Time Slider  */}
            <View
              style={{
                height: 40,
                width: SCREEN_WIDTH,
                alignItems: 'center',
              }}>
              <Text>Slider Here... </Text>
            </View>
            {/* Controller Icon here */}
            <View
              style={{
                flex: 4,
                flexDirection: 'row',
                alignItems: 'center',
                justifyContent: 'space-around',
              }}>
              <Ionicons name="ios-fastforward" size={35} />
              <Ionicons name="ios-pause" size={50} />
              <Ionicons name="ios-rewind" size={35} />
            </View>
          </Animated.View>
        </Animated.View>
      </Animated.View>
    );
  }
}
export default ToolbarPlayer;
...