Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom switch slide animation React Native, how to make it smooth?

I need to make switch slide animation, and I almost did it, the slide animation to the right looks really good, but the slide animation to the left doesn't work smooth, any ideas how is possible to fix it?

Here is my code:

import * as Animatable from 'react-native-animatable';

 changeLogin = () => {
        if (!this.state.loginEmail){
            this.slideRight()
        } else {
            this.slideLeft()
        }
        this.setState({ loginEmail: !this.state.loginEmail })
      }

  handleViewRef = ref => this.view = ref;  

    slideRight = () => this.view.animate({ 

      0: {
        translateX: 0,
      },
      0.5: {
        translateX: 100,
      },
      1: {
        translateX: 150,
      },
      2: {
        translateX: 300,
    }  
      })


      slideLeft = () => this.view.animate({ 
        0: {
          translateX: 0,
        },
        0.5: {
          translateX: -0.3,
        },
        1: {
          translateX: -0.5,
        },
        2: {
          translateX: -1,
      }  
        })  


                    <TouchableWithoutFeedback  onPress={this.changeLogin}>
                        <View style={styles.buttonRowTop} >
                        <Animatable.View style={styles.buttonSwitch}
                        ref={this.handleViewRef}
                       >

                        </Animatable.View>
                        <View style={{flexDirection: 'row', justifyContent: 'space-between', width: 260, zIndex: 100, marginLeft: -180, marginTop: 5}}>
                            <Text style={[!loginEmail? styles.textSwitchActiveLeft: styles.textSwitchLeft ]}>Phone</Text> 
                            <Text  style={[loginEmail? styles.textSwitchInactive:styles.textSwitch]}>Email</Text> 
                        </View>
                        </View>
                    </TouchableWithoutFeedback>  

Here is how it looks right now:

enter image description here

like image 305
Lucky_girl Avatar asked Nov 02 '25 14:11

Lucky_girl


2 Answers

I changed slideLeft function, animation looks much smoother now:

 slideLeft = () => this.view.animate({ 
        0: {
          translateX: 100,
        },
        0.5: {
          translateX: -0.3,
        },
        1: {
          translateX: -0.5,
        },
        2: {
          translateX: -1,
        }  
        })   
like image 185
Lucky_girl Avatar answered Nov 04 '25 07:11

Lucky_girl


I custom the code with functional style

import React, { useRef, useState } from 'react';
import {
  StyleSheet,
  Text,
  View,
  TouchableWithoutFeedback,
  Dimensions,
} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { t } from 'i18next';
import appStyles from '../../../styles/global';
import COLORS from '../../../styles/colors';
import * as Animatable from 'react-native-animatable';

export const screenWidth = Dimensions.get('window').width;
let componentWidth = screenWidth;

const TransportMethod = props => {
  const [activeIndex, setActiveIndex] = useState(0);
  const updateIndex = () => {
    if (activeIndex === 0) {
      slideRight();
      setActiveIndex(1);
    } else {
      slideLeft();
      setActiveIndex(0);
    }
  };

  const handleViewRef = useRef(null);

  const slideRight = () =>
    handleViewRef.current.animate({
      0: {
        translateX: 0,
      },
      0.5: {
        translateX: 100,
      },
      1: {
        translateX: componentWidth / 2 - 5,
      },
    });

  const slideLeft = () =>
    handleViewRef.current.animate({
      0: {
        translateX: componentWidth / 2 - 5,
      },
      0.5: {
        translateX: componentWidth / 4,
      },
      1: {
        translateX: 0,
      },
    });

  return (
    <TouchableWithoutFeedback onPress={updateIndex}>
      <View
        style={styles.backgroundSwitch}
        onLayout={event => {
          componentWidth = event.nativeEvent.layout.width;
        }}
      >
        <Animatable.View
          duration={500}
          style={styles.buttonSwitch}
          ref={handleViewRef}
        />
        <View
          style={{
            flexDirection: 'row',
            justifyContent: 'space-between',
          }}
        >
          <Text style={[styles.textOption]}>Walk</Text>
          <Text style={[styles.textOption]}>Car</Text>
        </View>
      </View>
    </TouchableWithoutFeedback>
  );
};

const styles = StyleSheet.create({
  backgroundSwitch: {
    backgroundColor: '#F3F7F9',
    height: 50,
    borderRadius: 100,
    justifyContent: 'center',
  },
  textOption: {
    width: '50%',
    textAlign: 'center',
  },
  buttonSwitch: {
    position: 'absolute',
    backgroundColor: 'white',
    height: '80%',
    width: '48%',
    borderRadius: 100,
    left: '2%',
    right: '2%',
  },
});

export default TransportMethod;

like image 32
Tuan Pham Anh Avatar answered Nov 04 '25 08:11

Tuan Pham Anh