likes
comments
collection
share

react native动画竟然能响应式

作者站长头像
站长
· 阅读数 20

这些天在公司发现最常用到较为复杂的效果就是动画,新手刚刚接触react native 的动画会眼前一黑,因为和css的差别很大。我现在主要介绍一种,因为另一个我没学。

Animated

Animated 是 React Native 中用于创建精细交互控制的动画系统。它允许你以声明性的方式描述动画,并提供了丰富的 API 来创建各种动画效果。

怎么来操作呢?我用一个例子来介绍一下。安装依赖包必不可少。

Animated.Value表示驱动动画标量值。通过它创建一个实例对象并附上初始值。当然还有其他方法,后面提。

这里是一个缩放的例子

import { Animated, View, ViewStyle } from 'react-native';
export function Pagination(props: PaginProps) {

  const translateX = new Animated.Value(0.7);

  Animated.timing(translateX, {   //监听动画变量
    toValue: 1,                   //目标值(数字,字符串,对象)
    duration: 500,                //延迟时间
    useNativeDriver: true
  }).start();                    //动画实例上的一个方法,开始执行动画

  return (
    <Animated.View >             //包裹需要添加动画的DOM
        <View
          key={index}
          style={[
              { transform: [{ scale: translateX }] }  //把变量放进来
          ]}
        ></View>
    </Animated.View>
  );
}

你可以用Animated.View包裹一个容器,控制这个容器的动画,也可以将Animated.Text等等作为容器使用。

useNativeDriver

useNativeDriver:为true表示使用原生动画驱动?表示动画的计算和渲染将使用原生平台ios或android的原生动画,不在JavaScript的线程上完成。这样可以提高动画的流畅度和性能,因为原生平台的动画渲染通常比JS线程快。

这里有个问题,为什么原生平台会比JS线程渲染快?我说点重要的。

  1. 减少回流重绘:更好管理回流重绘,减少不必要的渲染。
  2. 并行执行:原生平台的渲染和JS线程并行执行,JS线程在做其他事情时,渲染进程会继续执行。
  3. 动画API:原生平台提供了更高效的动画API。
  4. 硬件加速:原生平台采用硬件加速,动画的计算和渲染在GPU上执行,而不是CPU。

useSharedValue

hooks钩子函数,用于创建一个共享值,可以在组件中传递和共享该值,可以用于动画和其他场景。

它和ref的使用方法比较像,但是功能更加突出

  1. 通过.value访问和修改。
  2. 同样可以实现响应式编程。
  3. 由于组件共享的特性可以实现全局状态管理。

useAnimatedStyle

用于创建一个可动画的样式对象,会返回一个样式对象,它还可以和useSharedValue配合使用,实现响应式和驱动式的动画。

用个例子来展示响应式的动画吧

这里使用渐变色组件LinearGradient演示一个简单的来回扫动的动画。

export const SkeletonLoader = (props: SkeletonLoaderProps) => {
  const position = useSharedValue(0);              //创建响应式变量
  const positionStyle = useAnimatedStyle(() => ({  //样式对象
    transform: [{ translateX: position.value }]
  }));

  const animate = useCallback(() => {
    position.value = withRepeat(
      withTiming(150, { duration: 1000, easing: Easing.linear }),
      -1
    );
  }, []);

  useEffect(() => {
    animate();                                     //启动动画
    return () => {
      position.value = withSpring(0);
    };
  }, [animate]);

  return (
      <Animated.View style={positionStyle}>         //使用样式对象
        <LinearGradient
          style={[{ width: width, height: '100%' }]}
          colors={[
            'rgba(255, 255, 255,0) 40%',
            'rgba(255, 255, 255, 1) 50%',
            'rgba(255, 255, 255, 0) 60%',
          ]}
          start={{ x: 0, y: 1 }}
          end={{ x: 1, y: 0 }}
        ></LinearGradient>
      </Animated.View>
  );
};

创建了一个响应式变量控制样式对象的平移的数值,通过控制position的值做到重复平移。

  • withRepeat:两个必选参数。
    • 动画对象,可以是任何支持重复的动画类型。
    • 重复次数(0,-1都代表无限重复)
  • withTiming:多个可选参数,我简单介绍
    • value:动画静止时的值(接受很多类型:数字,带后缀的数字["5.5%""90deg",后缀和数字不能有空格且是基本英文字母,官方这解释。。。],颜色,对象,数组,变换矩阵)
    • config:定时动画配置。{延迟时间,缓动函数,reduceMotion(减少动画,手机需要开启相关辅助功能)}
  • withSpring:可以用来创建基于弹簧的动画。
    • 返回一个保存动画当前状态的动画对象。它可以直接分配给共享值,也可以用作从useAnimatedStyle返回的样式对象的值。
    • 传递给第三个参数的回调会自动进行工作并在UI 线程上运行:有一个名为 onFrame 的参数,它是一个回调函数,用于在动画的每一帧上执行一些操作。根据官方文档,这个回调函数会自动在 UI 线程上运行,这意味着你可以在回调函数中执行一些与 UI 相关的操作,而不需要担心线程安全问题。

行了,介绍到这,等我用到其他的再写。

转载自:https://juejin.cn/post/7392115478560686107
评论
请登录