Gyroscope interpolation for rotation animations

#1

Hey,

I’m interested in rotating a view by interpolating the gyroscope. I’ve tried doing so with the following code:

import React, { Component } from 'react';
import { ScrollView, View, Text, Animated } from 'react-native';
import { Gyroscope } from 'expo';

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

    this.state = {
      x: new Animated.Value(0),
      y: new Animated.Value(0)
    };
  }
  componentDidMount() {
    Gyroscope.addListener(({ x, y, z }) => {
      this.setState({ x: new Animated.Value(x), y: new Animated.Value(y) });
    });
    Gyroscope.setUpdateInterval(16);
  }

  render() {
    const { x, y } = this.state;
    const { title, style, children, snapToInterval, sectionPosition } = this.props;

    const rotateY = this.state.x.interpolate({
      inputRange: [-1, 0, 1],
      outputRange: ['-45deg', '0deg', '45deg'],
      extrapolate: 'clamp',
      useNativeDriver: true
    });

    const rotateX = this.state.y.interpolate({
      inputRange: [-1, 0, 1],
      outputRange: ['-45deg', '0deg', '45deg'],
      extrapolate: 'clamp',
      useNativeDriver: true
    });

    return (
      <Animated.View style={{ flex: 1, transform: [{ rotateY }, { rotateX }] }}>
        <Text style={styles.sectionName}>{title}</Text>
        <Animated.ScrollView
          style={[style || null, { transform: [{ translateY: sectionPosition }] }]}
          contentContainerStyle={{ paddingRight: 15 }}
          showsHorizontalScrollIndicator={false}
          snapToInterval={snapToInterval || 365}
          decelerationRate={'fast'}
          horizontal
        >
          {children}
        </Animated.ScrollView>
      </Animated.View>
    );
  }
}

const styles = {
  sectionName: {
    fontFamily: 'syncopate',
    fontSize: 15,
    letterSpacing: 1.65,
    backgroundColor: 'transparent',
    color: '#32383c',
    marginLeft: 17.5,
    marginTop: 12.5
  },
};

Unfortunately, all I get is a view that sporadically rotates whenever I move my device and eventually stops moving all together. Is Expo/React Native capable of such animations or am I going about this the wrong way? Any help would be greatly appreciated!

This is the effect I’m trying to reproduce: https://designmodo.com/apple-tv-effect/

0 Likes

#2

this.setState(...) causes a new React re-render each time. Instead of that you could just .setValue(...) on the existing Animated.Values.

0 Likes