You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native如何实现类似CSS加载效果的动画边框?

React Native实现类似的边框加载动画

当然可以在React Native中实现你要的这种边框流动加载动画,下面提供两种实用的实现方案:

方案一:使用React Native内置Animated API实现

这种方案无需额外依赖,用原生提供的动画API就能完成:

import React, { useEffect, useRef } from 'react';
import { View, Animated, StyleSheet } from 'react-native';

const BorderLoading = () => {
  const animValue = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    // 启动无限循环动画
    Animated.loop(
      Animated.sequence([
        Animated.timing(animValue, {
          toValue: 1,
          duration: 1500,
          useNativeDriver: false,
        }),
        Animated.timing(animValue, {
          toValue: 0,
          duration: 1500,
          useNativeDriver: false,
        }),
      ])
    ).start();
  }, [animValue]);

  // 为四个边框段计算动画插值
  const topScale = animValue.interpolate({
    inputRange: [0, 0.5, 1],
    outputRange: [0, 1, 0],
  });
  const rightScale = animValue.interpolate({
    inputRange: [0, 0.5, 1],
    outputRange: [0, 0, 1],
  });
  const bottomScale = animValue.interpolate({
    inputRange: [0, 0.5, 1],
    outputRange: [1, 0, 0],
  });
  const leftScale = animValue.interpolate({
    inputRange: [0, 0.5, 1],
    outputRange: [0, 1, 0],
  });

  return (
    <View style={styles.container}>
      {/* 上边边框 */}
      <Animated.View style={[styles.topBorder, { transform: [{ scaleX: topScale }] }]} />
      {/* 右边边框 */}
      <Animated.View style={[styles.rightBorder, { transform: [{ scaleY: rightScale }] }]} />
      {/* 下边边框 */}
      <Animated.View style={[styles.bottomBorder, { transform: [{ scaleX: bottomScale }] }]} />
      {/* 左边边框 */}
      <Animated.View style={[styles.leftBorder, { transform: [{ scaleY: leftScale }] }]} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    width: 100,
    height: 100,
    position: 'relative',
  },
  topBorder: {
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: 3,
    backgroundColor: '#165DFF',
    transformOrigin: 'left center',
  },
  rightBorder: {
    position: 'absolute',
    top: 0,
    right: 0,
    width: 3,
    height: '100%',
    backgroundColor: '#165DFF',
    transformOrigin: 'center top',
  },
  bottomBorder: {
    position: 'absolute',
    bottom: 0,
    left: 0,
    width: '100%',
    height: 3,
    backgroundColor: '#165DFF',
    transformOrigin: 'right center',
  },
  leftBorder: {
    position: 'absolute',
    top: 0,
    left: 0,
    width: 3,
    height: '100%',
    backgroundColor: '#165DFF',
    transformOrigin: 'center bottom',
  },
});

export default BorderLoading;

方案二:使用react-native-reanimated实现更流畅的原生动画

如果需要更好的性能(尤其是在低配置设备上),可以用react-native-reanimated库,它支持原生驱动动画,流畅度更高:

第一步:安装依赖

npm install react-native-reanimated
# 或者用yarn
yarn add react-native-reanimated

(RN 0.60+版本会自动完成链接,低版本需要手动配置)

第二步:实现代码

import React, { useEffect } from 'react';
import { View, StyleSheet } from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withRepeat,
  withSequence,
  withTiming,
} from 'react-native-reanimated';

const BorderLoadingReanimated = () => {
  const animProgress = useSharedValue(0);

  useEffect(() => {
    // 启动无限循环的时序动画
    animProgress.value = withRepeat(
      withSequence(
        withTiming(1, { duration: 1500 }),
        withTiming(0, { duration: 1500 }),
      ),
      -1 // -1表示无限循环
    );
  }, []);

  // 为每个边框段创建动画样式
  const topStyle = useAnimatedStyle(() => {
    return {
      transform: [{ scaleX: animProgress.value.interpolate({
        inputRange: [0, 0.5, 1],
        outputRange: [0, 1, 0],
      }) }],
    };
  });

  const rightStyle = useAnimatedStyle(() => {
    return {
      transform: [{ scaleY: animProgress.value.interpolate({
        inputRange: [0, 0.5, 1],
        outputRange: [0, 0, 1],
      }) }],
    };
  });

  const bottomStyle = useAnimatedStyle(() => {
    return {
      transform: [{ scaleX: animProgress.value.interpolate({
        inputRange: [0, 0.5, 1],
        outputRange: [1, 0, 0],
      }) }],
    };
  });

  const leftStyle = useAnimatedStyle(() => {
    return {
      transform: [{ scaleY: animProgress.value.interpolate({
        inputRange: [0, 0.5, 1],
        outputRange: [0, 1, 0],
      }) }],
    };
  });

  return (
    <View style={styles.container}>
      <Animated.View style={[styles.topBorder, topStyle]} />
      <Animated.View style={[styles.rightBorder, rightStyle]} />
      <Animated.View style={[styles.bottomBorder, bottomStyle]} />
      <Animated.View style={[styles.leftBorder, leftStyle]} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    width: 100,
    height: 100,
    position: 'relative',
  },
  topBorder: {
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: 3,
    backgroundColor: '#165DFF',
    transformOrigin: 'left center',
  },
  rightBorder: {
    position: 'absolute',
    top: 0,
    right: 0,
    width: 3,
    height: '100%',
    backgroundColor: '#165DFF',
    transformOrigin: 'center top',
  },
  bottomBorder: {
    position: 'absolute',
    bottom: 0,
    left: 0,
    width: '100%',
    height: 3,
    backgroundColor: '#165DFF',
    transformOrigin: 'right center',
  },
  leftBorder: {
    position: 'absolute',
    top: 0,
    left: 0,
    width: 3,
    height: '100%',
    backgroundColor: '#165DFF',
    transformOrigin: 'center bottom',
  },
});

export default BorderLoadingReanimated;

自定义调整

你可以根据需求修改以下参数:

  • 边框颜色:修改backgroundColor值
  • 边框宽度:调整height(上下边)或width(左右边)
  • 动画速度:修改duration值
  • 容器大小:调整container的width和height

内容的提问来源于stack exchange,提问作者Bi0max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 14:03:15