更新记录
1.0.0(2026-07-12)
- 发布 Android、iOS UTS 原生 SVGA 播放组件。
- 支持 uni-app App nvue 页面和 uni-app x App。
- 支持网络 SVGA、本地
/staticSVGA 资源加载。 - 支持加载、播放、暂停、继续、停止、清空和连续切换资源。
- 支持循环次数、结束画面、缩放模式和停止清屏设置。
- 支持指定帧、指定进度和指定帧区间播放。
- 支持查询动画总帧数以及加载、播放、循环、帧进度、完成和错误事件。
- 支持包含内嵌音频的 SVGA 动画。
平台兼容性
uni-app(3.8.0)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | √ | 1.0.0 | 5.0 | 1.0.0 | 12 | 1.0.0 | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(3.8.0)
| Chrome | Safari | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|---|---|
| × | × | 5.0 | 1.0.0 | 12 | 1.0.0 | × | × |
kongbai-svga
kongbai-svga 是基于 UTS 原生组件开发的 SVGA 播放组件,适用于 uni-app App nvue 页面和 uni-app x App。组件封装了 Android、iOS 原生 SVGAPlayer,支持网络资源、本地资源、播放控制、循环播放、指定帧播放、进度跳转以及带内嵌音频的 SVGA 文件。
适合直播礼物、入场特效、会员开通、活动奖励等需要连续播放 SVGA 动画的 App 场景。组件不包含广告代码,不采集、不存储、不上传用户个人信息;播放网络资源时仅使用宿主 App 已配置的网络访问能力。
平台支持
| 平台 | 支持情况 |
|---|---|
| uni-app App nvue Android | 支持 |
| uni-app App nvue iOS | 支持 |
| uni-app x App Android | 支持 |
| uni-app x App iOS | 支持 |
| uni-app vue 页面 | 不支持 |
| Web / H5 | 不支持 |
| 各类小程序 | 不支持 |
组件依赖原生 SDK,普通浏览器和小程序环境无法运行。添加或更新插件后,必须重新制作包含 kongbai-svga 的自定义基座或重新云打包;普通调试基座和热更新都不会包含 SVGAPlayer-Android,会导致 NoClassDefFoundError: com.opensource.svgaplayer.SVGAImageView。
原生依赖
- Android:
com.github.yyued:SVGAPlayer-Android:2.6.1 - iOS:
SVGAPlayer 2.5.7 - Android 最低版本:API 21
- iOS 最低版本:iOS 9
Android 依赖从 JitPack 下载,插件的 app-android/config.json 已配置 https://jitpack.io 仓库。制作基座或云打包时需要保持网络可访问该仓库。
安装
将插件放入项目的 uni_modules/kongbai-svga 目录即可。组件会按照 uni_modules 规范自动注册,不需要在页面中手动 import。
uni-app 项目必须在 .nvue 页面中使用;uni-app x 项目在 .uvue 页面中使用。
uni-app nvue 基础示例
<template>
<view class="page">
<kongbai-svga
ref="svga"
class="svga-player"
:autoPlay="false"
:loops="1"
fillMode="forward"
scaleMode="fitCenter"
@ready="onReady"
@finished="onFinished"
@error="onError"
></kongbai-svga>
<text @click="loadAndPlay">加载并播放</text>
<text @click="pause">暂停</text>
<text @click="resume">继续</text>
<text @click="stop">停止</text>
<text @click="getTotalFrames">获取总帧数</text>
</view>
</template>
<script>
export default {
methods: {
loadAndPlay() {
this.$refs.svga.loadAndPlay('/static/demo.svga')
},
pause() {
this.$refs.svga.pause()
},
resume() {
this.$refs.svga.resume()
},
stop() {
this.$refs.svga.stop(false)
},
getTotalFrames() {
this.$refs.svga.getTotalFrames((frames) => {
console.log('总帧数', frames)
})
},
onReady(event) {
const detail = this.getEventDetail(event)
console.log('加载完成', detail)
},
onFinished(event) {
const detail = this.getEventDetail(event)
console.log('播放完成', detail)
},
onError(event) {
const detail = this.getEventDetail(event)
console.log('加载失败', detail.code, detail.message)
},
// nvue 会把 UTS 组件事件对象包装到 dynamicJSONFields 中。
getEventDetail(event) {
const eventDetail = event.detail || event
return eventDetail.dynamicJSONFields || eventDetail
}
}
}
</script>
<style>
.svga-player {
width: 750rpx;
height: 500rpx;
}
</style>
uni-app x 基础示例
<template>
<view>
<kongbai-svga
ref="svgaRef"
class="svga-player"
:autoPlay="false"
@ready="onReady"
@error="onError"
></kongbai-svga>
</view>
</template>
<script setup lang="uts">
const svgaRef = ref<KongbaiSvgaElement | null>(null)
function loadAndPlay() {
svgaRef.value?.loadAndPlay('/static/demo.svga')
}
function pause() {
svgaRef.value?.pause()
}
function resume() {
svgaRef.value?.resume()
}
function playFromFrame() {
svgaRef.value?.stepToFrame(30, true)
}
function getTotalFrames() {
svgaRef.value?.getTotalFrames((frames : any, keepAlive : boolean) => {
console.log('总帧数', frames as number)
})
}
function onReady(event : UniCustomEvent<UTSJSONObject>) {
console.log('加载完成', event.detail)
}
function onError(event : UniCustomEvent<UTSJSONObject>) {
console.log('加载失败', event.detail)
}
</script>
<style lang="scss">
.svga-player {
width: 750rpx;
height: 500rpx;
}
</style>
加载资源
本地资源
将文件放在项目 static 目录,通过根路径加载:
this.$refs.svga.loadAndPlay('/static/demo.svga')
Android 端会将 /static 路径转换为应用运行时的真实资源路径,不要读取或引用 unpackage 中的编译产物。
网络资源
this.$refs.svga.loadAndPlay('https://example.com/demo.svga')
网络地址必须可以由 App 直接访问。加载失败时通过 error 事件返回错误信息。
只加载不播放
this.$refs.svga.load('/static/demo.svga')
收到 ready 事件后,资源已经解析完成,可以调用 play()、stepToFrame() 或其他播放方法。
连续切换动画
直接再次调用 loadAndPlay() 即可播放新资源:
this.$refs.svga.loadAndPlay('/static/gift-1.svga')
this.$refs.svga.loadAndPlay('/static/gift-2.svga')
切换时组件会停止当前动画、清空画布并加载新资源。旧资源尚未完成的解析结果和播放回调会被忽略,避免连续礼物动画发生闪屏或回调串线。
播放控制
暂停和继续
this.$refs.svga.pause()
this.$refs.svga.resume()
pause() 保留当前播放帧;resume() 从暂停位置继续播放。continuePlay() 是 resume() 的别名。
停止
// 停止并回到开始帧,保留画布。
this.$refs.svga.stop(false)
// 停止并清空画布。
this.$refs.svga.stop(true)
停止和暂停的用途不同:暂停用于稍后继续,停止会重置播放进度。
清空
this.$refs.svga.clear()
clear() 会停止当前动画、清空画布并释放当前资源。清空后需要重新调用 load() 或 loadAndPlay()。
指定帧和指定进度
// 显示第 30 帧,不继续播放。
this.$refs.svga.stepToFrame(30, false)
// 跳到第 30 帧并继续播放。
this.$refs.svga.stepToFrame(30, true)
// 跳到 50% 的位置并继续播放。
this.$refs.svga.stepToPercentage(0.5, true)
指定帧前应确保资源已经触发 ready。如果资源尚未加载,请先调用 load(),在 ready 事件中执行跳转。
播放指定帧区间:
// 从第 20 帧开始播放 40 帧,false 表示正向播放。
this.$refs.svga.playRange(20, 40, false)
获取总帧数
uni-app nvue 不支持原生组件方法同步返回值,因此 getTotalFrames() 通过 callback 返回一个帧数值。uni-app x 使用相同接口:
getTotalFrames() {
this.$refs.svga.getTotalFrames((frames) => {
console.log('总帧数', frames)
})
}
资源未加载或已经调用 clear() 时,帧数为 0。
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
src |
String | "" |
SVGA 本地路径或网络地址;变更后自动加载 |
source |
String | "" |
src 的兼容别名;同时设置时以 src 为准 |
autoPlay |
Boolean | true |
通过属性加载完成后是否自动播放 |
loops |
Number | 0 |
播放次数;0 表示无限循环 |
fillMode |
String | forward |
播放结束后的画面状态 |
scaleMode |
String | fitCenter |
动画在组件区域内的缩放方式 |
clearsAfterStop |
Boolean | false |
调用 stop(false) 时是否仍清空画布 |
fillMode
| 值 | 说明 |
|---|---|
forward |
播放结束后保留最后一帧 |
backward |
播放结束后显示开始帧 |
clear |
播放结束后清空画面 |
兼容值:first 等同于 backward,none 等同于 clear。
scaleMode
| 值 | 说明 |
|---|---|
fitCenter |
保持比例完整显示,居中放置 |
center |
原始尺寸居中 |
centerCrop / center_crop |
保持比例铺满,超出部分裁剪 |
centerInside / center_inside |
保持比例并限制在组件范围内 |
fitXY / fit_xy / stretch |
拉伸铺满组件区域 |
fitStart / fit_start |
保持比例并靠起始位置 |
fitEnd / fit_end |
保持比例并靠结束位置 |
不同系统原生 SDK 的缩放实现存在细微差异,建议为播放区域设置固定宽高,并使用实际资源检查显示效果。
方法
| 方法 | 参数 | 说明 |
|---|---|---|
load(src) |
src: String |
加载资源,不自动播放 |
loadAndPlay(src) |
src: String |
加载资源并在解析完成后播放 |
play() |
无 | 播放当前资源;未加载时会尝试加载当前地址 |
start() |
无 | play() 的别名 |
playRange(startFrame, frames, reverse) |
起始帧、播放帧数、是否倒序 | 播放指定帧区间 |
pause() |
无 | 暂停并保留当前帧 |
resume() |
无 | 从暂停位置继续播放 |
continuePlay() |
无 | resume() 的别名 |
stop(clear) |
clear: Boolean |
停止并重置进度;按参数决定是否清空 |
clear() |
无 | 停止、清空画布并释放当前资源 |
updateLoops(count) |
count: Number |
立即更新循环次数,0 表示无限循环 |
updateFillMode(mode) |
mode: String |
立即更新结束显示模式 |
updateScaleMode(mode) |
mode: String |
立即更新缩放模式 |
updateClearsAfterStop(value) |
value: Boolean |
设置停止时是否清空画布 |
stepToFrame(frame, andPlay) |
帧序号、是否继续播放 | 跳转到指定帧 |
stepToPercentage(percentage, andPlay) |
0-1 进度、是否继续播放 |
跳转到指定进度 |
getState() |
无 | 获取组件内部加载和播放状态 |
getTotalFrames(callback) |
callback: Function |
获取总帧数,callback 只返回帧数值 |
事件
| 事件 | 数据 | 说明 |
|---|---|---|
load |
src |
开始加载资源 |
ready |
Android:src、frames、fps |
资源解析完成 |
start |
src |
开始播放 |
pause |
src |
播放暂停 |
resume |
src |
继续播放 |
stop |
src、clear |
播放停止 |
finished |
src |
当前播放完成 |
repeat |
src |
Android 每次循环回调 |
step |
src、frame、percentage |
Android 播放帧进度回调 |
error |
code、message、src |
资源加载或解析失败 |
clear |
src |
画布已清空 |
表中事件数据以 Android 为准。iOS 支持 load、ready、start、pause、resume、stop、finished、error、clear 事件,但目前不携带 src、帧数、错误码等事件详情;repeat 和 step 仅 Android 支持。跨端业务请将事件作为状态通知使用,或仅在 Android 端读取 event.detail。
错误码
| 错误码 | 说明 |
|---|---|
empty_src |
资源地址为空 |
invalid_stream |
无法打开本地文件或系统资源流 |
load_failed |
加载过程发生异常 |
parse_failed |
文件下载完成,但 SVGA 解析失败 |
invalid_url |
iOS 网络资源地址不合法 |
invalid_path |
iOS 本地资源路径不合法 |
unsupported_src |
iOS 不支持 data: URI 资源 |
音频说明
组件支持带内嵌音频的 SVGA 文件,不接收单独的 mp3、wav 地址。音频播放由原生 SVGAPlayer 管理,会跟随动画的播放、暂停、继续、停止和清空操作。
如果动画可以显示但没有声音,请先确认源文件本身包含音频,并检查设备媒体音量和系统静音状态。
使用建议
- 礼物动画连续播放时,直接调用新的
loadAndPlay(),不需要先手动clear()。 - 组件必须设置明确的宽度和高度,否则原生画布可能没有可见区域。
- 本地测试资源建议放在
static目录,使用/static/文件名.svga。 - 调整插件原生依赖或 UTS 源码后,需要重新制作基座或重新打包。
- 不要调用 nvue 的
$callMethod(),直接通过组件ref调用公开方法。 - 不要将原生组件 ref 强制转换为普通 VueComponent。
常见问题
点击方法提示 load is not a function
确认页面是 .nvue,插件位于 uni_modules/kongbai-svga,并且更新插件后已经重新制作基座。不要在普通 .vue 页面中使用原生组件。
$callMethod is not a function
本组件的方法已经通过 ref 公开,直接调用:
this.$refs.svga.loadAndPlay('/static/demo.svga')
本地文件提示 parse_failed
确认文件是有效的 SVGA 文件,并使用 /static/demo.svga 形式的路径。不要使用 unpackage 中的临时编译路径。
动画播放完保留最后一帧
这是 fillMode="forward" 的效果。需要播放结束后清空时,将 fillMode 设置为 clear,或者主动调用 clear()。
获取总帧数没有同步返回值
这是 nvue 原生组件的方法桥接方式决定的。请通过 getTotalFrames((frames) => {}) 获取数值,不要使用 const frames = getTotalFrames()。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 8
赞赏 0
下载 12417505
赞赏 1933
赞赏
京公网安备:11010802035340号