garrettmac
8/16/2017 - 5:47 PM

Medium Blog Post - React Native Animation Cheat Sheet: Using the “LayoutAnimation” and “Animated” Components

Medium Blog Post - React Native Animation Cheat Sheet: Using the “LayoutAnimation” and “Animated” Components

Slidebox

import React, { Component } from 'react';
import {
  View,
  Text,
  Dimensions,
  FlatList,
  Animated,
  LayoutAnimation,
  StyleSheet,PanResponder,
  Easing,TouchableOpacity,
} from 'react-native';
const {width, height} = Dimensions.get('window');
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'

export default class Example extends Component {
  constructor(props){
    super(props);

    this.state={
      example:new Animated.ValueXY({x:100,y:0}),
      boo:false,
    }

    //create animation
    this.slideIn = Animated.timing(
      this.state.example,
      {
        toValue:{x:200,y:0},
        duration:2000,
        delay:1000,
        easing:Easing.in(Easing.ease)
      }
    )
  this.triggerAnimation=this.triggerAnimation.bind(this)
  }
  componentDidMount() {




  }
triggerAnimation(){
    this.slideIn.start()
}
  render() {
    const slideStyle = this.state.example.getTranslateTransform();

    return (
      <View style={[s.container]}>
        <TouchableOpacity onPress={this.triggerAnimation}
                style={{position:"absolute",top:25,right:10,flex:1,zIndex:3,width:35,height:35,alignItems:"center",justifyContent:"center",backgroundColor:"transparent"}}>
                <Icon name={"circle-outline"} size={25} color="rgba(0,0,0,0.5)"/>
        </TouchableOpacity>

      <Animated.View style={[s.animatedViewConatiner,{transform:slideStyle}]}>


        <Text style={s.text}>
          Hello
        </Text>

</Animated.View>
      </View>
    );
  }
}

const s = StyleSheet.create({
  animatedViewConatiner:{
    // flex:1,
    // position: 'absolute',
    width:100,
    height:100,
    justifyContent:"center",
    alignItems:"center",
    backgroundColor:"rgba(240,0,0,.5)",
  },
  container: {

    flex: 1,
    height,
    width,
    // justifyContent: "center",
    // alignItems: "center",
    backgroundColor: "#F5FCFF",
  },
  text:{
fontWeight:"600",
// fontSize:100,
textAlignVertical: "center", textAlign: "center",}
});

Popup

import React, { Component } from 'react';
import {
  View,
  Text,
  Dimensions,
  FlatList,
  Animated,
  LayoutAnimation,
  StyleSheet,PanResponder,
  Easing,TouchableOpacity,
} from 'react-native';
const {width, height} = Dimensions.get('window');
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'

const Button = (props) => {

    function getContent() {
        if(props.children){
            return props.children;
        }
        return <Text style={props.s.label}>{props.label}</Text>
    }

    return (
        <TouchableOpacity
            underlayColor="#ccc"
            onPress={props.onPress}
            style={[
                props.noDefaultStyles ? '' : s.button,
                props.s ? props.s.button : '']}
        >
            { getContent() }
        </TouchableOpacity>
    );
}

const NewsItem = ({ news, index }) => {

    function onPress(news) {
        //do anything you want
    }

    return (
        <Button
            key={index}
            noDefaultStyles={true}
            onPress={onPress.bind(this, news)}
        >
            <View style={s.news_item}>
                <Text style={s.title}>{news.title}</Text>
                <Text>{news.website}</Text>
            </View>
        </Button>
    );
}


export default class Example extends Component {
  constructor(props){
    super(props);

    this.y_translate = new Animated.Value(0);
      this.state = {
        menu_expanded: false
      };
      this.openMenu=this.openMenu.bind(this)
      this.hideMenu=this.hideMenu.bind(this)
  }
  componentDidMount() {




  }
triggerAnimation(){
    this.slideIn.start()
}
openMenu() {
  this.setState({
    menu_expanded: true
  }, () => {
    this.y_translate.setValue(0);
    Animated.spring(
      this.y_translate,
      {
        toValue: 1,
        friction: 3
      }
    ).start();
  });
  
}
hideMenu() {
  this.setState({
    menu_expanded: false
  }, () => {
    this.y_translate.setValue(1);
    Animated.spring(
      this.y_translate,
      {
        toValue: 0,
        friction: 4
      }
    ).start();
  });
}
  render() {
    // const slideStyle = this.state.example.getTranslateTransform();
    const menu_moveY = this.y_translate.interpolate({
           inputRange: [0, 1],
           outputRange: [0, -300]
       });
    return (
      <View style={[s.container]}>
        <TouchableOpacity onPress={this.hideMenu}
                style={{position:"absolute",top:25,right:10,flex:1,zIndex:3,width:35,height:35,alignItems:"center",justifyContent:"center",backgroundColor:"transparent"}}>
                <Icon name={"circle-outline"} size={25} color="rgba(0,0,0,0.5)"/>
        </TouchableOpacity>


<Animated.View
     style={[
       s.footer_menu,
       {
         transform: [
           {translateY: menu_moveY}
         ]
       }
     ]}
   >

     <TouchableOpacity
style={{justifyContent:"center",alignItems:"center",}}
       onPress={this.openMenu} noDefaultStyles={true}>
       <Icon name="circle-outline" size={50} color="red" />
     </TouchableOpacity>

     {/* <Text style={s.text}>
               Hello
             </Text> */}

   </Animated.View>

{
  !this.state.menu_expanded &&
  <View style={s.tip_menu}>
    <TouchableOpacity onPress={this.openMenu} noDefaultStyles={true}>
      <Icon name="circle-outline" size={50} color="red" />
    </TouchableOpacity>
  </View>
}
      </View>
    );
  }
}

const s = StyleSheet.create({
  animatedViewConatiner:{
    // flex:1,
    // position: 'absolute',
    width:100,
    height:100,
    justifyContent:"center",
    alignItems:"center",
    backgroundColor:"rgba(240,0,0,.5)",
  },
  container: {

    flex: 1,
    height,
    width,
    // justifyContent: "center",
    // alignItems: "center",
    backgroundColor: "#F5FCFF",
  },
  text:{
fontWeight:"600",
// fontSize:100,
textAlignVertical: "center", textAlign: "center",},






// container: {
//   flex: 10,
//   flexDirection: 'column'
// },
body: {
  flex: 10,
  backgroundColor: '#ccc'
},
footer_menu: {
  position: 'absolute',
  left:0,right:0,
  width: 600,
  height: 350,
  bottom: -300,
  backgroundColor: '#1fa67a',
  alignItems: 'center',
  // justifyContent:"center",
},
tip_menu: {
  flexDirection: 'row'
},
button: {
  backgroundColor: '#fff'
},
button_label: {
  fontSize: 20,
  fontWeight: 'bold'
}

});

Bar Graph

import React, { Component } from 'react';
import {
  View,
  Text,
  Dimensions,
  FlatList,
  Animated,
  LayoutAnimation,
  StyleSheet,PanResponder,
  Easing,TouchableOpacity,
} from 'react-native';
const {width, height} = Dimensions.get('window');
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
import randomcolor from 'randomcolor';
const DELAY = 100;

class AnimatedBar extends Component {
  // ...
  constructor(props) {
    super(props);

    this._width = new Animated.Value(0); // Added
    this.state = {
      // color: "blue",
      color: randomcolor()
    };
  }
  componentDidMount() {
    this.animateTo(this.props.delay, this.props.value);
  }

  componentWillReceiveProps(nextProps) {
    this.animateTo(nextProps.delay, nextProps.value);
  }

  animateTo = (delay, value) => {
    Animated.sequence([
      Animated.delay(delay),
      Animated.timing(this._width, {
        toValue: value,
      }),
    ]).start();
  }


    render() {
      const barStyles = {
        backgroundColor: this.state.color,
        height: 40,
        width: this._width, // Changed
        borderTopRightRadius: 4,
        borderBottomRightRadius: 4,
      };

      return (
        <Animated.View style={barStyles} />
      );
    }
}


export default class App extends Component {
  constructor(props){
    super(props);


      this.state = {
       data: [],
      };
      this.startAnimation=this.startAnimation.bind(this)
      this.endAnimation=this.endAnimation.bind(this)
      this.generateData=this.generateData.bind(this)
  }


startAnimation(){
  this.interval = setInterval(() => {
      this.generateData();
    }, 1000);
}
endAnimation(){

  clearInterval(this.interval);
}
componentDidMount() {
  this.interval = setInterval(() => {
      this.generateData();
    }, 1000);
}
// generateData = () => {
generateData(){
  const data = [];
  for (let i = 0; i < 10; i++) {
    data.push(Math.floor(Math.random() * window.width));
  }

  this.setState({
    data,
  });
}
  render() {
    // const slideStyle = this.state.example.getTranslateTransform();

    return (
      <View style={[s.container]}>
        <TouchableOpacity onPress={this.startAnimation}
                style={{position:"absolute",top:25,right:10,flex:1,zIndex:3,width:35,height:35,alignItems:"center",justifyContent:"center",backgroundColor:"transparent"}}>
                <Icon name={"circle-outline"} size={25} color="rgba(0,0,0,0.5)"/>
        </TouchableOpacity>
        <TouchableOpacity onPress={this.endAnimation}
                style={{position:"absolute",top:25,left:10,flex:1,zIndex:3,width:35,height:35,alignItems:"center",justifyContent:"center",backgroundColor:"transparent"}}>
                <Icon name={"circle-outline"} size={25} color="red"/>
        </TouchableOpacity>

  {this.state.data.map((value, index) => <AnimatedBar value={value} delay={DELAY * index} key={index} />)}

      </View>
    );
  }
}

const s = StyleSheet.create({
  animatedViewConatiner:{
    // flex:1,
    // position: 'absolute',
    width:100,
    height:100,
    justifyContent:"center",
    alignItems:"center",
    backgroundColor:"rgba(240,0,0,.5)",
  },
  container: {

    flex: 1,
    height,
    width,
    // justifyContent: "center",
    // alignItems: "center",
    backgroundColor: "#F5FCFF",
  },
  text:{
fontWeight:"600",
// fontSize:100,
textAlignVertical: "center", textAlign: "center",},






// container: {
//   flex: 10,
//   flexDirection: 'column'
// },
body: {
  flex: 10,
  backgroundColor: '#ccc'
},
footer_menu: {
  position: 'absolute',
  left:0,right:0,
  width: 600,
  height: 350,
  bottom: -300,
  backgroundColor: '#1fa67a',
  alignItems: 'center',
  // justifyContent:"center",
},
tip_menu: {
  flexDirection: 'row'
},
button: {
  backgroundColor: '#fff'
},
button_label: {
  fontSize: 20,
  fontWeight: 'bold'
}

});

React Native Animation Cheat Sheet: Using the “LayoutAnimation” and “Animated” Components

This is really a way for me to reference this in the future, as I always find my self forgetting parts of this, so hi future self.