首页 > 解决方案 > 反应原生动画无法正常工作

问题描述

我正在尝试创建动画标题,其中高度、fontSize 和位置正在更改,同时像 uber 的标题一样滚动

它有效,但不顺畅

当我慢慢滚动时,它摇晃得很快

构造函数:

  constructor(props) {
super(props);
this.state = {
  fontSizeAnimation: new Animated.Value(30),
  positionX: new Animated.Value(0),
  positionY: new Animated.Value(0),
  height: new Animated.Value(0),
  positionAnimation: new Animated.ValueXY(),
  scrollY: 0,
  counter: 0,
}

}

动画功能:

  animateTitle = (e) => {
  const scrollY = e.nativeEvent.contentOffset.y;
  if(scrollY - this.state.scrollY > 5 || scrollY - this.state.scrollY < -5) {
    this.setState({counter: this.state.counter+1})
    this.setState({scrollY});
    Animated.parallel([
      Animated.timing(this.state.height, {
        toValue: this.state.scrollY,
        duration: 0,
        easing: Easing.linear
      }),
      Animated.timing(this.state.fontSizeAnimation, {
        toValue: this.state.scrollY,
        duration: 0,
        easing: Easing.linear
      })
    ]).start(() => {
      this.state.positionAnimation.setValue({
        x: this.state.scrollY > 50? 50 : this.state.scrollY,
        y: this.state.scrollY > 50? -50 : -this.state.scrollY,
      }) 
    })    
  }

}

渲染功能:

  render() {
const interpolatedFontSize = this.state.fontSizeAnimation.interpolate({
  inputRange: [0, 50],
  outputRange: [30, 20],
  extrapolate: "clamp"
});
const interpolatedHeight = this.state.height.interpolate({
  inputRange: [0, 50],
  outputRange: [120, 60],
  extrapolate: "clamp"
});
return (
  <View>
      <Animated.View style={[styles.header, {height: interpolatedHeight}]}>
        <Image source={require("./images/back-button.png")} style={styles.back} />
        <Animated.Text style={[styles.title, { fontSize: interpolatedFontSize, transform: this.state.positionAnimation.getTranslateTransform() }]}>Title</Animated.Text>
      </Animated.View>
      <ScrollView
        onScroll={(e) => this.animateTitle(e)}
        contentContainerStyle={{minHeight: "100%", height: 1000, backgroundColor: "grey"}}
        >
          <View style={{height: 800, backgroundColor: "red", width: "100%", marginBottom: 10}}>
          </View>
      </ScrollView>
  </View>
)

} }

风格:

const styles = StyleSheet.create({

返回:{位置:“绝对”,顶部:20,左侧:10,高度:30,宽度:30},标题:{位置:“绝对”,填充顶部:5,顶部:60,左侧:10},标题: {位置:“相对”,背景颜色:“灰色”,}});

标签: react-native

解决方案


您的动画当前正在 JS 线程上运行。您可以通过以下方式轻松地将动画移动到本机线程:

Animated.timing(this.state.animatedValue, {
  toValue: 1,
  duration: 500,
  useNativeDriver: true, // <-- Adding this line
}).start();

使用本机驱动程序可以提高性能,因为它可以清除 JS 线程以执行其他任务。试试看!


推荐阅读