基于svga+uniapp的微信小程序动画组件开发指南

lottie动画指南

效果

概述

本项目使用 svgaplayer.weapp.js 库来实现 SVGA 动画播放功能,支持在微信小程序、H5 等多端环境下播放高质量的矢量动画。SVGA 是一种跨平台的开源动画格式,具有文件小、渲染性能高的特点。

技术栈

  • 核心库: svgaplayer.weapp.js (专为小程序优化的 SVGA 播放器)
  • 框架: Vue 3 + Composition API
  • 平台: 支持微信小程序、H5 等多端

(svgaplayer.weapp二次封装)

项目结构

src/
├── components/
│   ├── common/
│   │   └── svgaPlayer.vue           # SVGA播放器核心组件
│   └── AnimationTemplate/
│       ├── index.vue                # 简化版动画模板组件
│       └── AnimationTemplate.vue   # 高级动画模板组件
├── static/
│   └── js/
│       └── svgaplayer.weapp.js     # SVGA播放器库文件
└── pages/
    └── sale-entry/
        └── index.vue               # 使用示例页面

核心组件

1. SvgaPlayer 组件 (src/components/common/svgaPlayer.vue)

这是 SVGA 播放的核心组件,负责加载、解析和播放 SVGA 动画文件。

主要特性:

  • 支持本地和远程 SVGA 文件加载
  • 内置缓存机制,避免重复加载
  • 支持循环播放、播放控制
  • 提供丰富的回调函数
  • 自动适配不同平台的 Canvas API

2. AnimationTemplate 组件

基于 SvgaPlayer 的封装组件,提供了更易用的动画展示模板。

主要特性:

  • 全屏遮罩展示
  • 支持多种位置布局(居中、顶部、底部)
  • 自动播放完成后隐藏
  • 支持手动关闭按钮

使用方法

基础使用

  1. 引入组件
<template>
  <view>
    <!-- 基础使用 -->
    <SvgaPlayer
      ref="svgaPlayerRef"
      :url="animationUrl"
      :width="300"
      :height="300"
      :canvas-id="'myCanvas'"
      :loops="1"
      :clears-after-stop="true"
    />

    <!-- 模板组件使用 -->
    <AnimationTemplate
      ref="animationTemplateRef"
      :animation-url="animationUrl"
      :width="400"
      :height="400"
      :loops="1"
      :show-close-button="true"
      @close="handleAnimationClose"
      @animationStart="handleAnimationStart"
      @animationEnd="handleAnimationEnd"
    />
  </view>
</template>
<script setup>
import SvgaPlayer from '@/components/common/svgaPlayer.vue';
import AnimationTemplate from '@/components/AnimationTemplate/AnimationTemplate.vue';

const svgaPlayerRef = ref(null);
const animationTemplateRef = ref(null);
const animationUrl = 'https://xxx.***.com.cn/frontEnd/files/common/aidfinal1.svga';
</script>

  1. 程序化控制
// 开始播放动画
const startAnimation = () => {
   
   
  if (animationTemplateRef.value) {
   
   
    // 设置回调函数
    setupAnimationCallbacks();
    // 开始播放
    animationTemplateRef.value.startAnimation();
  }
};

// 设置动画回调
const setupAnimationCallbacks = () => {
   
   
  if (animationTemplateRef.value) {
   
   
    // 动画完成回调
    animationTemplateRef.value.setOnFinished(() => {
   
   
      console.log('动画播放完成');
      animationTemplateRef.value.hide();
    });

    // 帧回调
    animationTemplateRef.value.setOnFrame((frame) => {
   
   
      console.log('当前帧:', frame);
    });

    // 进度回调
    animationTemplateRef.value.setOnPercentage((percentage) => {
   
   
      console.log('播放进度:', Math.<
<think>我们被要求实现微信小程序中播放SVGA动画并同时播放音频的功能。根据引用[1],我们知道SVGAPlayer-Web支持微信小程序,但该项目已不再维护。不过,我们仍然可以参考其实现。 步骤: 1. 引入SVGA播放器库:在微信小程序中,我们需要使用支持小程序的SVGA播放器。引用[1]提到SVGAPlayer-Web支持微信小程序,因此我们可以使用这个库(虽然不再维护,但可用)。 2. 加载SVGA文件:通过播放器加载SVGA动画文件。 3. 播放动画:调用播放器的方法播放动画。 4. 播放音频:使用微信小程序的音频API(wx.createInnerAudioContext)来播放音频,并需要与动画播放同步。 但是,SVGA文件本身并不包含音频,因此我们需要另外准备音频文件,并在动画开始播放时同时播放音频。 具体步骤: 1. 下载SVGA播放器的微信小程序版本。我们可以从GitHub上获取SVGAPlayer-Web的代码(https://github.com/svga/SVGAPlayer-Web),然后将适用于微信小程序的代码(位于miniprogram目录)复制到我们的小程序项目中。 2. 在需要播放动画的页面的json文件中引入SVGA组件: ```json { "usingComponents": { "svga": "/path/to/svga-miniprogram-component/index" } } ``` 3. 在wxml中使用svga组件: ```html <svga id="svgaPlayer" src="{{svgaUrl}}" loops="1" clearafterstop="true" bind:init="onSvgaInit" bind:start="onStart" bind:end="onEnd"></svga> ``` 这里我们绑定了几个事件:初始化完成、动画开始、动画结束。 4. 在页面的js文件中,我们需要: - 设置SVGA文件的URL和音频文件的URL。 - 在初始化完成后,我们可以获取播放器实例,但通常不需要,因为播放可以通过组件的方法触发。 -动画开始事件(onStart)中,我们播放音频。 - 注意:由于网络加载问题,音频可能需要预加载,以避免动画开始后音频加载延迟。 5. 音频播放: - 使用wx.createInnerAudioContext创建音频上下文。 - 预加载音频,并设置自动播放为false,然后在动画开始时播放。 6. 控制同步:由于动画和音频是两个独立的播放源,我们需要确保它们同时开始。我们可以在动画开始事件中同时启动动画和音频,但要注意动画可能已经开始(事件是在动画开始后触发的)。因此,我们可以先暂停动画,然后同时开始。 然而,SVGA组件的播放控制: 在组件初始化完成后,我们可以通过选择器获取组件实例,然后调用其方法。例如,我们可以先暂停,然后通过一个按钮同时开始,或者我们可以在加载完成后先暂停,然后在准备就绪后同时开始。 另一种做法: - 在onSvgaInit事件中,我们可以获取svga组件的实例,然后调用pause()方法暂停动画- 然后我们预加载音频,并等待用户触发(比如一个开始按钮)或者自动在合适的时机(比如都加载完成后)同时开始动画和音频。 但是,如果不需要用户交互,我们可以在页面显示后自动播放。我们可以这样做: a. 加载SVGA文件和音频文件(预加载音频)。 b. 在SVGA初始化完成后,暂停动画,并记录初始化完成。 c. 当音频加载完成(通过onCanplay事件)后,记录音频就绪。 d. 当两者都就绪后,同时开始播放动画和音频。 由于我们要求自动播放,且没有用户交互,所以需要这样处理。 具体代码结构示例: wxml: ```html <svga id="svgaPlayer" src="{{svgaUrl}}" loops="1" clearafterstop="true" bind:init="onSvgaInit" bind:start="onStart" bind:end="onEnd"></svga> ``` js: ```javascript Page({ data: { svgaUrl: 'https://example.com/animation.svga', // SVGA文件地址 audioReady: false, svgaReady: false, canPlay: false // 标记是否可以开始播放(两个都准备好) }, onLoad() { // 创建音频上下文 this.audioCtx = wx.createInnerAudioContext({ useWebAudioImplement: true // 使用Web Audio API,避免一些兼容性问题 }); this.audioCtx.src = 'https://example.com/sound.mp3'; this.audioCtx.autoplay = false; // 预加载音频 this.audioCtx.onCanplay(() => { this.setData({ audioReady: true }); this.checkCanPlay(); }); this.audioCtx.load(); // 加载音频 }, onSvgaInit(e) { // 初始化完成后,获取组件实例并保存 this.svgaPlayer = e.detail.player; // 暂停动画,等待音频加载完成 this.svgaPlayer.pause(); this.setData({ svgaReady: true }); this.checkCanPlay(); }, checkCanPlay() { if (this.data.audioReady && this.data.svgaReady) { this.setData({ canPlay: true }); // 同时开始 this.svgaPlayer.start(); // 开始动画 this.audioCtx.play(); // 播放音频 } }, onStart() { console.log('动画开始'); }, onEnd() { console.log('动画结束'); // 动画结束后,可以停止音频(如果音频还没结束,可以根据需要停止) // this.audioCtx.stop(); // 如果需要同时停止 }, onUnload() { // 销毁音频 if (this.audioCtx) { this.audioCtx.destroy(); } } }); ``` 注意:上面的代码中,我们通过一个检查函数`checkCanPlay`来确保两者都准备好后同时开始。但是,动画的开始我们调用了`this.svgaPlayer.start()`,而音频调用`this.audioCtx.play()`。 但是,我们注意到在`onSvgaInit`事件中,动画可能已经开始自动播放(因为组件默认可能会自动播放)。因此,我们需要在组件中设置属性`autoplay`为false?查看SVGAPlayer-Web的文档,它有一个`autoplay`属性,我们可以设置为0(false)或者不设置(默认是1,即自动播放)。所以我们在组件上设置`autoplay="0"`。 修改wxml: `<svga ... autoplay="0" ...>` 这样,动画加载完成后不会自动播放,而是等待我们的指令。 另外,我们使用`bind:init`事件来获取播放器实例,然后调用`pause()`其实不是必须的,因为我们已经设置autoplay为0。但为了保险,我们可以在获取实例后调用pause()确保暂停。 但是,在组件初始化时,我们设置了autoplay为0,所以不会自动播放,那么我们在两者准备好后直接调用`start()`即可。 然而,我们注意到在组件的文档中,播放控制有start、pause、stop等方法。我们通过`e.detail.player`获取到实例,然后调用这些方法。 7. 关于音频的循环:如果动画循环多次,音频可能需要根据情况处理。但上述代码中,我们设置动画循环1次(loops="1"),所以音频也只需要播放一次。 8. 如果动画循环多次,并且需要每次循环都播放音频,那么我们需要监听动画的循环事件(如果有)或者结束事件,然后在每次循环结束时重新播放音频(但这样可能不同步)。更复杂的需求可能需要更精细的控制。 9. 另外,注意微信小程序音频播放的限制:需要用户交互才能播放?在微信小程序中,音频播放需要用户交互(在部分iOS设备上)。但是,我们可以在用户打开页面后,通过一个按钮触发播放,或者使用wx.getSetting获取用户的授权。如果遇到自动播放问题,可能需要用户触发(比如点击一个按钮开始播放)。 10. 考虑到自动播放音频可能被阻止,我们可以设计一个“开始”按钮,用户点击后开始播放动画和音频。这样也能确保同步。 因此,如果遇到自动播放问题,我们可以改为用户点击后播放: wxml: ```html <svga id="svgaPlayer" ... autoplay="0"></svga> <button bindtap="onTapStart">开始播放</button> ``` js: ```javascript onTapStart() { if (this.data.canPlay) { this.svgaPlayer.start(); this.audioCtx.play(); } } ``` 这样,用户点击按钮后同时开始动画和音频。 总结: 根据以上分析,我们可以有两种实现方式: - 自动播放:在页面加载后自动加载,并在两者都准备好后自动播放(但可能受音频自动播放策略限制)。 - 用户触发:通过用户点击按钮来触发播放,避免自动播放的限制。 考虑到微信小程序的限制,推荐使用用户触发的方式。 因此,我们修改代码为: wxml: ```html <svga id="svgaPlayer" src="{{svgaUrl}}" loops="1" clearafterstop="true" bind:init="onSvgaInit" autoplay="0"></svga> <button bindtap="play" disabled="{{!canPlay}}">播放</button> ``` js: ```javascript Page({ data: { svgaUrl: 'https://example.com/animation.svga', audioUrl: 'https://example.com/sound.mp3', canPlay: false }, onLoad() { this.audioCtx = wx.createInnerAudioContext(); this.audioCtx.src = this.data.audioUrl; this.audioCtx.autoplay = false; this.audioCtx.onCanplay(() => { this.setData({ audioReady: true }); this.checkCanPlay(); }); this.audioCtx.load(); }, onSvgaInit(e) { this.svgaPlayer = e.detail.player; this.setData({ svgaReady: true }); this.checkCanPlay(); }, checkCanPlay() { if (this.data.audioReady && this.data.svgaReady) { this.setData({ canPlay: true }); } }, play() { if (this.data.canPlay) { this.svgaPlayer.start(); this.audioCtx.play(); } }, onUnload() { if (this.audioCtx) { this.audioCtx.destroy(); } } }); ``` 注意:这里我们给按钮绑定了play事件,并且在不可用时禁用按钮。 这样,用户点击按钮后,动画和音频会同时开始。 关于SVGA文件的获取:需要将SVGA文件放在服务器上,然后设置src为对应的URL。同样,音频文件也需要放在服务器上。 另外,SVGA组件可能还支持其他属性,比如设置循环次数、清除画布等,可以根据需要设置。 最后,由于SVGAPlayer-Web已经不再维护,如果遇到问题,可能需要考虑其他方案,比如引用[2]和[3]提到的PAG(腾讯开源的动画渲染库),它支持微信小程序,并且功能更加强大。但是,用户要求使用SVGA格式,所以我们还是使用SVGA播放器。 如果决定使用PAG,那么实现方式会有所不同。但根据问题,我们使用SVGA。 因此,按照上述步骤即可在微信小程序中播放SVGA动画并同时播放音频。 注意:实际项目中,需要确保SVGA文件和音频文件的地址正确,并且注意网络请求的域名需要配置在小程序的合法域名中。 引用: [^1]: SVGAPlayer-Web 是一个轻量级的JavaScript库,专门用于在Web环境中播放SVGA格式的动画。这个项目虽然已经不再维护,但其遗留的代码和资源仍然是一个宝贵的参考资料,可以继续被开发者们使用和学习。此外,它还提供了对微信小程序的支持,使得在小程序中集成动态效果变得轻松简单。 [^2]: 主要使用在 UI 动画场景,存在 Android、iOS、macOS、Web、微信小程序等平台,iOS 平台继承于 UIView, Andoroid 平台继承于 TextView, PAGView 支持通过本地路径 和 PAGComposition 加载, 调用 play 方法进行播放,内部有一个定时器,同时也提供了 PAGViewListener 的接口监听动画播放的状态,PAGView 内部实现了 PAGPlayer、PAGSurface、PAGComposition 的封装处理。 [^3]: 一个简单的全屏动效展示功能 ...(代码示例)... 三、动效踩过的坑 ...(比较了视频、gif、帧动画的缺点)... 根据引用[1],我们使用了SVGAPlayer-Web的微信小程序组件。同时,引用[3]中提到了一些动效的坑,其中SVGA可能避免了gif和帧动画的一些问题,但要注意SVGA文件大小和复杂动画的支持。 相关问题: 1. 微信小程序中播放SVGA动画时如何控制播放速度? 2. 如何监听SVGA动画的循环事件? 3. 微信小程序中同时播放多个音频有什么限制?</think>### 微信小程序播放 SVGA 动画并同步音频的实现方法 在微信小程序中实现 SVGA 动画与音频同步播放,需要结合 **SVGA 播放器组件**和**微信音频 API**,以下是具体实现步骤: --- #### 一、核心实现步骤 1. **引入 SVGA 播放器** - 下载 [SVGAPlayer-Mini](https://github.com/svga/SVGAPlayer-Web/tree/master/miniprogram) 组件 -组件复制到小程序项目目录(如 `components/svga-player`) - 在页面 JSON 中注册组件: ```json { "usingComponents": { "svga-player": "/components/svga-player/index" } } ``` 2. **WXML 布局** ```html <svga-player id="svgaPlayer" src="{{svgaUrl}}" loops="1" clearafterstop="true" bindinit="onSvgaInit" bindstart="onAnimationStart" ></svga-player> ``` 3. **JS 逻辑控制** ```javascript Page({ data: { svgaUrl: 'https://example.com/anim.svga', // SVGA 文件 URL audioReady: false }, onLoad() { // 创建音频上下文 this.audioCtx = wx.createInnerAudioContext() this.audioCtx.src = 'https://example.com/sound.mp3' this.audioCtx.autoplay = false this.audioCtx.onCanplay(() => { this.setData({ audioReady: true }) }) }, // SVGA 初始化完成 onSvgaInit(e) { this.svgaPlayer = e.detail.player }, // 动画开始事件(同步播放音频) onAnimationStart() { if (this.data.audioReady) { this.audioCtx.seek(0) // 重置音频进度 this.audioCtx.play() // 播放音频 } }, // 用户触发播放(如按钮点击) playAnimation() { if (this.svgaPlayer) { this.svgaPlayer.start() // 触发 bindstart 事件 } }, onUnload() { this.audioCtx.destroy() // 销毁音频实例 } }) ``` --- #### 二、关键细节说明 1. **同步机制** - 通过 SVGA 的 `bindstart` 事件触发音频播放,确保两者同时开始 - 使用 `audioCtx.seek(0)` 保证每次播放都从音频开头开始 2. **音频预加载** ```javascript // 提升首次播放体验 this.audioCtx.obeyMuteSwitch = false // iOS 静音开关不影响 this.audioCtx.preload = 'auto' // 自动预加载 ``` 3. **循环播放处理** - 若需循环播放,在动画结束时重置: ```javascript bindended="onAnimationEnd" // ... onAnimationEnd() { this.audioCtx.stop() this.svgaPlayer.start() // 重新开始动画 } ``` 4. **资源加载优化** - SVGA 文件不超过 500KB(微信小程序包限制) - 使用 CDN 加速资源加载 - 添加加载状态提示: ```html <text wx:if="{{!audioReady}}">资源加载中...</text> ``` --- #### 三、注意事项 1. **iOS 音频限制** - 需用户交互(如按钮点击)触发首次音频播放 - 解决方案:将 `playAnimation()` 绑定到按钮点击事件 2. **性能优化** - 避免同时播放多个 SVGA 动画 - 使用 `wx.compressImage` 压缩音频文件 - 动画结束后调用 `this.svgaPlayer.clear()` 释放内存 3. **兼容性** - 测试基础库版本 ≥ 2.7.3(确保 `createInnerAudioContext` 完整支持) - 安卓端注意静音模式处理: ```javascript this.audioCtx.obeyMuteSwitch = false ``` > ⚠️ 注意:SVGAPlayer-Web 项目已停止维护[^1],若遇到兼容性问题可考虑替代方案(如 PAG 动画库[^2]) --- #### 四、替代方案参考 如需更完善的音画同步方案,可考虑腾讯开源的 **PAG 动画库**: ```javascript // PAG 实现示例(需单独集成) const pagFile = PAG.PAGFile.load(await fetch('anim.pag')) const pagView = await PAG.PAGView.init(pagFile, canvas) pagView.play().then(() => { wx.createInnerAudioContext().play() // 精确到帧同步 }) ``` 优势:支持逐帧回调、AE 特效、音频轨道嵌入[^3] ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值