Coder Social home page Coder Social logo

svgaplayer-web-lite's Introduction

SVGAPlayer-Web-Lite · npm version PRs Welcome

这是一个 SVGA 在移动端 Web 上的播放器,它的目标是 更轻量更高效

实现

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

实验性

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

差异

  • 不支持播放 SVGA 1.x 格式
  • 不支持声音播放

安装

NPM

yarn add svga
# 或者
npm i svga

CDN

<script src="https://unpkg.com/svga/dist/index.min.js"></script>

使用

简单使用

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

const parser = new Parser()
const svga = await parser.load('xx.svga')

const player = new Player(document.getElementById('canvas'))
await player.mount(svga)

player.onStart = () => console.log('onStart')
player.onResume = () => console.log('onResume')
player.onPause = () => console.log('onPause')
player.onStop = () => console.log('onStop')
player.onProcess = () => console.log('onProcess', player.progress)
player.onEnd = () => console.log('onEnd')

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

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

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

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

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

// 销毁
// parser.destroy()
// player.destroy()

ParserConfigOptions

new Parser({
  // 是否取消使用 WebWorker,默认值 false
  isDisableWebWorker: false,

  // 是否取消使用 ImageBitmap 垫片,默认值 false
  isDisableImageBitmapShim: false
})

PlayerConfigOptions

const enum PLAYER_FILL_MODE {
  // 播放完成后停在首帧
  FORWARDS = 'forwards',
  // 播放完成后停在尾帧
  BACKWARDS = 'backwards'
}

const enum PLAYER_PLAY_MODE {
  // 顺序播放
  FORWARDS = 'forwards',
  // 倒序播放
  FALLBACKS = 'fallbacks'
}

new Player({
  // 播放动画的 Canvas 元素
  container?: HTMLCanvasElement

  // 循环次数,默认值 0(无限循环)
  loop?: number | boolean

  // 最后停留的目标模式,默认值 forwards
  // 类似于 https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode
  fillMode?: PLAYER_FILL_MODE

  // 播放模式,默认值 forwards
  playMode?: PLAYER_PLAY_MODE

  // 开始播放的帧数,默认值 0
  startFrame?: number

  // 结束播放的帧数,默认值 0
  endFrame?: number

  // 循环播放开始的帧数,可设置每次循环从中间开始。默认值 0,每次播放到 endFrame 后,跳转到此帧开始循环,若此值小于 startFrame 则不生效
  // 类似于 https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopStart
  loopStartFrame?: number

  // 是否开启缓存已播放过的帧数据,默认值 false
  // 开启后对已绘制的帧进行缓存,提升重复播放动画性能
  isCacheFrames?: boolean

  // 是否开启动画容器视窗检测,默认值 false
  // 开启后利用 Intersection Observer API 检测动画容器是否处于视窗内,若处于视窗外,停止描绘渲染帧避免造成资源消耗
  // https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API
  isUseIntersectionObserver?: boolean

  // 是否使用避免执行延迟,默认值 false
  // 开启后使用 `WebWorker` 确保动画按时执行(避免个别情况下浏览器延迟或停止执行动画任务)
  // https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API#Policies_in_place_to_aid_background_page_performance
  isOpenNoExecutionDelay?: boolean
})

替换元素 / 插入动态元素

可通过修改解析后的数据元,从而实现修改元素、插入动态元素功能

const svga = await parser.load('xx.svga')

// 替换元素
const image = new Image()
image.src = 'https://xxx.com/xxx.png'
svga.replaceElements['key'] = image

// 动态元素
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)
svga.dynamicElements['key'] = fontCanvas

await player.mount(svga)

DB

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

import { DB } from 'svga'

try {
  const url = 'xx.svga'
  const db = new DB()
  let svga = await db.find(url)
  if (!svga) {
    // Parser 需要配置取消使用 ImageBitmap 特性,ImageBitmap 数据无法直接存储到 DB 内
    const parser = new Parser({ isDisableImageBitmapShim: true })
    svga = await parser.load(url)
    await db.insert(url, svga)
  }
  await player.mount(svga)
} catch (error) {
  console.error(error)
}

TypeScript 声明 SVGA 文件

// global.d.ts
declare module '*.svga'

Webpack SVGA

SVGA 文件可用 url-loader 配置 Webpack 进行打包构建,例如:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.svga$/i,
        use: 'url-loader'
      }
    ]
  }
}

// js
import { Parser } from 'svga'
import xx from './xx.svga'
const parser = new Parser()
const svga = await parser.load(xx)

Vite SVGA

SVGA 文件可通过配置 Vite 作为 静态资源 打包构建,例如:

// vite.config.ts
export default defineConfig({
  assetsInclude: [
    'svga'
  ]
})

// js
import { Parser } from 'svga'
import xx from './xx.svga?url'
const parser = new Parser()
const svga = await parser.load(xx)

在 VSCode 编辑器预览 SVGA 文件,感谢 @ETTTTT 提供。

贡献

我们感谢社区提供错误修正和改进。

# 安装依赖
yarn install

# 开发 & 测试
yarn test

# 构建
yarn build

LICENSE

Apache License 2.0

svgaplayer-web-lite's People

Contributors

dependabot[bot] avatar lijialiang avatar matrixbirds avatar maxlee avatar naeemo avatar pedx avatar windyrain avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

svgaplayer-web-lite's Issues

Uncaught SyntaxError: Private field '#PARSER_V2_INLINE_WROKER' must be declared in an enclosing class

你好,想问下parser.ts里有两行代码
const INLINE_WORKER_FLAG = '#PARSER_V2_INLINE_WROKER#'
this.worker = new Worker(window.URL.createObjectURL(new Blob([INLINE_WORKER_FLAG])))
我这边在自己项目里跑了下会报Uncaught SyntaxError: Private field '#PARSER_V2_INLINE_WROKER' must be declared in an enclosing class这个错误,想问下初始化worker时传这个进去是为什么

vscode插件 svga perview

基于你这个轻量级的包,写了一个vscode插件,可以在vscode里面像看图片样看svga了,svga perview可以试试

iPhone7 iOS13.5.1 WKWebview high cpu

svga.lite is very nice💗 !
but in iPhone7 iOS13.5.1, it take too high cpu
I try do something below

  • setTimeout -> requestAnimationFrame
  • bind doFrame in constructor
  • judge loop by loop != 1 / 0 before now condition

but not work, I want some help ~

There is a cpu compare picture capture by instruments

  • without svga, average 2%
    image

  • with svga, average 20% ~ 30%
    image

here is my svga file: https://cdn.kaishuhezi.com/kstory/activity_flow/attachment/51f8c9b5-8b04-4d41-a0c6-4f446ddc63e0_info__s=37118.svga

图片剪裁不生效

clipPath没有绘制,导致图片剪裁没有生效,SVGAPlayer-Web和web-lite的效果不一致

SVGAPlayer-Web-Lite not work on ios 14.6 wkwebview

i found that on ios 14.6 version ,the wkwebview not working with SVGAPlayer-web-lite, which cant load the SVGA animation(no errors, not warnings, just dont show up). but on ios 14.7 it works good and some versions (such as ios 13.x, not fully test). Any solutions or reasons? thanks :)

使用DB报错

Cannot set properties of undefined (setting 'storeName')

二次播放失败问题

当第一次播放完毕之后,再点击start,没有任何动画效果,必须在第一次播放完触发end事件里执行player.stop(),第二次才能正常播放

How to configure nginx? 如何在 nginx 中配置以支持 svga 远程调用?

我尝试远程调用演示站上的 svga 文件,是可以正常使用的。

但是,我尝试调用我们自己服务器上的 svga 文件,无法正常使用。

我觉得应该是我的 nginx 配置没有做好,所以想请问一下,在 nginx 上要如何配置,才能支持 svga 文件的远程调用。


I try to call the SVGA file on the demo station remotely, which can be used normally.

However, I tried to call the SVGA file on our own server and it didn't work properly.

I think it should be my nginx configuration is not done well, so I would like to ask how to configure it on nginx to support the remote call of SVGA files.


My English is not good, the above English content for Google translation.

thinks

ts 文件 部分枚举类型未导出

enum FILL_MODE 枚举未导出,在使用该枚举类型是,导出的FILL_MODE 是个undefind, 需要本身声明这样一个枚举,建议完善一下代码

How to achieve adaptive width and height like svga-web ?

Hi~

When I migrated from svga-web to web-lite, I found that the element width and height cannot be adjusted?

First, the animation size of demo.svga is 400 * 400

In svga-web, used like this, it scales normally, showing as 200*200.

<div id="demoCanvas" style="width: 200px;height:200px;"></div>

var player = new SVGA.Player('#demoCanvas');
var parser = new SVGA.Parser('#demoCanvas');
parser.load('demo.svga', function(videoItem) {
    player.setVideoItem(videoItem);
    player.startAnimation();
})

In web-lite, below is the code I tried, but unfortunately it doesn't work.

<div id="demoCanvas" style="width: 200px;height:200px;">
    <canvas id="canvas" width="200" height="200"></canvas>
</div>

import { Parser, Player } from 'svga'

const parser = new Parser()
const svga = await parser.load('demo.svga')

const player = new Player(document.getElementById('canvas'))
await player.mount(svga)
player.start()

I noticed that the width of the canvas can be manipulated via svga.size.width , but there are many more svga.images sizes to adjust.
Of course, can use css scale(0.5) to do it, but it's not a good way.

How can I do it easily? Thanks for your help.

💐

setText and setImage

Hello, we would need to have the features setText and setImage from the legacy sdk, do you think it could be possible to achieve the same with the lite sdk?
Otherwise we would use the legacy sdk, but we didn't find a way to destroy the player.
Thanks

播放崩溃问题

  1. 在多段svga 大小不一 情况下,某段svga 在IOS下播放时 会是直接空白,在Android 上运行内存足够大 会正常播放

创建svga 播放代码
image

web 测试链接

  1. 请问是某段svga 过大会造成崩溃嘛

动画每次调用start都会闪动

我有一个角色 需要在两个动画间切换, 每次调用start的时候动画都会闪动一下, 衔接不顺畅。
即使已经在播放的动画 每次调用start时候都会闪动下;
我猜测这是每次 start, 都会重新初始化动画, 这会导致闪动...,

有没有可能已经初始化的动画在start的时候不要闪动, 顺滑的播放?

svga.d.ts needed!

svga.d.ts is needed in some developments, but i don't konw how to generate it ,so for expanding svga,could you provide one?

Cannot set properties of undefined (setting 'storeName')

I can use local file to paly svga animation, but when I use { DB } from 'svga', the error showed like this

image

here is my code: ( vue2 )

import {Parser, Player, DB} from 'svga'
import animation from './test.svga'

export default {
  name: "Mysvg",
  async mounted() {
    try {
      // const url = 'https://yun.tuisnake.com/h5-mami/pluginAct/takePack1/cai1.svga'
      const url = animation
      const db = DB()
      let svga = await db.find(url)
      if (!svga) {
        const parser = new Parser({ isDisableImageBitmapShim: true })
        svga = await parser.load(url)
        await db.insert(url, svga)
      }
      const player = new Player({
        // 播放动画的 Canvas 元素
        container:  document.getElementById('canvas'),

        // 循环次数,默认值 0(无限循环)
        loop:1,

        // 是否开启缓存已播放过的帧数据,默认值 false
        // 开启后对已绘制的帧进行缓存,提升重复播放动画性能
        isCacheFrames: true,
      })

      await player.mount(svga)

      // 开始播放动画
      player.start()
    } catch (error) {
      console.error(error)
    }
}

[Feature Request] Probably a switch between requestAnimationFrame and setTimeout

Most browsers stop sending requestAnimationFrame() callbacks to background tabs or hidden <iframe>s in order to improve performance and battery life.
from MDN Page Visibility API

However, there is some use cases we need the svga to keep on playing no matter what. For example, a countdown that has a svga playing as a visual notice, and rely on the svga's completion callback for later work.
Under these scenarios, setTimeout can do the job. Maybe there is anything else as a workround, please let me know.

If the feature seems useful, I can try to provide a PR 😬

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.