【翻译】用 Reanimated CSS 动画为 TextInput 添加发光效果

用 Reanimated CSS 动画为 TextInput 添加发光效果

细微的 UI 反馈会让应用更有生命力。给文本输入框增加质感最简单的方法之一,就是在用户开始输入时触发一个发光效果。

借助 Reanimated 的 CSS 动画支持,你可以用很少几行代码做到这一点:不需要 useSharedValue,不需要 useAnimatedStyle,只用 keyframes 和 boxShadow

The Approach

思路很直接:

  1. 定义两个关键帧动画:一个让 boxShadow 渐显,一个让它渐隐。
ts 复制代码
const glowIn: CSSAnimationKeyframes = {
  from: { boxShadow: `0 0 0 0 ${GLOW_COLOR}00` },
  to: { boxShadow: `0 0 32px 4px ${GLOW_COLOR}80` },
};
 
const glowOut: CSSAnimationKeyframes = {
  from: { boxShadow: `0 0 32px 4px ${GLOW_COLOR}59` },
  to: { boxShadow: `0 0 0 0 ${GLOW_COLOR}00` },
};
  1. 根据输入框是否有文本,在两者之间切换。
ts 复制代码
const [text, setText] = useState("");
const hasText = text.length > 0;
 
return (
  <Animated.View
    style={{
      animationName: hasText ? glowIn : glowOut,
    }}
  />
);
  1. Animated.View 包住 TextInput,再通过样式属性以声明式方式应用动画。
ts 复制代码
import { useState } from "react";
import { StyleSheet, TextInput, View } from "react-native";
import Animated, { type CSSAnimationKeyframes } from "react-native-reanimated";
 
const GLOW_COLOR = "#6C63FF";
 
const glowIn: CSSAnimationKeyframes = {
  from: { boxShadow: `0 0 0 0 ${GLOW_COLOR}00` },
  to: { boxShadow: `0 0 32px 4px ${GLOW_COLOR}80` },
};
 
const glowOut: CSSAnimationKeyframes = {
  from: { boxShadow: `0 0 32px 4px ${GLOW_COLOR}59` },
  to: { boxShadow: `0 0 0 0 ${GLOW_COLOR}00` },
};
 
export function GlowInput() {
  const [text, setText] = useState("");
  const hasText = text.length > 0;
 
  return (
    <View style={styles.container}>
      <Animated.View
        style={[
          styles.glow,
          {
            animationName: hasText ? glowIn : glowOut,
            animationDuration: hasText ? "400ms" : "500ms",
            animationFillMode: "forwards",
            animationTimingFunction: "ease-out",
          },
        ]}
      >
        <TextInput
          autoFocus
          value={text}
          onChangeText={setText}
          placeholder="Type something..."
          placeholderTextColor="#999"
          cursorColor={GLOW_COLOR}
          style={styles.input}
        />
      </Animated.View>
    </View>
  );
}
 
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    paddingHorizontal: 24,
  },
  glow: {
    borderRadius: 999,
  },
  input: {
    color: "#fff",
    fontSize: 18,
    fontWeight: "500",
    paddingHorizontal: 20,
    paddingVertical: 16,
    backgroundColor: "#1c1c1e",
    borderRadius: 999,
    borderWidth: 1,
    borderColor: "#333",
  },
});

Tips

  • 替换颜色 :修改 GLOW_COLOR 来匹配你应用的强调色。错误态可以用红色,成功态可以用绿色,按你的场景来定。
  • 调节强度32px 的模糊半径和 4px 的扩散值决定了发光有多"戏剧化"。如果你想更克制一些,就把它们调小。
  • 改为在 focus 时触发 :如果你希望用户点按输入框就发光,而不是输入后才发光,把 hasText 判断改成 onFocus / onBlur 状态即可。

Want to go deeper?

React Native 课程里有一节 Animations and Gestures ,内容包括 Reanimated 辅助函数(withTimingwithSpring 及相关 API)和 React Native Gesture Handler 的手势类型,并配有一个小型示例应用可供参考。

课程:Animations and Gestures

完整课程目录可见 React Native course

如果你希望持续获取实用技巧、实验内容与更新,也可以订阅我的 newsletter

如果你想和我合作,可以通过 beto@codewithbeto.dev 联系我。

相关推荐
李剑一2 小时前
前后端命名冲突?驼峰与下划线的统一方案(附可直接复用代码)
前端
用户11481867894842 小时前
Git Stash 丢失后的完整找回指南
前端·git
代码不加糖2 小时前
2026 React 面试“通关秘籍”:高频 12 问 + 深度解析(含Hooks源码思想)
前端·react.js·面试
我滴老baby2 小时前
ReAct推理模式详解让智能体学会边思考边行动
前端·react.js·前端框架
菜鸟小码2 小时前
MapReduce 核心阶段深度解析:Map 阶段与 Reduce 阶段的作用及执行流程
前端·javascript·mapreduce
步步为营DotNet2 小时前
深入剖析.NET 11 中 Semantic Kernel 于智能后端集成的创新实践
前端·.net·easyui
@大迁世界2 小时前
33.如何在 React 中使用内联样式(inline styles)?
前端·javascript·react.js·前端框架·ecmascript
CodeSheep2 小时前
DeepSeek的最新招人标准,太讽刺了。
前端·后端·程序员
不法2 小时前
vue 地图路线渲染
前端·vue.js·ubuntu