0

I'm facing a problem with centring the text after the animation finishes as you can see in the video here https://www.youtube.com/watch?v=hhBGUp9_GAY&feature=youtu.be. I want to get both titles perfectly centered horizontally on all devices no matter the screen width. I'm using the Animated API. Any suggestions?

Here is my approach

import React, { useEffect } from "react";
import { View, StyleSheet, Animated, Text, Dimensions, AsyncStorage } from "react-native";

export default function Welcome({ navigation }) {
  const width = Dimensions.get('screen').width

  let position1 = new Animated.ValueXY(0, 0);
  let position2 = new Animated.ValueXY(0, 0);
  useEffect(() => {
    Animated.timing(position1, {
      toValue: { x: width / 4.5, y: 0 },
      duration: 900
    }).start();
    Animated.timing(position2, {
      toValue: { x: -width / 3, y: 0 },
      duration: 900
    }).start();
  }, []);

  _retrieveData = async () => {
    try {
      const token = await AsyncStorage.getItem('tokehhn');
      if (token !== null) {
        // We have data!!
        setTimeout(() => navigation.navigate('Home'), 2000)
      } else {
        setTimeout(() => navigation.navigate('Auth'), 2000)
      }
    } catch (error) {
      // Error retrieving data
    }
  };

  useEffect(() => {
    _retrieveData()
  }, [])

  return (
    <View style={styles.container}>
      <Animated.View style={position1.getLayout()}>
        {/* <View style={styles.ball} /> */}
        <Text style={{ position: 'relative', fontWeight: 'bold', fontSize: 24, color: '#5790f9' }}>Welcome to Glue</Text>
      </Animated.View>
      <Animated.View style={position2.getLayout()}>
        {/* <View style={styles.ball} /> */}
        <Text style={{ position: 'relative', right: -220, fontWeight: 'bold', fontSize: 21, color: '#5790f9' }}>Where everything happens</Text>
      </Animated.View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center'
  }
});
Rajan
  • 1,512
  • 2
  • 14
  • 18

2 Answers2

0

Thats how you do it:

let {width} = Dimensions.get('window')

export default function App() {
  let animation = new Animated.Value(-width);
  let translateX = animation.interpolate({inputRange:[-width,0],outputRange:[2*width,0]});
  React.useEffect(()=>{
    Animated.timing(animation,{toValue:0}).start();
  },[])//eslint-ignore-line
  return (
    <View style={styles.container}>
      <Animated.Text style={[styles.text,{transform:[{translateX:animation}]}]}>LOL</Animated.Text>
      <Animated.Text style={[styles.text,{transform:[{translateX}]}]}>Longer LOLLLL</Animated.Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  text:{
    textAlign:'center'
  }
});

I have created snack as well

OriHero
  • 1,168
  • 1
  • 10
  • 24
0

Make it a simple and clean interpolation.

The code looks always clean, and readable if we use Animated.Value in range of 0 - 1.


Full code:

    import React, {useEffect} from 'react';
    import {View, StyleSheet, Animated} from 'react-native';

    const App = () => {
      const animate = new Animated.Value(0);
      const inputRange = [0, 1];
      const translate1 = animate.interpolate({inputRange, outputRange: [-100, 0]});
      const translate2 = animate.interpolate({inputRange, outputRange: [100, 0]});
      useEffect(() => {
        Animated.timing(animate, {
          toValue: 1,
          duration: 1000,
          useNativeDriver: true,
        }).start();
      }, []);
      return (
        <View style={styles.container}>
          <Animated.Text
            style={[styles.text, {transform: [{translateX: translate1}]}]}>
            First Text
          </Animated.Text>
          <Animated.Text
            style={[styles.text, {transform: [{translateX: translate2}]}]}>
            Second Text
          </Animated.Text>
        </View>
      );
    };

    export default App;

    const styles = StyleSheet.create({
      container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
      },
      text: {
        fontSize: 25,
      },
    });

Using that animated value, implement any other animations if needed.

For example, If you need to scale the text while moving:

const scale = animate.interpolate({inputRange, outputRange: [1, 1.5]});
Aswin C
  • 1,152
  • 7
  • 12
  • When possible, please make an effort to provide additional explanation instead of just code. Such answers tend to be more useful as they help members of the community and especially new developers better understand the reasoning of the solution, and can help prevent the need to address follow-up questions. – Rajan May 20 '20 at 13:47