reactjs - 使用 React Native 在 Logo 点击上来回旋转动画

标签 reactjs react-native animation react-navigation

我正在尝试为菜单 Logo 设置动画以在单击时旋转。当它向上旋转时,我成功地获得了旋转,但它只是在向下旋转时直接变为 0,而不是通过旋转动画。

这是我的组件:

import React from 'react';
import { TouchableOpacity, Animated } from 'react-native';
import PropTypes from 'prop-types';

import styles from './styles';

const TabIcon = ({
  route,
  renderIcon,
  onPress,
  focused,
  menuToggled,
  activeTintColor,
  inactiveTintColor,
}) => {
  const isMenuLogo = route.params && route.params.navigationDisabled;
  const animation = new Animated.Value(0);

  Animated.timing(animation, {
    toValue: menuToggled ? 1 : 0,
    duration: 200,
    useNativeDriver: true,
  }).start();

  const rotateInterpolate = animation.interpolate({
    inputRange: [0, 1],
    outputRange: ['0deg', '180deg'],
  });
  const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
  const logoStyles = [animatedStyles, styles.logoStyle];

  return (
    <TouchableOpacity
      style={styles.tabStyle}
      onPress={onPress}
      activeOpacity={isMenuLogo && 1}
    >
      <Animated.View style={isMenuLogo ? logoStyles : null}>
        {
          renderIcon({
            route,
            focused,
            tintColor: focused
              ? activeTintColor
              : inactiveTintColor,
          })
        }
      </Animated.View>
    </TouchableOpacity>
  );
};

TabIcon.propTypes = {
  route: PropTypes.shape({
    key: PropTypes.string,
  }).isRequired,
  renderIcon: PropTypes.func.isRequired,
  onPress: PropTypes.func,
  focused: PropTypes.bool,
  menuToggled: PropTypes.bool,
  activeTintColor: PropTypes.string.isRequired,
  inactiveTintColor: PropTypes.string.isRequired,
};

TabIcon.defaultProps = {
  onPress: () => {},
  focused: false,
  menuToggled: false,
};

export default TabIcon;

在实际旋转它之前,我首先检查它是否已被切换。在显示自定义底部选项卡导航的另一个父组件中调用此组件。

当它向下旋转时,我是否应该为它制作不同的动画,或者我是否缺少当前动画中的配置?

我们将不胜感激任何帮助和建议。谢谢。

最佳答案

我认为这个问题与以下事实有关,即当您设置 animation 的初始值时,因为它始终设置为 0 它不会反射(reflect)更改你切换菜单。

你需要改变:

const animation = new Animated.Value(0);

const animation = new Animated.Value(menuToggled ? 0 : 1);

尽管进行该更改会导致不同的问题。因为 menuToggled 会影响动画的开始和结束位置,所以 Icon 现在将从结束位置旋转到正确的开始位置。这并不理想。

不过,我们可以通过为 menuToggled 设置默认值 null 来解决这个问题。然后将动画包装在 if 语句 中,该语句仅在 menuToggled 不为 null 时运行。

这是一个基于您的初始代码的示例:

import React from 'react';
import { View, StyleSheet, Animated, TouchableOpacity } from 'react-native';
import { Ionicons } from '@expo/vector-icons';

const TabIcon = ({
  onPress,
  menuToggled
}) => {
  const logoStyles = [styles.logoStyle];
  if (menuToggled !== null) {
    const animation = new Animated.Value(menuToggled ? 0 : 1);

    Animated.timing(animation, {
      toValue: menuToggled ? 1 : 0,
      duration: 200,
      useNativeDriver: true
    }).start();

    const rotateInterpolate = animation.interpolate({
      inputRange: [0, 1],
      outputRange: ['0deg', '180deg']
    });
    const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
    logoStyles.push(animatedStyles);
  }

  return (
    <TouchableOpacity
      style={styles.tabStyle}
      onPress={onPress}
    >
      <Animated.View style={logoStyles}>
        <Ionicons name="md-checkmark-circle" size={32} color="green" />
      </Animated.View>
    </TouchableOpacity>
  );
};
export default class App extends React.Component {
  state = {
    menuToggled: null
  }

  toggleMenu = () => {
    this.setState(prevState => {
      return { menuToggled: !prevState.menuToggled };
    });
  }

  render () {
    return (
      <View style={styles.container}>
        <TabIcon
          onPress={this.toggleMenu}
          menuToggled={this.state.menuToggled}
        />
      </View>
    );
  }
}

我剥离了您的 TabIcon 组件,因为那里有很多与动画无关的东西。您应该能够轻松地将我所做的合并到您自己的组件中。 https://snack.expo.io/@andypandy/rotating-icon

关于reactjs - 使用 React Native 在 Logo 点击上来回旋转动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54849363/

相关文章:

javascript - 当不同组件使用 axiosinstance 调用 api 时,在哪里添加/删除拦截器

javascript - React Native Touchable 不透明度函数

reactjs - 在 React 中隐藏和显示外部组件

reactjs - 如何在 react 原生 map View 上设置 legend.png 的样式

android - 如何获取 react-native WebView 的文本选择?

javascript - 找不到模块 : Error: Can't resolve './node_modules/react' in '/Users/<user-name>/Documents/gift-test/client'

ios - React native flexbox 无法正确适应

java - 缓冲图像动画代码无法正确重画

python - 为什么我的波函数的简单动画代码不起作用?

javascript - 如何使用javascript使div或对象逐渐移动到鼠标点击点?