更新记录

v0.1.9(2026-09-27) 下载此版本

优化预加载方案,使用indexedDB缓存替代内存缓存

v0.1.8(2026-08-28) 下载此版本

新增 svga 播放开始时的 start 函数

v0.1.7(2026-08-28) 下载此版本

修复 process 函数丢失

查看更多

平台兼容性

uni-app(3.8.4)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- √ √ √ - - - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

一个使用 svga 库封装的 uniapp H5 SVGA 播放组件示例项目

预览

特性

  • IndexedDB 持久缓存:资源字节缓存在 IndexedDB(磁盘级),跨会话复用,二次播放零网络请求
  • 零开销预加载:preload 只下载字节写入 IndexedDB,不做解析、不挂载、不占运行时内存
  • 按需解析、用完即还:play 每次直接读 IndexedDB 转 objectURL,再创建 Parser / Player;播完、停止或失败立即销毁并 revokeObjectURL——不保留任何会话级缓存,常驻内存恒定为单次播放的量
  • 缓存过期:通过 cacheMaxAge 控制 IndexedDB 缓存有效期,过期自动重新下载
  • 尺寸单位:width / height 支持 px、rpx、vw 等 CSS 单位(rpx 按 750 基准换算为 px)

平台限制:组件依赖 indexedDB、document.createElement('canvas')、URL.createObjectURL 等浏览器 API,仅支持 H5 平台。

安装依赖

pnpm install
# 或仅安装播放器依赖
pnpm install svga

基本使用

<script setup lang="ts">
import svgaPlayer from '@/components/svga-player/svga-player.vue'

const svgaPlayerRef = ref<InstanceType<typeof svgaPlayer>>()

const svgaUrl = new URL('@/static/svga/angel.svga', import.meta.url).href

onMounted(() => {
  svgaPlayerRef.value?.play(svgaUrl)
})
</script>

<template>
  <svga-player ref="svgaPlayerRef" />
</template>

完整示例

<script setup lang="ts">
import svgaPlayer from '@/components/svga-player/svga-player.vue'

const svgaPlayerRef = ref<InstanceType<typeof svgaPlayer>>()

const svga = [
  new URL('@/static/svga/angel.svga', import.meta.url).href,
  new URL('@/static/svga/rose.svga', import.meta.url).href,
]

const loop = ref(1)

onMounted(() => {
  svgaPlayerRef.value?.play(svga[0])
  svgaPlayerRef.value?.preload(svga[1])
})

async function handlePlay(url: string) {
  try {
    await svgaPlayerRef.value?.play(url)
  }
  catch (e) {
    // play 失败时除触发 error 事件外,Promise 也会 reject
    console.error('play failed:', e)
  }
}

function handleStop() {
  svgaPlayerRef.value?.stop()
}

function onReady() {
  console.info('SVGA ready')
}

function onStart() {
  console.info('SVGA started')
}

function onProcess(p: { elapsed: number, remain: number }) {
  console.info(`elapsed: ${p.elapsed}s, remain: ${p.remain}s`)
}

function onEnd() {
  console.info('SVGA playback ended')
}

function onError(e: unknown) {
  console.error('SVGA error:', e)
}

function onLoopChange(e: any) {
  loop.value = e.detail.value
}
</script>

<template>
  <view>
    <slider :value="loop" :min="1" :max="10" show-value @change="onLoopChange" />
    <button @click="handlePlay(svga[0])">天使</button>
    <button @click="handlePlay(svga[1])">玫瑰</button>
    <button @click="handleStop">停止</button>

    <svga-player
      ref="svgaPlayerRef"
      :loop="loop"
      canvas-id="svga-main"
      @ready="onReady"
      @start="onStart"
      @process="onProcess"
      @end="onEnd"
      @error="onError"
    />
  </view>
</template>

Props 属性

属性名 类型 默认值 说明
canvasId string 'svga-container' Canvas 元素的 ID,用于挂载播放器 DOM 节点。同一页面使用多个播放器时需设置不同的 ID。
loop number 1 动画循环次数。设置为 0 表示无限循环。
width string '100vw' Canvas 宽度,支持 px、rpx、vw 等 CSS 单位(rpx 按 750 基准换算)。
height string 'auto' Canvas 高度,支持 px、rpx、vw 等 CSS 单位(rpx 按 750 基准换算)。
customClass string '' 自定义容器类名,追加到容器的 class 上,可用于样式定制。
cacheMaxAge number \| null null IndexedDB 缓存有效期(毫秒)。null 表示永不过期。过期后 play 会删除旧缓存并在后台重新下载(本次播放仍使用原 URL,下次命中最新缓存)。

Method 实例方法

通过 ref 调用,均已 defineExpose 暴露。

方法名 参数 返回值 说明
preload svgaUrl: string \| string[] Promise<void> 预加载 SVGA 动画(支持单个或多个 URL)。仅下载字节写入 IndexedDB,不做解析与挂载;已存在且未过期则跳过。失败时触发 error 事件(不 reject)。
play svgaUrl: string Promise<void> 播放指定的 SVGA 动画。播放或加载期间重复调用会被忽略(重入保护)。播放结束、stop 或失败会自动销毁播放器并回收 objectURL。失败时触发 error 事件且 Promise 会 reject(被 stop 主动中止的调用静默返回,不触发 error)。
stop 无 void 停止播放并清理资源(与播完一致):销毁 Parser / Player、回收 objectURL、重置状态并隐藏容器。加载期间调用不会立即中断,而是标记取消,由进行中的 play() 在加载完成后自动清理并静默退出。

Events 事件

事件名 回调参数 说明
ready 无 SVGA 解析成功并挂载到播放器后、开始播放前触发。
start 无 SVGA 动画开始播放时触发。
process { elapsed: number, remain: number } 动画播放过程中逐帧触发。elapsed 为已播放时长(秒),remain 为剩余时长(秒)。
end 无 动画播放完成(loop 次数耗尽)后触发。触发前资源已清理完毕(Parser / Player 销毁、objectURL 回收),因此可在本回调内立即发起下一次 play()。
error error: unknown 预加载、播放或容器初始化失败时触发。

工作流程

preload(url | urls)  ──→  fetch 字节  ──→  写入 IndexedDB(不解析 / 不挂载 / 不占运行时内存)
                                                │
play(url)  ──→  读 IndexedDB ── 命中未过期 ──→  Blob → createObjectURL(仅存活于本次播放)
           │                ── 命中已过期 ──→  删除旧记录 + 后台重下,本次用原 url
           │                 ── 未命中 ──→  用原 url,后台静默下载供下次使用
                                                ↓
                  Parser.load(url)  ──→  Player.mount(video)  ──→  start()
                   │
                   │  加载期间收到 stop() / unmount → 标记 cancelled,
                   │  play() 在检查点静默 cleanup() 退出
                   ↓
        onEnd() / stop() / 失败  ──→  cleanup(): stop + clear + destroy Parser/Player
                                                ──→  revokeObjectURL,释放内存
                                                ──→  之后才触发 @end(回调内可立即 play())

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

无

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议

暂无用户评论。