文档
文档
useAnimations 是一个免费的动态图标库,采用 MIT 许可证,为 React 提供 300 个动态图标。每个图标都内置一种交互:循环播放、点击播放或悬停播放。您可以通过 react-useanimations 软件包使用它们,也可以用 shadcn CLI 添加到项目中。
快速上手
npm install react-useanimations
import UseAnimations from 'react-useanimations';
import github from 'react-useanimations/lib/github';
export default function Header() {
return <UseAnimations animation={github} size={32} />;
}
图标会跟随文字颜色,并播放自己的交互:github 在悬停期间循环播放。这个软件包没有任何依赖,由内置播放器(gzip 压缩后 8 kB)把图标绘制成 SVG;每个图标都是独立模块,因此打包结果只包含您导入的图标。
交互方式
每个图标都自带为它设计的交互,可以用 interaction 属性覆盖。
| 交互方式 | 效果 | 示例图标 |
|---|---|---|
loop |
持续播放。 | loading, activity, alertCircle |
click-toggle |
点击时在两种状态之间切换(先正向,再反向)。 | menu, checkBox, playPause |
click-replay |
每次点击都从头播放。 | download, refresh, send |
hover |
指针移入时正向播放,移出时反向播放。 | archive, settings, trash |
hover-loop |
悬停期间循环播放,移出后播完当前一轮。 | github, twitter, dribbble |
hover-replay |
指针移入时从头播放一次。 | arrowRight, bluetooth, zap |
当用户偏好减少动态效果时,图标会保持静止:循环图标显示第一帧,悬停和重播动画不会播放,切换类图标会直接切换到新状态。
属性
<UseAnimations animation={github} size={56} strokeColor="#4b5cff" style={{ padding: 8 }} />
| 属性 | 默认值 | 说明 |
|---|---|---|
animation |
— | 从 react-useanimations/lib/<name> 导入的图标;使用自己的动画时传入 { animationData, interaction }。 |
size |
24 |
宽度和高度;数字表示像素,字符串可以是任意 CSS 长度,例如 '1.5em'。 |
strokeColor |
'currentColor' |
线条颜色。默认跟随文字颜色。 |
fillColor |
strokeColor |
填充部分的颜色,例如点赞后的爱心。 |
interaction |
因图标而异 | 'loop'、'click-toggle'、'click-replay'、'hover'、'hover-loop' 或 'hover-replay'。 |
active |
— | 用于 click-toggle 图标:true 显示结束状态。受控模式:在 onClick 中设置它,点击本身不会切换图标。 |
autoplay |
因图标而异 | loop 图标默认为 true,除非用户偏好减少动态效果。 |
loop |
因图标而异 | loop 和 hover-loop 图标默认为 true。 |
speed |
1 |
播放速度。 |
render |
— | 用于自定义外层元素的 render 属性,参见把图标放进真正的按钮。 |
其他属性(className、aria-label、onClick 等)都会传给外层的 <span>。您的事件处理函数会先于动画执行;调用 event.preventDefault() 即可跳过动画。
导入图标
可以从 react-useanimations/lib/<name> 逐个导入图标,也可以从 react-useanimations/icons 一次导入多个:
import { github, heart, menu } from 'react-useanimations/icons';
无论哪种方式,生产构建都只包含您用到的图标。开发服务器和测试运行器不做 tree-shaking,所以在这些环境中 react-useanimations/icons 会加载全部图标;如果这一点对您很重要,请优先使用 lib/<name>。delete 和 package 是保留字,请分别以 deleteIcon 和 packageIcon 导入。
受控切换
import { useState } from 'react';
import UseAnimations from 'react-useanimations';
import menu from 'react-useanimations/lib/menu';
export function MenuButton() {
const [open, setOpen] = useState(false);
return (
<UseAnimations
animation={menu}
size={40}
active={open} // `open` 在别处改变时同样会播放动画
onClick={() => setOpen(!open)}
/>
);
}
把图标放进真正的按钮
对于可点击的图标,请用 render 属性在图标外面包一层可聚焦的元素:eventProps 放在您的元素上,animationProps 放在其内部的 <span> 上。这样按钮获得键盘焦点时,悬停动画也会播放。
import heart from 'react-useanimations/lib/heart';
<UseAnimations
animation={heart}
size={32}
render={(eventProps, animationProps) => (
<button type="button" aria-label="Add to favorites" {...eventProps}>
<span {...animationProps} />
</button>
)}
/>;
尺寸与颜色
这些图标都是线性图标,绘制在 24 或 32 px 的画板上,任何尺寸下都保持清晰:把 size 设为像素数或任意 CSS 长度即可。
线条使用 currentColor,因此图标会自动继承文字颜色、悬停状态和深色模式。可以通过 strokeColor 和 fillColor、CSS color 修改颜色,也可以直接给路径设置样式:内置规则的优先级(specificity)为零,所以您的 CSS 总能生效。
有些图标在自身上留出了镂空(visibility、microphone、video、volume 和 notification 中的斜线,download 中的对勾,notification3 徽标周围的圆环)。镂空部分取页面背景色:浅色页面上为白色,设置了 color-scheme: dark 的页面上为深色。在其他背景上,请用 CSS 变量 --ua-knockout 指定,例如 body { --ua-knockout: #0f172a; }。
// Tailwind:颜色和线条粗细
<UseAnimations animation={github} className="text-indigo-500 [&_path]:stroke-[3]" />
Next.js 与服务端渲染
组件标记为 'use client',只在浏览器中绘制动画,因此可以在服务端组件和 SSR 框架(Next.js、Remix、Astro)中直接渲染,无需 dynamic(…, { ssr: false })。图标模块是普通数据,服务端组件可以直接导入并作为属性传递。
shadcn/ui
每个图标也都收录在 shadcn 注册表中。CLI 会添加一个现成的组件,并安装 react-useanimations:
npx shadcn@latest add https://useanimations.com/r/checkmark.json
import { AnimatedCheckmark } from '@/components/animations/checkmark';
<AnimatedCheckmark size={24} />;
组件名为 Animated 加上 PascalCase 形式的图标 id(check-box → AnimatedCheckBox),文件位于 components/animations/<id>.tsx,接受与 UseAnimations 相同的属性。注册表索引位于 /r/registry.json。如果想使用 npx shadcn@latest add @useanimations/checkmark 这种简短写法,请把注册表添加到 components.json:
{
"registries": {
"@useanimations": "https://useanimations.com/r/{name}.json"
}
}
使用自己的动画
import animationData from './my-animation.json';
<UseAnimations animation={{ animationData, interaction: 'hover' }} />;
您的动画必须是 Lottie JSON 文件,也就是这些图标所用的格式。播放器支持图标所需的功能:形状图层、预合成、空对象图层与父子关系、路径、矩形、椭圆、描边、填充、修剪路径、蒙版、带缓动的关键帧、定格关键帧和运动路径,以及 loopOut() 和 wiggle() 表达式。其他内容(例如渐变、文本或图片图层、效果和遮罩)不会被绘制;对于不支持的图层、形状和表达式,控制台会给出警告。
文件与 icons.json
每个图标都可以下载,既可以在图标页面下载,也可以通过固定且支持 CORS 的网址获取:
| 文件 | 网址 |
|---|---|
| 动画(Lottie JSON) | https://useanimations.com/icons/<id>.json |
| 每个状态的静态 SVG | https://useanimations.com/icons/<id>/<state>.svg |
| 包含 JSON 和 SVG 的 ZIP | https://useanimations.com/icons/<id>.zip |
| 图标页面 | https://useanimations.com/icons/<id> |
| 全部图标的目录 | https://useanimations.com/icons.json |
icons.json 列出了每个图标的 id、标题、类别、搜索关键词、交互方式、文件网址、尺寸和时长,以及对应的 react-useanimations 导入语句和 shadcn 命令。npm 软件包中也附带相同的数据:react-useanimations/catalog.json(元数据)、react-useanimations/icons(动画)和 react-useanimations/svg.json(静态 SVG)。
不使用 React
这些图标都是标准的 Lottie JSON,任何 Lottie 播放器都能从 https://useanimations.com/icons/<id>.json 或项目中的副本播放它们。在 React 之外,交互需要您自己实现。更多播放器和示例请参阅 Lottie 图标。
有些图标用到了 After Effects 表达式(loopOut()、wiggle()),icons.json 中用 requiresFullPlayer 标出了它们。在网页上,它们需要 lottie-web 的完整版,而不是 lottie_light;原生播放器则不会执行表达式。
HTML 与 JavaScript
<div id="icon" style="width: 48px; height: 48px"></div>
<script src="https://cdn.jsdelivr.net/npm/lottie-web@5.13.0/build/player/lottie.min.js"></script>
<script>
const el = document.getElementById('icon');
const animation = lottie.loadAnimation({
container: el,
renderer: 'svg',
loop: false,
autoplay: false,
path: 'https://useanimations.com/icons/archive.json',
});
// hover:移入时正向播放,移出时反向播放
el.addEventListener('mouseenter', () => {
animation.setDirection(1);
animation.play();
});
el.addEventListener('mouseleave', () => {
animation.setDirection(-1);
animation.play();
});
</script>
使用 SVG 渲染器时,图标也可以像 React 组件那样跟随文字颜色:
#icon path[stroke^='rgb']:not([stroke='rgb(255,255,255)']) {
stroke: currentColor;
}
#icon path[fill='rgb(0,0,0)'] {
fill: currentColor;
}
Vue
<script setup>
import lottie from 'lottie-web';
import { onBeforeUnmount, onMounted, ref } from 'vue';
const el = ref(null);
let animation;
onMounted(() => {
animation = lottie.loadAnimation({
container: el.value,
renderer: 'svg',
loop: true,
autoplay: true,
path: 'https://useanimations.com/icons/loading.json',
});
});
onBeforeUnmount(() => animation?.destroy());
</script>
<template>
<div ref="el" style="width: 48px; height: 48px" />
</template>
React Native
import LottieView from 'lottie-react-native';
<LottieView source={require('./loading.json')} autoPlay loop style={{ width: 48, height: 48 }} />;
iOS
使用 lottie-ios,并把 JSON 放进应用包:
import Lottie
import SwiftUI
LottieView(animation: .named("loading"))
.looping()
.frame(width: 48, height: 48)
Android
在 Jetpack Compose 中使用 lottie-android,并把 JSON 放在 res/raw 中:
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.loading))
LottieAnimation(composition, iterations = LottieConstants.IterateForever, modifier = Modifier.size(48.dp))
Flutter
使用 lottie 包:
Lottie.asset('assets/loading.json', width: 48, height: 48)
性能与无障碍
- 小巧:播放器 gzip 压缩后为 8 kB,没有任何依赖;单个图标为 1 到 15 kB(中位数 2 kB)。
- 延迟绘制:动画只在浏览器中、页面渲染完成后才绘制;自动播放的循环动画在滚出视口时会暂停,组件卸载时会清理所有资源。
- 默认仅作装饰:图标对屏幕阅读器隐藏(
aria-hidden),除非您传入aria-label,此时它会被当作图片读出。对于只有图标的控件,请使用带aria-label的真正<button>(见上文),并用aria-pressed或aria-expanded反映切换状态。 - 减少动态效果与触屏:图标遵循
prefers-reduced-motion,在触摸屏上轻触不会触发悬停动画。
AI 编程智能体
智能体可以从 icons.json 或软件包内的 react-useanimations/catalog.json 中按关键词或交互方式挑选图标,并使用其中列出的导入语句或 shadcn 命令。每个图标导入的类型定义里也带有它的标题、关键词、交互方式和预览。本文档提供 Markdown 版本,位于 /documentation.md;/llms.txt 则是整个站点的索引。
从 v2 升级
对大多数应用来说,升级就是安装 v3:组件本身、react-useanimations/lib/<name> 形式的导入以及 v2 的全部 79 个图标都保持不变。请按下面的步骤逐一检查适用于您代码的部分。
1. 安装 v3
v3 需要 React 18 或更高版本,并且没有任何依赖。如果应用中没有其他地方用到 lottie-web,也请一并移除。
npm install react-useanimations@3
npm uninstall lottie-web
2. 用 active 替换 reverse
active 是完全受控的:active 变化时图标播放动画,单独点击不会切换图标,因此请在 onClick 中更新它。reverse 仍然和 v2 中一样可用(它设置初始状态,点击会切换图标),但已被弃用。两者都只对 click-toggle 图标生效:四个圆形箭头图标现在改为点击重播(见第 6 步)。
- <UseAnimations animation={checkBox} reverse={checked} onClick={toggle} />
+ <UseAnimations animation={checkBox} active={checked} onClick={toggle} />
3. 检查颜色
在 v2 中,除非设置了 strokeColor,图标都是黑色的。v3 的图标跟随文字颜色(currentColor),并且 fillColor 默认等于 strokeColor。位于彩色文字或链接中的图标会随之变色;如果想保持黑色,请自己设置颜色:
<UseAnimations animation={github} strokeColor="#000" />
4. 迁移 wrapperStyle、pathCss 和 options
wrapperStyle已弃用:请改用style。pathCss已移除:请通过类名给路径设置样式。options(lottie-web 的设置)已随 lottie-web 一起移除。请使用loop、autoplay和speed属性;lottie-web 的其他选项没有对应的替代。
如果仍然传入 pathCss 或 options,会输出一次警告,然后被忽略。
- <UseAnimations animation={github} wrapperStyle={{ margin: 8 }} pathCss="stroke-width: 3px;" options={{ loop: true }} />
+ <UseAnimations animation={github} style={{ margin: 8 }} className="thick" loop />
.thick path {
stroke-width: 3px;
}
5. 检查外层元素
外层元素现在是 inline-block 的 <span>,而不是 <div>,因此可以合法地放在按钮和链接中,并与文字处于同一行。请更新把外层元素当作 div 来选择的 CSS,并在 render 属性中把 animationProps 展开到 <span> 上:
render={(eventProps, animationProps) => (
<button type="button" aria-label="Like" {...eventProps}>
- <div {...animationProps} />
+ <span {...animationProps} />
</button>
)}
图标现在默认对屏幕阅读器隐藏(aria-hidden),除非您传入 aria-label;对于本身就承载含义的图标,请为它加上标签。
6. 检查交互方式有变化的图标
交互方式现在与 useanimations.com 保持一致。如果希望某个图标保持 v2 中的行为,请传入它原来的交互方式:
| 图标 | v2 | v3 |
|---|---|---|
arrowDownCircle, arrowLeftCircle, arrowRightCircle, arrowUpCircle |
click-toggle |
click-replay |
calendar, folder, home, instagram, userMinus, userPlus, userX, youtube, youtube2 |
hover-replay* |
hover |
behance, codepen, facebook, github, linkedin, pocket, twitter |
hover-replay* |
hover-loop |
copy, edit, mail |
click-replay |
hover |
dribbble |
hover |
hover-loop |
zoomIn, zoomOut |
loop |
hover |
* v2 中这些图标在指针移入时播放一次,移出时跳回起点;hover-replay 是最接近的效果。
<UseAnimations animation={zoomIn} interaction="loop" />
7. 更新导入
只能以 react-useanimations/lib/<name> 的形式或从 react-useanimations/icons 导入图标。v2 的内部文件路径,例如 react-useanimations/lib/github/index 或 react-useanimations/lib/github/github.json,已无法解析;Lottie JSON 现在是图标的 animationData:
- import githubJson from 'react-useanimations/lib/github/github.json';
+ import github from 'react-useanimations/lib/github';
+ const githubJson = github.animationData;
react-useanimations/utils 路径已被移除。请直接从软件包导入类型:
- import type { Animation, AnimationKey } from 'react-useanimations/utils';
+ import type { Animation, AnimationKey, Interaction, UseAnimationsProps } from 'react-useanimations';
Animation 现在是 { animationData, interaction };v2 的 animationKey 字段已不存在,因此您自己构造的对象请改用 interaction。
其他新特性
新增 221 个图标(共 300 个)、可从 react-useanimations/icons 一次导入多个图标、支持减少动态效果、键盘聚焦时播放悬停动画、触摸屏上不再出现卡住的悬停动画、无需变通方案即可服务端渲染,以及 shadcn 注册表。
许可证
图标和代码均以 MIT 许可证发布:可以在个人和商业作品中使用、修改和再分发。署名不是必需的,但我们很欢迎:
Animated icons by <a href="https://useanimations.com">useAnimations</a>
完整条款:许可与条款。
常见问题
useAnimations 可以免费用于商业项目吗?
可以。图标和软件包都采用 MIT 许可证,无需署名。
如何修改图标的颜色?
图标默认跟随文字颜色。可以通过 strokeColor 和 fillColor、CSS color,或者直接给路径设置样式来修改。参见尺寸与颜色。
不使用 React 也能用吗?
这个软件包是为 React 设计的。不过每个图标同时也是 Lottie JSON 文件,lottie-web、lottie-ios、lottie-android、Flutter 和 React Native 都能播放,另外还提供静态 SVG。参见不使用 React 和 Lottie 图标。
AI 编程智能体可以使用 useAnimations 吗?
可以。让它们读取 icons.json 和 /documentation.md 即可;软件包本身也附带 catalog.json,并为每个图标提供了带文档注释的类型定义。