React中實(shí)現(xiàn)動(dòng)畫的兩種方式及對(duì)比詳解
引言
在現(xiàn)代 Web 開發(fā)中,動(dòng)畫不僅是提升用戶體驗(yàn)的重要手段,更是增強(qiáng)用戶交互、引導(dǎo)用戶行為、提升界面美感的關(guān)鍵因素。React 本身不直接提供動(dòng)畫功能,但通過 CSS 的 transition 和第三方動(dòng)畫庫如 Framer Motion,我們可以輕松實(shí)現(xiàn)豐富的動(dòng)畫效果。
本文將通過兩個(gè)例子,講解一下如何在 React 中使用 CSS transition 和 Framer Motion 實(shí)現(xiàn)動(dòng)畫,并對(duì)比它們的優(yōu)缺點(diǎn),幫助我們?cè)陧?xiàng)目中做出合適的技術(shù)選型。
一、使用 CSS transition 實(shí)現(xiàn)動(dòng)畫
1.1 示例代碼解析
我們先來看一個(gè)簡(jiǎn)單的動(dòng)畫組件,實(shí)現(xiàn)一個(gè)點(diǎn)擊按鈕后展開/收起的盒子效果。
// Box.jsx
import styles from './box.module.styl';
import { useState } from 'react';
const Box = () => {
const [open, setOpen] = useState(false);
return (
<div>
<button onClick={() => setOpen(!open)}>
{open ? 'Close' : 'Open'}
</button>
<div className={`${styles.box} ${open ? styles.open : ''}`}></div>
</div>
);
};
export default Box;
對(duì)應(yīng)的 box.module.styl 文件(使用 Stylus):
.box
width: 100px
height: 0
background-color: lightblue
transition: height 0.3s ease
overflow: hidden
.box.open
height: 100px
動(dòng)畫展示:

1.2 工作原理
.box初始高度為0。- 當(dāng)點(diǎn)擊按鈕時(shí),
open狀態(tài)改變,組件的類名變?yōu)?.box.open。 .box.open的高度變?yōu)?100px,通過transition屬性,高度變化會(huì)以 0.3 秒的動(dòng)畫形式完成。
1.3 優(yōu)點(diǎn)與限制
| 特性 | 說明 |
|---|---|
| 簡(jiǎn)單易用 | 適用于簡(jiǎn)單的屬性變化動(dòng)畫,如顏色、大小、位置等 |
| 性能良好 | 瀏覽器對(duì) CSS 動(dòng)畫進(jìn)行了優(yōu)化 |
| 無需依賴 | 不需要引入額外庫 |
| 控制力弱 | 難以實(shí)現(xiàn)復(fù)雜動(dòng)畫邏輯 |
| 狀態(tài)管理繁瑣 | 需要手動(dòng)管理類名和狀態(tài)切換 |
二、使用 Framer Motion 實(shí)現(xiàn)動(dòng)畫
2.1 安裝 Framer Motion
在使用 Framer Motion 之前,需要先安裝它。小編使用的是pnpm,可以使用以下命令安裝:
pnpm install framer-motion
安裝完成后,我們就可以在 React 組件中導(dǎo)入 motion 組件并開始使用它了。
2.2 示例代碼解析
下面是一個(gè)使用 Framer Motion 實(shí)現(xiàn)的動(dòng)畫組件,展示點(diǎn)擊按鈕后內(nèi)容從上方向下淡入的動(dòng)畫效果:
// MotionBox.jsx
import { motion } from 'framer-motion'
import { useState } from 'react'
const MotionBox = () => {
const [isOpen, setIsOpen] = useState(false)
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? '隱藏內(nèi)容' : '顯示內(nèi)容'}
</button>
<motion.div
initial={{ opacity: 0, y: -50 }}
animate={{ opacity: isOpen ? 1 : 0, y: isOpen ? 0 : -50 }}
transition={{ duration: 0.5 }}
style={{
backgroundColor: 'skyblue',
padding: 20,
marginTop: 10,
pointerEvents: 'none' // 防止動(dòng)畫區(qū)域被誤點(diǎn)
}}
>
<h2>Motion Box</h2>
<p>這是一個(gè)使用 Framer Motion 的動(dòng)畫組件</p>
</motion.div>
</div>
)
}
export default MotionBox
動(dòng)畫展示

2.3 工作原理
initial: 定義組件初始狀態(tài),如透明度為 0,垂直方向向上偏移 50px。animate: 根據(jù)isOpen狀態(tài)變化定義動(dòng)畫的目標(biāo)狀態(tài)。當(dāng)isOpen為true時(shí),組件顯示為不透明并回到原位置;為false時(shí)則隱藏。transition: 定義動(dòng)畫過渡的持續(xù)時(shí)間(0.5 秒)和緩動(dòng)函數(shù)(默認(rèn)ease),控制動(dòng)畫播放的節(jié)奏。motion.div: 是 Framer Motion 提供的動(dòng)畫化組件,自動(dòng)處理從初始狀態(tài)到目標(biāo)狀態(tài)的插值與渲染過程。
2.4 優(yōu)點(diǎn)與限制
| 特性 | 說明 |
|---|---|
| 動(dòng)畫控制能力強(qiáng) | 支持延遲、循環(huán)、組合動(dòng)畫等高級(jí)動(dòng)畫邏輯 |
| 內(nèi)置手勢(shì)支持 | 支持拖拽、點(diǎn)擊、懸停等交互事件 |
| 性能優(yōu)化良好 | 基于 requestAnimationFrame,支持硬件加速 |
| 豐富的 API | 支持 TypeScript、React Hooks,生態(tài)完善 |
| 引入依賴 | 需要引入第三方庫,增加項(xiàng)目體積 |
| 學(xué)習(xí)成本略高 | 需要一定時(shí)間學(xué)習(xí)其 API 和動(dòng)畫控制方式 |
三、CSS Transition 與 Framer Motion 對(duì)比總結(jié)
| 特性 | CSS Transition | Framer Motion |
|---|---|---|
| 動(dòng)畫類型 | 屬性變化動(dòng)畫 | 支持路徑、物理模擬、組合動(dòng)畫 |
| 控制能力 | 依賴類名和狀態(tài)切換 | 支持編程控制(暫停、重放、中斷) |
| 性能表現(xiàn) | 一般良好 | 優(yōu)化良好,支持硬件加速 |
| 學(xué)習(xí)成本 | 低 | 中等 |
| 適用場(chǎng)景 | 簡(jiǎn)單 UI 狀態(tài)變化 | 復(fù)雜交互動(dòng)畫、動(dòng)效設(shè)計(jì) |
| 依賴 | 無 | 第三方庫 |
四、使用選擇建議
- 簡(jiǎn)單 UI 動(dòng)畫(如按鈕懸停、菜單展開):使用 CSS
transition,輕量且易于實(shí)現(xiàn)。 - 復(fù)雜交互動(dòng)畫(如模態(tài)框、頁面切換、拖拽效果):使用 Framer Motion,其強(qiáng)大的控制能力和豐富的 API 能滿足大多數(shù)復(fù)雜動(dòng)畫需求。
- 混合使用:可以在項(xiàng)目中同時(shí)使用兩者,CSS 負(fù)責(zé)基礎(chǔ)動(dòng)畫,F(xiàn)ramer Motion 負(fù)責(zé)高級(jí)動(dòng)效。
到此這篇關(guān)于React中實(shí)現(xiàn)動(dòng)畫的兩種方式及對(duì)比詳解的文章就介紹到這了,更多相關(guān)React實(shí)現(xiàn)動(dòng)畫方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解webpack2+node+react+babel實(shí)現(xiàn)熱加載(hmr)
這篇文章主要介紹了詳解webpack2+node+react+babel實(shí)現(xiàn)熱加載(hmr) ,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-08-08
React項(xiàng)目配置prettier和eslint的方法
這篇文章主要介紹了React項(xiàng)目配置prettier和eslint的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
react最流行的生態(tài)替代antdpro搭建輕量級(jí)后臺(tái)管理
這篇文章主要為大家介紹了react最流行的生態(tài)替代antdpro搭建輕量級(jí)后臺(tái)管理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
React+TS+IntersectionObserver實(shí)現(xiàn)視頻懶加載和自動(dòng)播放功能
通過本文的介紹,我們學(xué)習(xí)了如何使用 React + TypeScript 和 IntersectionObserver API 來實(shí)現(xiàn)一個(gè)視頻播放控制組件,該組件具有懶加載功能,只有在用戶滾動(dòng)頁面且視頻進(jìn)入視口時(shí)才開始下載視頻資源,需要的朋友可以參考下2023-04-04

