UNPKG

11.5 kBMarkdownView Raw
1<img src="https://pag.art/img/readme/logo.png" alt="PAG Logo" width="474"/>
2
3[官网](https://pag.art) | [English](./README.md) | 简体中文 | [Weblite版本](./web/lite) | [小程序版本](./web/wechat) | [小程序lite版本](./web/lite/wechat)
4
5## 介绍
6
7libpag 是 PAG (Portable Animated Graphics) 动效文件的渲染 SDK,目前已覆盖几乎所有的主流平台,包括:iOS, Android, macOS,
8Windows, Linux, 以及 Web 端。
9
10## 特性
11
12- Web 平台能力适配,支持 libpag 全能力
13- 基于 WebAssembly + WebGL
14
15## 快速开始
16
17PAG Web 端,由 libpag.js + libpag.wasm 文件组成。
18
19### Browser(推荐)
20
21直接使用 `<script>` 引入,`libpag` 会被注册为一个全局变量
22
23对于生产环境我们推荐使用一个明确的版本号,以避免新版本带来不可预期的影响
24
25```html
26<script src="https://cdn.jsdelivr.net/npm/libpag@4.1.8/lib/libpag.min.js"></script>
27```
28
29你可以在公共 CDN [cdn.jsdelivr.net/npm/libpag/](https://cdn.jsdelivr.net/npm/libpag/) 浏览 NPM 包内的内容,同时你也可以使用 `@latest` 将版本指定为最新的稳定版。
30
31也可以使用其他同步 NPM 的公共 CDN 如 [unpkg](https://unpkg.com/libpag@latest/lib/libpag.min.js)
32
33```html
34<canvas class="canvas" id="pag"></canvas>
35<script src="https://cdn.jsdelivr.net/npm/libpag@latest/lib/libpag.min.js"></script>
36<script>
37 window.onload = async () => {
38 // 实例化 PAG
39 const PAG = await window.libpag.PAGInit();
40 // 获取 PAG 素材数据
41 const buffer = await fetch('https://pag.art/file/like.pag').then((response) => response.arrayBuffer());
42 // 加载 PAG 素材为 PAGFile 对象
43 const pagFile = await PAG.PAGFile.load(buffer);
44 // 将画布尺寸设置为 PAGFile的尺寸
45 const canvas = document.getElementById('pag');
46 canvas.width = pagFile.width();
47 canvas.height = pagFile.height();
48 // 实例化 PAGView 对象
49 const pagView = await PAG.PAGView.init(pagFile, canvas);
50 // 播放 PAGView
51 await pagView.play();
52 };
53</script>
54```
55
56调用 libpag.js 上的 `PAGInit()` 方法时,默认会加载 libpag.js 同一目录下的 libpag.wasm 文件。如果你希望把 libpag.wasm 放在其他目录下,则可以使用 `locateFile` 将 libpag.wasm 的路径返回给 `PAGInit()` 方法。如下
57
58```js
59const PAG = await window.libpag.PAGInit({
60 locateFile: () => {
61 if (location.host === 'dev.pag.art') {
62 // development environment
63 return 'https://dev.pag.art/file/libpag.wasm';
64 } else {
65 // production environment
66 return 'https://pag.art/file/libpag.wasm';
67 }
68 },
69});
70```
71
72### EsModule
73
74```bash
75$ npm i libpag
76```
77
78```js
79import { PAGInit } from 'libpag';
80
81PAGInit().then((PAG) => {
82 // 实例化 PAG
83});
84```
85
86**使用 ESModule 引入的方式需要注意,像 Webpack 和 Rollup 等打包工具是默认没有打包 .wasm 文件的。也就是说如果你的项目时 Vue / React 这类使用脚手架构建的项目需要把 node_modules 下的 libpag/lib/libpag.wasm 文件打包到最终产物中,并且使用 `locateFile` 钩子返回 libpag.wasm 文件的路径,这样才能确保在网络请求中能加载到 libpag.wasm 文件**
87
88npm package 中提供了多种构建产物,可以阅读 [这里](./doc/develop-install.md) 了解不同目录下产物的差别。
89
90Demo 项目提 [pag-web](https://github.com/libpag/pag-web) 供了简单的接入示例和 Vue / React / PixiJS 等配置示例, 可以点击 [这里](https://github.com/libpag/pag-web) 查看。
91
92更多的 API 接口可以阅读 [API 文档](https://pag.art/api.html#/apis/web/)。
93
94## 浏览器兼容性
95
96| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Chrome for Android | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Safari on iOS | QQ Browser Mobile |
97| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ----------------- |
98| Chrome >= 69 | Safari >= 11.3 | Android >= 7.0 | iOS >= 11.3 | last 2 versions |
99
100更多版本的兼容工作正在进行中
101
102**以上的兼容表仅代表可以运行的兼容性。对于有移动端接入需要的用户,需要阅读一下这篇[兼容性情况](./doc/compatibility.md)的文章**
103
104## 使用指南
105
106### 垃圾回收
107
108因为 libpag 基于 WebAssembly 做跨端应用,所以从 WebAssembly 中取出来的对象,基本都是 C++ 的指针,所以 JavaScript 的 GC 是无法释放这一部分内存的。所以,当不需要使用 libpag 产生的对象时,需要调用对象上的 destroy 方法将其释放掉。
109
110### 渲染相关
111
112#### 首帧渲染
113
114`PAGView.init` 默认会进行首帧渲染,如不需要可以在 `PAGView.init` 的第三个参数传入 `{ firstFrame: false }` 取消首帧渲染。
115
116在进行首帧渲染的过程中,当 PAG 动画文件中存在 BMP 预合成(下文说明如何确认 PAG 文件是否存在 BMP 预合成)时,会调用 VideoReader 模块。
117
118因为 VideoReader 模块在 Web 平台依赖于 VideoElement,所以在部分移动端场景下,PAGView.init 不是在用户交互产生的调用链中,可能会存在不允许播放导致无法正常渲染画面的问题。
119
120当出现这种情况,我们推荐使用 `PAGView.init(pagFile, canvas, { firstFrame: false }) ` 提前初始化 PAGView 并且取消首帧渲染,然后在用户交互产生的调用链中再调用 `pagView.play()` 进行画面渲染。
121
122#### PAG 渲染尺寸
123
124在 Web 平台上,设备像素分辨率与 CSS 像素分辨率是不同的,而它们之比被称为 `devicePixelRatio`。所以当我们需要显示 CSS 像素 1px 时, 需要 1px \* `devicePixelRatio` 的渲染尺寸。
125
126PAG 默认会对 Canvas 在屏幕中的可视尺寸进行缩放计算后进行渲染,因此会对 Canvas 的宽高以及 `style` 产生副作用。如果希望 PAG 不对 Canvas 产生副作用, 可以在 `PAGView.init` 的第三个参数传入 `{ useScale: false }` 来取消缩放。
127
128#### PAGView 尺寸过大
129
130为了高清的渲染效果,PAGView 默认会按照 Canvas 尺寸 \* `devicePixelRatio` 作为实际渲染尺寸。
131受设备自身性能影响 WebGL 的最大渲染尺寸可能各不相同。会出现渲染尺寸过大导致白屏的情况。
132
133建议移动端下,实际渲染尺寸不大于 2560px。
134
135#### 多个 PAGView 实例场景
136
137首先,因为 PAG Web 版是单线程的 SDK,所以我们不建议**同屏播放多个 PAGView**
138
139对于有多个 PAGView 实例的场景,我们需要先知道,浏览器环境中 WebGL 活跃的 context 数量是有限制的,Chrome 是 16 个,Safari 是 8 个。因为有这个限制存在,我们应当及时使用 `destroy` 回收无用的 PAGView 实例和移除 Canvas 的引用。
140
141以下是特殊场景的解决方法,不推荐使用:
142
143如果你需要在 Chrome 浏览器中同屏存在多个 PAGView 实例且不需要在 Safari 上使用,可以尝试使用 canvas2D 模式,需要在 `PAGView.init` 的时候传入 `{ useCanvas2D: true }` 。这个模式下,会用一个 WebGL 当作渲染器,然后往多个 canvas2D 分发画面,从而规避 WebGL 活跃 context 数量的限制。
144
145因为 Safari 上 [`CanvasRenderingContext2D.drawImage()`](https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/drawImage) 的性能很差,所以我们不推荐在 Safari 上使用这个模式。
146
147#### 注册解码器
148
149对于“用户与页面交互之后才可以使用 Video 标签进行视频播放”规则的限制,PAG Web 版提供软件解码器注入接口 ` PAG.registerSoftwareDecoderFactory()`
150
151注入软件解码器后,PAG 会调度软件解码器去对 BMP 预合成进行解码与上屏,从而实现部分平台进入页面自动播放的功能。
152
153推荐解码器接入:https://github.com/libpag/ffavc/tree/main/web
154
155已知“用户与页面交互之后才可以使用 Video 标签进行视频播放”限制的平台有:移动端微信浏览器,iPhone 省电模式,部分 Android 浏览器。
156
157## 关于 BMP 预合成
158
159可以下载 [PAGViewer](https://pag.art/docs/install.html) 打开 PAG 文件,点击"视图"->"显示 编辑面板",在编辑面板中我们能看到 Video 的数量,当 Video数量大于 0 时,即为 PAG 动画文件中存在 BMP 预合成。
160
161## Roadmap
162
163Web SDK 未来能力支持规划可以点击 [这里](https://github.com/Tencent/libpag/wiki/PAG-Web-roadmap) 查看
164
165## 参与开发
166
167### 前置工作
168
169需要确保已经可编译 C++ libpag 库,并且安装 [Emscripten 套件](https://emscripten.org/docs/getting_started/downloads.html) 和 Node 依赖
170
171```bash
172# 安装Node依赖
173$ npm install
174```
175
176### 开发流程
177
178执行 `build.sh debug` 来获得 `libpag.wasm` 文件
179
180```bash
181# web/script目录下
182$ cd script
183# 添加执行权限
184$ chmod +x ./build.sh
185# 打包
186$ ./build.sh debug
187```
188
189打包 Typescript 文件,修改 Typescript 文件会自动打包到 Javascript 文件
190
191```bash
192# web目录下
193$ npm run dev
194```
195
196启动 HTTP 服务
197
198```bash
199# web目录下
200$ npm run server
201```
202
203Chrome 浏览器打开 `http://localhost:8081/demo/index.html` 即可看到效果
204
205需要断点调试时,可以安装 [C/C++ DevTools Support (DWARF)](https://chrome.google.com/webstore/detail/cc%20%20-devtools-support-dwa/pdcpmagijalfljmkmjngeonclgbbannb),并打开 Chrome DevTools > 设置 > 实验 > 勾选「WebAssembly Debugging: Enable DWARF support」选项启用 SourceMap 支持。现在就可以在 Chrome DevTools 中对 C++ 文件进行断点调试了。
206
207#### 注意点
208
209在使用 `build.sh` 编译 `libpag.wasm` 时,因为 `emscripten` 与系统的 std 库有兼容问题,所以屏蔽了 undefined symbols 报错。
210
211```shell
212# build.sh
213emcc -s ERROR_ON_UNDEFINED_SYMBOLS=0
214```
215
216编译过程中需要留意是否有std库兼容外的 warning 信息,避免 undefined symbols 的错误在运行时才暴露出来。
217
218### 生产流程
219
220执行 `build.sh` 脚本
221
222```bash
223# web/script目录下
224$ cd script
225# 添加执行权限
226$ chmod +x ./build.sh
227# 打包
228$ ./build.sh
229```
230
231### CLion 编译
232
233创建一个新的 profile,然后使用下面的 **CMake options**(位置在 **CLion** > **Preferences** > **Build, Execution, Deployment** > **CMake**
234
235```
236-DCMAKE_TOOLCHAIN_FILE=path/to/emscripten/emscripten/version/cmake/Modules/Platform/Emscripten.cmake
237```
238
239### 测试流程
240
241打包生产版本
242
243```bash
244$ cd script & ./build.sh
245```
246
247启动测试 HTTP 服务
248
249```bash
250$ npm run server
251```
252
253启动 cypress 测试
254
255```bash
256$ npm run test
257```