大家好,我是jobleap.cn的小九。
你想要掌握 lottie-react 库的常用用法,并获取一份基于 Next.js 15 的详细实战教程,把该库的核心 API 串联起来完整使用。下面我会从环境搭建到 API 实战,一步步带你掌握 lottie-react 在 Next.js 15 中的全场景用法。

一、前置知识与环境准备

1. 核心依赖说明

lottie-reactlottie-web 的 React 封装库,专门用于在 React 项目中播放 Lottie 动画(AE 导出的 JSON 动画文件)。Next.js 15 采用 App Router 作为默认路由,且组件默认是服务器组件,而 lottie-react 依赖浏览器 DOM,因此必须标记为客户端组件('use client')。

2. 环境搭建步骤

步骤 1:创建 Next.js 15 项目
# 创建 Next.js 15 项目
npx create-next-app@latest lottie-next15-demo
cd lottie-next15-demo

# 安装核心依赖
npm install lottie-react lottie-web
# 或 yarn/pnpm
# yarn add lottie-react lottie-web
# pnpm add lottie-react lottie-web
步骤 2:准备 Lottie 动画文件

LottieFiles 下载一个免费的 Lottie JSON 动画文件(比如 animation.json),放到项目的 public/lottie/ 目录下(需手动创建 lottie 文件夹)。

二、lottie-react 核心 API 详解与 Next.js 15 实战

lottie-react 的核心是 <Lottie /> 组件,下面按「基础渲染 → 播放控制 → 事件监听 → 高级配置」的顺序,串联所有常用 API。

1. 基础渲染(核心 props)

核心 API:animationData/animationPathwidth/heightstyle
  • animationData:直接传入 Lottie JSON 数据(适合导入本地文件)
  • animationPath:传入动画文件的网络/本地路径(适合 public 目录下的文件)
  • width/height:设置动画容器尺寸(支持数字/字符串,如 300'100%'
  • style:自定义容器样式(React 行内样式)
Next.js 15 实战代码(客户端组件)

创建 app/lottie-demo/page.tsx(App Router 路由):

// app/lottie-demo/page.tsx
'use client' // 必须标记为客户端组件
import React from 'react'
import Lottie from 'lottie-react'
// 方式1:导入本地 JSON 文件(需配置 Next.js 支持 JSON 导入,默认已支持)
import animationData from '@/public/lottie/animation.json'

export default function LottieDemo() {
  return (
    <div style={{ padding: '2rem' }}>
      <h2>基础渲染:两种加载方式</h2>
      
      {/* 方式1:使用 animationData(导入本地 JSON) */}
      <div style={{ marginBottom: '2rem' }}>
        <p>animationData 方式</p>
        <Lottie
          animationData={animationData}
          width={300} // 数字表示 px
          height={300}
          style={{ border: '1px solid #eee' }} // 自定义样式
        />
      </div>

      {/* 方式2:使用 animationPath(public 目录路径) */}
      <div>
        <p>animationPath 方式</p>
        <Lottie
          animationPath="/lottie/animation.json" // public 根目录开始
          width="100%" // 响应式宽度
          height={200}
        />
      </div>
    </div>
  )
}

2. 播放控制(核心 props + 实例方法)

核心 API:
  • 基础控制 props:autoplay(自动播放)、loop(循环播放)、speed(播放速度)
  • 实例方法(通过 ref 获取):play()pause()stop()setSpeed()goToAndPlay()goToAndStop()
Next.js 15 实战代码(带控制按钮)

修改 app/lottie-demo/page.tsx,添加播放控制逻辑:

// app/lottie-demo/page.tsx
'use client'
import React, { useRef } from 'react'
import Lottie, { LottieRef } from 'lottie-react'
import animationData from '@/public/lottie/animation.json'

export default function LottieDemo() {
  // 创建 ref 用于获取 Lottie 实例
  const lottieRef = useRef<LottieRef>(null)

  // 控制方法
  const handlePlay = () => lottieRef.current?.play()
  const handlePause = () => lottieRef.current?.pause()
  const handleStop = () => lottieRef.current?.stop()
  const handleSpeedUp = () => lottieRef.current?.setSpeed(2) // 2倍速
  const handleSpeedDown = () => lottieRef.current?.setSpeed(0.5) // 0.5倍速
  const goToFrame10 = () => lottieRef.current?.goToAndPlay(10, true) // 跳转到第10帧并播放
  const stopAtFrame50 = () => lottieRef.current?.goToAndStop(50, true) // 跳转到第50帧并停止

  return (
    <div style={{ padding: '2rem' }}>
      <h2>播放控制:props + 实例方法</h2>
      
      {/* Lottie 动画容器 */}
      <Lottie
        ref={lottieRef}
        animationData={animationData}
        width={300}
        height={300}
        autoplay={false} // 关闭自动播放
        loop={true} // 开启循环(手动播放后生效)
        speed={1} // 初始速度 1
      />

      {/* 控制按钮组 */}
      <div style={{ marginTop: '1rem', gap: '0.5rem', display: 'flex' }}>
        <button onClick={handlePlay} style={btnStyle}>播放</button>
        <button onClick={handlePause} style={btnStyle}>暂停</button>
        <button onClick={handleStop} style={btnStyle}>停止</button>
        <button onClick={handleSpeedUp} style={btnStyle}>2倍速</button>
        <button onClick={handleSpeedDown} style={btnStyle}>0.5倍速</button>
        <button onClick={goToFrame10} style={btnStyle}>跳到第10帧播放</button>
        <button onClick={stopAtFrame50} style={btnStyle}>跳到第50帧停止</button>
      </div>
    </div>
  )
}

// 按钮样式
const btnStyle = {
  padding: '0.5rem 1rem',
  border: 'none',
  borderRadius: '4px',
  backgroundColor: '#0070f3',
  color: 'white',
  cursor: 'pointer',
}

3. 事件监听(核心回调 API)

核心 API:
  • onComplete:动画播放完成(非循环时触发)
  • onLoopComplete:循环播放时,每一轮完成触发
  • onEnterFrame:每一帧播放时触发
  • onSegmentStart:指定片段播放开始时触发
  • onPlay/onPause/onStop:播放/暂停/停止时触发
Next.js 15 实战代码(添加事件监听)

继续修改 app/lottie-demo/page.tsx,添加事件监听:

// app/lottie-demo/page.tsx
'use client'
import React, { useRef, useState } from 'react'
import Lottie, { LottieRef } from 'lottie-react'
import animationData from '@/public/lottie/animation.json'

export default function LottieDemo() {
  const lottieRef = useRef<LottieRef>(null)
  const [log, setLog] = useState<string[]>([]) // 存储事件日志

  // 事件回调:添加日志
  const addLog = (msg: string) => {
    setLog(prev => [...prev, `${new Date().toLocaleTimeString()}: ${msg}`])
    // 只保留最新10条日志
    if (log.length > 10) setLog(prev => prev.slice(-10))
  }

  return (
    <div style={{ padding: '2rem', display: 'flex', gap: '2rem' }}>
      <div>
        <h2>事件监听:捕获动画状态</h2>
        <Lottie
          ref={lottieRef}
          animationData={animationData}
          width={300}
          height={300}
          autoplay={true}
          loop={true}
          speed={1}
          // 事件回调
          onComplete={() => addLog('动画播放完成(非循环)')}
          onLoopComplete={() => addLog('一轮循环播放完成')}
          onEnterFrame={(frame) => {
            // 避免日志刷屏,每10帧记录一次
            if (frame.currentFrame % 10 === 0) {
              addLog(`当前帧:${frame.currentFrame}`)
            }
          }}
          onPlay={() => addLog('动画开始播放')}
          onPause={() => addLog('动画暂停')}
          onStop={() => addLog('动画停止')}
        />

        {/* 控制按钮 */}
        <div style={{ marginTop: '1rem', gap: '0.5rem', display: 'flex' }}>
          <button onClick={() => lottieRef.current?.play()} style={btnStyle}>播放</button>
          <button onClick={() => lottieRef.current?.pause()} style={btnStyle}>暂停</button>
          <button onClick={() => lottieRef.current?.stop()} style={btnStyle}>停止</button>
        </div>
      </div>

      {/* 事件日志面板 */}
      <div style={{ flex: 1, border: '1px solid #eee', padding: '1rem', height: '300px', overflow: 'auto' }}>
        <h3>事件日志</h3>
        <ul style={{ listStyle: 'none', padding: 0 }}>
          {log.map((item, index) => (
            <li key={index} style={{ color: '#666', fontSize: '0.9rem' }}>{item}</li>
          ))}
        </ul>
      </div>
    </div>
  )
}

const btnStyle = {
  padding: '0.5rem 1rem',
  border: 'none',
  borderRadius: '4px',
  backgroundColor: '#0070f3',
  color: 'white',
  cursor: 'pointer',
}

4. 高级配置(initialSegment、rendererSettings)

核心 API:
  • initialSegment:指定动画播放的帧范围(如 [10, 50] 表示只播放第10到50帧)
  • rendererSettings:自定义渲染配置(如抗锯齿、背景透明等)
Next.js 15 实战代码(高级配置)
// app/lottie-demo/advanced.tsx(可新建页面)
'use client'
import React from 'react'
import Lottie from 'lottie-react'
import animationData from '@/public/lottie/animation.json'

export default function AdvancedLottie() {
  return (
    <div style={{ padding: '2rem' }}>
      <h2>高级配置:帧范围 + 渲染设置</h2>
      
      <Lottie
        animationData={animationData}
        width={300}
        height={300}
        autoplay={true}
        loop={true}
        initialSegment={[10, 50]} // 只播放第10到50帧
        // 自定义渲染配置
        rendererSettings={{
          preserveAspectRatio: 'xMidYMid meet', // 保持宽高比
          clearCanvas: true, // 每一帧清空画布
          antialias: true, // 开启抗锯齿
          backgroundColor: 'transparent', // 背景透明(默认白色)
        }}
      />
    </div>
  )
}

三、完整整合示例(串联所有 API)

下面是一个整合了「基础渲染、播放控制、事件监听、高级配置」的完整 Next.js 15 组件:

// app/lottie-full/page.tsx
'use client'
import React, { useRef, useState } from 'react'
import Lottie, { LottieRef } from 'lottie-react'
import animationData from '@/public/lottie/animation.json'

export default function FullLottieDemo() {
  // 1. 实例 ref + 状态管理
  const lottieRef = useRef<LottieRef>(null)
  const [log, setLog] = useState<string[]>([])
  const [speed, setSpeed] = useState<number>(1)
  const [frameRange, setFrameRange] = useState<[number, number]>([0, 100])

  // 2. 事件日志处理
  const addLog = (msg: string) => {
    setLog(prev => [...prev, `${new Date().toLocaleTimeString()}: ${msg}`].slice(-10))
  }

  // 3. 帧范围修改
  const updateFrameRange = () => {
    lottieRef.current?.destroy() // 先销毁旧实例
    // 重新渲染时应用新的帧范围
  }

  return (
    <div style={{ padding: '2rem', maxWidth: '1200px', margin: '0 auto' }}>
      <h1>Lottie-React + Next.js 15 全 API 实战</h1>

      <div style={{ display: 'flex', gap: '2rem', flexWrap: 'wrap' }}>
        {/* 动画容器 */}
        <div>
          <Lottie
            ref={lottieRef}
            animationData={animationData}
            width={400}
            height={400}
            autoplay={false}
            loop={true}
            speed={speed}
            initialSegment={frameRange}
            rendererSettings={{
              antialias: true,
              backgroundColor: 'transparent',
            }}
            onPlay={() => addLog('播放')}
            onPause={() => addLog('暂停')}
            onStop={() => addLog('停止')}
            onLoopComplete={() => addLog('循环完成')}
            onEnterFrame={(f) => f.currentFrame % 20 === 0 && addLog(`当前帧:${f.currentFrame}`)}
          />

          {/* 控制区 */}
          <div style={{ marginTop: '1rem', gap: '0.5rem', display: 'flex', flexWrap: 'wrap' }}>
            <button onClick={() => lottieRef.current?.play()} style={btnStyle}>播放</button>
            <button onClick={() => lottieRef.current?.pause()} style={btnStyle}>暂停</button>
            <button onClick={() => lottieRef.current?.stop()} style={btnStyle}>停止</button>
            
            <button onClick={() => { setSpeed(2); lottieRef.current?.setSpeed(2) }} style={btnStyle}>2倍速</button>
            <button onClick={() => { setSpeed(0.5); lottieRef.current?.setSpeed(0.5) }} style={btnStyle}>0.5倍速</button>
            
            <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
              <input
                type="number"
                value={frameRange[0]}
                onChange={(e) => setFrameRange([Number(e.target.value), frameRange[1]])}
                style={{ width: '60px', padding: '0.5rem' }}
                placeholder="起始帧"
              />
              <span>-</span>
              <input
                type="number"
                value={frameRange[1]}
                onChange={(e) => setFrameRange([frameRange[0], Number(e.target.value)])}
                style={{ width: '60px', padding: '0.5rem' }}
                placeholder="结束帧"
              />
              <button onClick={updateFrameRange} style={btnStyle}>应用帧范围</button>
            </div>
          </div>
        </div>

        {/* 日志面板 */}
        <div style={{ flex: 1, minWidth: '300px', border: '1px solid #eee', padding: '1rem', height: '400px', overflow: 'auto' }}>
          <h3>事件日志</h3>
          <ul style={{ listStyle: 'none', padding: 0 }}>
            {log.map((item, i) => (
              <li key={i} style={{ color: '#666', fontSize: '0.9rem', margin: '0.5rem 0' }}>{item}</li>
            ))}
          </ul>
        </div>
      </div>
    </div>
  )
}

const btnStyle = {
  padding: '0.5rem 1rem',
  border: 'none',
  borderRadius: '4px',
  backgroundColor: '#0070f3',
  color: 'white',
  cursor: 'pointer',
  minWidth: '80px',
}

四、Next.js 15 注意事项

  1. 客户端组件标记lottie-react 依赖浏览器 DOM,必须在组件顶部添加 'use client',否则会报 SSR 错误。
  2. 动画文件加载
    • animationPath 路径从 public 根目录开始(如 /lottie/animation.json);
    • animationData 导入本地 JSON 时,Next.js 15 无需额外配置,直接导入即可。
  3. 性能优化
    • 避免在 onEnterFrame 中执行复杂逻辑(会每帧触发,影响性能);
    • 非可视区域的 Lottie 动画建议销毁实例(lottieRef.current?.destroy())。
  4. 兼容问题:Next.js 15 对 React 19 兼容,lottie-react v2.x 以上版本已适配,建议使用最新版。

总结

  1. lottie-react 核心是 <Lottie /> 组件,在 Next.js 15 中必须标记为客户端组件('use client');
  2. 常用 API 分为三类:基础渲染(animationData/width)、播放控制(autoplay/play()/pause())、事件监听(onPlay/onLoopComplete);
  3. 高级用法可通过 initialSegment 控制播放帧范围,rendererSettings 自定义渲染配置,结合 ref 实例方法可实现全量播放控制。

通过以上教程,你可以在 Next.js 15 中完整使用 lottie-react 的所有常用 API,实现从基础渲染到复杂交互的 Lottie 动画效果。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐