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

如何在React Native中实现CSS关键帧旋转渐变动画?

在React Native中实现旋转渐变发光卡片动画

核心效果分析

原CSS动画的核心是:

  • 深色背景卡片,外层有旋转的渐变边框
  • 下层带模糊效果的同渐变层同步旋转
  • 鼠标悬停(或触摸)时,文字显现,渐变层停止旋转并淡出

下面基于你已有的react-native-reanimated和native-base实现该效果,额外需要react-native-linear-gradient处理渐变(若未安装,执行npm install react-native-linear-gradient)。

完整代码实现

import React, { useState, useEffect } from 'react';
import { Pressable } from 'react-native';
import { Box, Text } from 'native-base';
import Animated, { 
  useSharedValue, 
  useAnimatedStyle, 
  withRepeat, 
  withTiming 
} from 'react-native-reanimated';
import LinearGradient from 'react-native-linear-gradient';

const RotatingGradientCard = () => {
  // 定义卡片尺寸,对应原CSS的自定义变量
  const CARD_WIDTH = 300;
  const CARD_HEIGHT = 400;

  // 动画状态值
  const rotateDegree = useSharedValue(0);
  const gradientOpacity = useSharedValue(1);
  const [isActive, setIsActive] = useState(false);

  // 启动/停止旋转动画
  useEffect(() => {
    if (!isActive) {
      // 无限循环旋转,2.5秒一圈
      rotateDegree.value = withRepeat(withTiming(360, { duration: 2500 }), -1, false);
    } else {
      // 停止在当前角度
      rotateDegree.value = withTiming(rotateDegree.value);
    }
  }, [isActive, rotateDegree]);

  // 渐变层透明度动画
  useEffect(() => {
    gradientOpacity.value = withTiming(isActive ? 0 : 1, { duration: 500 });
  }, [isActive, gradientOpacity]);

  // 外层渐变边框(对应CSS的:before)的动画样式
  const animatedBorderStyle = useAnimatedStyle(() => ({
    transform: [{ rotate: `${rotateDegree.value}deg` }],
    opacity: gradientOpacity.value
  }));

  // 下层模糊渐变层(对应CSS的:after)的动画样式
  const animatedBlurStyle = useAnimatedStyle(() => ({
    transform: [{ rotate: `${rotateDegree.value}deg` }, { scale: 0.8 }],
    opacity: gradientOpacity.value,
    // 用阴影模拟模糊效果,若需要更精确可使用@react-native-community/blur
    shadowColor: '#5ddcff',
    shadowOffset: { width: 0, height: 0 },
    shadowOpacity: 0.8,
    shadowRadius: CARD_HEIGHT / 6
  }));

  return (
    <Pressable
      // Web端用hover事件,Native端用触摸事件替代
      onHoverIn={() => setIsActive(true)}
      onHoverOut={() => setIsActive(false)}
      onPressIn={() => setIsActive(true)}
      onPressOut={() => setIsActive(false)}
      style={{ justifyContent: 'center', alignItems: 'center', padding: 20 }}
    >
      <Box
        width={CARD_WIDTH}
        height={CARD_HEIGHT}
        bg="#191c29"
        borderRadius={6}
        justifyContent="center"
        alignItems="center"
        position="relative"
        padding={3}
      >
        {/* 外层旋转渐变边框 */}
        <Animated.View
          style={[
            {
              position: 'absolute',
              top: -CARD_HEIGHT * 0.01,
              left: -CARD_WIDTH * 0.02,
              width: CARD_WIDTH * 1.04,
              height: CARD_HEIGHT * 1.02,
              borderRadius: 8,
              zIndex: -1
            },
            animatedBorderStyle
          ]}
        >
          <LinearGradient
            colors={['#5ddcff', '#3c67e3', '#4e00c2']}
            start={{ x: 0, y: 0 }}
            end={{ x: 1, y: 1 }}
            style={{ flex: 1, borderRadius: 8 }}
          />
        </Animated.View>

        {/* 下层模糊渐变层 */}
        <Animated.View
          style={[
            {
              position: 'absolute',
              top: CARD_HEIGHT / 6,
              left: 0,
              right: 0,
              width: CARD_WIDTH,
              height: CARD_HEIGHT,
              zIndex: -2,
              alignSelf: 'center'
            },
            animatedBlurStyle
          ]}
        >
          <LinearGradient
            colors={['#5ddcff', '#3c67e3', '#4e00c2']}
            start={{ x: 0, y: 0 }}
            end={{ x: 1, y: 1 }}
            style={{ flex: 1, borderRadius: 6 }}
          />
        </Animated.View>

        {/* 卡片文字 */}
        <Text
          fontSize="1.5em"
          color={isActive ? 'rgba(88,199,250,1)' : 'rgba(88,199,250,0)'}
          fontFamily="cursive"
          transition="color 1000ms"
        >
          Hover Me!
        </Text>
      </Box>
    </Pressable>
  );
};

export default RotatingGradientCard;

关键细节说明

  1. 伪元素替代:React Native没有CSS伪元素,用两个绝对定位的Animated.View分别模拟:before和:after的效果。
  2. 旋转动画:通过react-native-reanimated的withRepeat和withTiming实现无限循环旋转,激活时停止在当前角度。
  3. 模糊效果:原CSS的filter: blur用阴影近似模拟,若需要更精确的模糊效果,可安装@react-native-community/blur并替换阴影部分为BlurView。
  4. 跨平台适配:Web端使用onHoverIn/onHoverOut,Native端用onPressIn/onPressOut替代hover交互,保证多平台可用。
  5. 文字过渡:通过native-base的transition属性实现文字颜色的平滑过渡,与原CSS效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:05:17