Restrict movement of a stepper inside a view (Slider) in a Panresponder (React native)

46 views Asked by At

Good morning. I am new to react native animation, I am not able to figure out the following issue in my code. Please help. Stepper in following code get out of sliderview and everytime when stepper being pulled down its limt changes.

import React, { useRef, useState } from 'react';
import { Animated, PanResponder, SafeAreaView, StyleSheet, Text, View } from 'react-native';

const slider = () => {
    const [sliderDimensions, setSliderDimensions] = useState({
        height: null,
        top: null,
        bottom: null,
    });
    
    const stepperAnim = useRef(new Animated.Value(0)).current;
    const railFillAnim = useRef(new Animated.Value(0)).current;
    
    const stepperResponder = PanResponder.create({
        onStartShouldSetPanResponder: () => true,
        onPanResponderGrant: () => {
          console.log(stepperAnim._value)
          stepperAnim.setOffset(stepperAnim._value);
          railFillAnim.setOffset(railFillAnim._value);
        },
        onPanResponderMove: (evt, {gestureState, dy, moveY}) => {
          // console.log(gestureState)
          // console.log('moveY:=',moveY)
          // console.log('sliderDimension.top:=',sliderDimensions.top)
          // console.log('sliderDimension.bottom:=',sliderDimensions.bottom)
          if (moveY > sliderDimensions.top && moveY < sliderDimensions.bottom) {
            stepperAnim.setValue(dy);
            railFillAnim.setValue(-dy);
          }
        },
        onPanResponderRelease: () => {
          stepperAnim.flattenOffset();
          railFillAnim.flattenOffset();
        },
      });
    return (
        <SafeAreaView>
      <Text style={styles.title}>What's your height?</Text>
      <View
        style={styles.slider}
        onLayout={(evt) => {
          const {height, y} = evt.nativeEvent.layout;
          setSliderDimensions({
            height: height,
            top: y,
            bottom: y + height,
          });
        }}>
        <View style={styles.rail}>
          <Animated.View style={[styles.railFill, {height: railFillAnim}]}>
            {sliderDimensions.height
              ? Array.apply(
                  null,
                  Array(Math.floor(sliderDimensions.height / 10)),
                ).map((item, index) => (
                  <View
                    key={index}
                    style={[styles.railFillSpace, {bottom: index * 10}]}
                  />
                ))
              : null}
          </Animated.View>
        </View>
        <Animated.View
          {...stepperResponder.panHandlers}
          style={[
            styles.stepper,
            {
              transform: [{translateY: stepperAnim}],
            },
          ]}
        />
      </View>
    </SafeAreaView>
  );
};

export default slider

const styles = StyleSheet.create({
    title: {
        textAlign: 'center',
        fontSize: 20,
        marginVertical: 50,
      },
      slider: {
        width: 50,
        height: '80%',
        marginLeft: 'auto',
        marginRight: 'auto',
        position: 'relative',
        marginBottom: 50,
      },
      rail: {
        width: 20,
        height: '100%',
        marginLeft: 'auto',
        marginRight: 'auto',
        backgroundColor: '#DBDBDB',
      },
      stepper: {
        width: '100%',
        height: 25,
        backgroundColor: 'black',
      },
      railFill: {
        width: '100%',
        backgroundColor: '#CBAA71',
        position: 'absolute',
        bottom: 0,
      },
      railFillSpace: {
        height: 5,
        width: '100%',
        backgroundColor: 'white',
        position: 'absolute',
      },
})

I want to limit the stepper inside a slider view, but the stepper jump out of top of slider and when pulled down it get restricted well above actual bottom of the slider. Even this new bottom value keeps changing by 2-3 points.

0

There are 0 answers