SVGAPlayer-Web-Lite 基于 SVGA 在移动端 Web 上的播放器 TS 版

发布于 2021-09-08 22:24:17 字数 8060 浏览 1616 评论 0

这是一个 SVGA 在移动端 Web 上的播放器,它的目标是 更轻量更高效,但它也放弃了对旧版本浏览器的兼容性支持。

依赖 Promise

若出现 Promise is not a constructor 等问题,外链 polyfill 或配置 babel 进行兼容

<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>

实现

  • 体积 = 55kb (gzip = 18kb)
  • 兼容 Android 4.4+ / iOS 9+
  • 更好的异步操作
  • 多线程 (WebWorker) 解析文件数据
  • OffscreenCanvas

实验性

  • 渲染引擎模拟运行在 WebWorker
  • 使用 WebAssembly 替代 WebWorker
  • GPU 加速运算

差异

  • 不支持声音播放

安装

NPM

yarn add svga.lite

# 或者

npm i svga.lite

CDN

<script src="https://cdn.jsdelivr.net/npm/svga.lite/svga.lite.min.js"></script>

使用

简单使用

<canvas id="canvas"></canvas>
import { Downloader, Parser, Player } from 'svga.lite'

const downloader = new Downloader()
// 默认调用 WebWorker 线程解析
// 可配置 new Parser({ disableWorker: true }) 禁止
const parser = new Parser()
// #canvas 是 HTMLCanvasElement
const player = new Player('#canvas')

;(async () => {
  const fileData = await downloader.get('./xxx.svga')
  const svgaData = await parser.do(fileData)

  player.set({ loop: 1 })

  await player.mount(svgaData)

  player
    // 开始动画事件回调
    .$on('start', () => console.log('event start'))
    // 暂停动画事件回调
    .$on('pause', () => console.log('event pause'))
    // 继续播放动画事件回调
    .$on('resume', () => console.log('event resume'))
    // 停止动画事件回调
    .$on('stop', () => console.log('event stop'))
    // 动画结束事件回调
    .$on('end', () => console.log('event end'))
    // 清空动画事件回调
    .$on('clear', () => console.log('event clear'))
    // 动画播放中事件回调
    .$on('process', () => console.log('event process', player.progress))

  // 开始播放动画
  player.start()

  // 暂停播放动画
  // player.pause()

  // 继续播放动画
  // player.resume()

  // 停止播放动画
  // player.stop()

  // 清空动画
  // player.clear()
})()

Player.set({ 参数 })

属性名说明类型默认值备注
loop循环次数number0设置为 0 时,循环播放
fillMode最后停留的目标模式forwards backwardsforwards类似于 css animation-fill-mode
playMode播放模式forwards fallbacksforwards
startFrame开始播放帧number0
endFrame结束播放帧number0设置为 0 时,默认为 SVGA 文件最后一帧
cacheFrames(v1.5+)是否缓存帧booleanfalse开启后对已绘制的帧进行缓存,提升重复播放动画性能
intersectionObserverRender(v1.5+)是否开启动画容器视窗检测booleanfalse开启后利用 Intersection Observer API 检测动画容器是否处于视窗内,若处于视窗外,停止描绘渲染帧避免造成资源消耗
noExecutionDelay(v1.5+)是否避免执行延迟booleanfalse开启后使用 WebWorker 确保动画按时执行( 一些情况下浏览器会延迟或停止执行一些任务

支持 1.x 版本 SVGA

import { Downloader, Parser, Player } from 'svga.lite'
import Parser1x from 'svga.lite/parser.1x'
import * as util from 'svga.lite/util'

const downloader = new Downloader()
const svgaFile = './svga/show.svga'
const fileData = await downloader.get(svgaFile)

// Parser1x 默认调用 WebWorker 线程解析
// 可配置 new Parser1x({ disableWorker: true }) 禁止
const parser = util.version(fileData) === 1 ? new Parser1x() : new Parser()
const svgaData = await parser.do(fileData)

const player = new Player('#canvas')
await player.mount(svgaData)
player.start()

替换元素

你能够通过改变 svga data 对应键值的元素

import { Downloader, Parser, Player } from 'svga.lite'

const downloader = new Downloader()
const parser = new Parser()
const player = new Player('#canvas')

;(async () => {
  const fileData = await downloader.get('./xxx.svga')
  const svgaData = await parser.do(fileData)

  const image = new Image()
  image.src = 'https://xxx.com/xxx.png'
  svgaData.images['key'] = image

  await player.mount(svgaData)

  player.start()
})()

动态元素

你可以通过 svga data 插入一些动态元素

const text = 'hello gg'
const fontCanvas = document.getElementById('font')
const fontContext = fontCanvas.getContext('2d')
fontCanvas.height = 30
fontContext.font = '30px Arial'
fontContext.textAlign = 'center'
fontContext.textBaseline = 'middle'
fontContext.fillStyle = '#000'
fontContext.fillText(text, fontCanvas.clientWidth / 2, fontCanvas.clientHeight / 2)

const { Downloader, Parser, Player } = SVGA
const downloader = new Downloader()
const parser = new Parser()
const player = new Player('#canvas')
const svgaFile = './svga/kingset.svga'
const fileData = await downloader.get(svgaFile)
const svgaData = await parser.do(fileData)

svgaData.dynamicElements['banner'] = fontCanvas

await player.mount(svgaData)

player.start()

可复用实例化 Downloader & Parser

import { Downloader, Parser, Player } from 'svga.lite'

const downloader = new Downloader()
const parser = new Parser()
const player1 = new Player('#canvas1')
const player2 = new Player('#canvas2')
const fileData1 = await downloader.get('./1.svga')
const fileData2 = await downloader.get('./2.svga')
const svgaData1 = await parser.do(fileData1)
const svgaData2 = await parser.do(fileData2)

await player1.mount(svgaData1)
await player2.mount(svgaData2)

player1.start()
player2.start()

销毁实例

const downloader = new Downloader()
downloader.destroy()

const parser = new Parser()
parser.destroy()

const player = new Player('#canvas')
player.destroy()

DB (v1.5+)

已下载并解析的数据利用 IndexedDB 进行持久化缓存,下次可避免重复消耗资源对统一 SVGA 下载和解析

import { Downloader, Parser, Player } from 'svga.lite'
import DB from 'svga.lite/db'

const svgaFile = 'test.svga'
let data = void 0
let db = void 0

try {
  db = new DB()
} catch (error) {
  console.error(error)
}

if (db) {
  data = await db.find(svgaFile)
}

if (!data) {
  const downloader = new Downloader()
  const fileData = await downloader.get(svgaFile)
  const parser = new Parser()

  data = await parser.do(fileData)

  // 插入数据
  db && (await db.insert(svgaFile, data))
}

const player = new Player('#canvas')
await player.mount(data)

player.start()

Downloader Cancel (v1.4.0+)

你可以取消下载中的 SVGA 文件请求

downloader.get('test.svga').then((fileData) => {
  console.log('下载完成')
}).catch(error => {
  console.log('catch', error)
})

setTimeout(() => {
  downloader.cancel() // 或者 downloader.destroy()
}, 1000)

项目地址:https://www.npmjs.com/package/svga.lite

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

lorenzathorton8

文章 0 评论 0

Zero

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

mylayout

文章 0 评论 0

tkewei

文章 0 评论 0

17818769742

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文