web端腾讯PAG初体验
Portable Animated Graphics 是一套完整的动画工作流解决方案。提供从 AE (Adobe After Effects) 导出插件,到桌面预览工具,再到覆盖 iOS,Android,macOS,Windows,Linux 和 Web 等各平台的渲染 SDK。PAG 的目标是降低或消除动画研发相关的成本,打通设计师创作到素材上线的自动化流程。.........
PAG介绍
Portable Animated Graphics 是一套完整的动画工作流解决方案。提供从 AE (Adobe After Effects) 导出插件,到桌面预览工具,再到覆盖 iOS,Android,macOS,Windows,Linux 和 Web 等各平台的渲染 SDK。
PAG 的目标是降低或消除动画研发相关的成本,打通设计师创作到
素材上线的自动化流程,不断输出运行时可编辑的高质量动画内容。
前情提要
公司移动端接入PAG去实现模版视频,产品一看不错嘛,web端也上!这样就有了接触的机会,PAG对接了许多桌面端的场景,目前web端项目刚起步,还不够成熟,不过影响我们学习使用,这里就给大家分享一下调试的坑与经验~~~
目前web端主要功能还是展示.pag
文件,通过canvas展示动图效果或者视频效果,项目是 react18
做的pc与移动端官网。
实战
PAG-web文档
目前接入方式分为两种,Browser script直接引用、ESModule。下面分别介绍一下
Browser script
官方目前推荐这种方式,直接复制文档代码即可文档
说几个官方文档的问题点
- 微信端无法播放,可以使用视频解码器去解决,但很耗费性能,移动端同页面多个的情况下会卡,或者建议设计师使用矢量导出。
- 官网使用unpkg cdn,可能被墙,所以上线项目要锁版本,并且换国内三方cdn或者放在自己服务器上
PAGInit()初始化的时候,默认会加载 libpag.js 同一目录下的 libpag.wasm 文件,所以除了.js文件,还要把其他文件下载下来放在同一目录。libpag为PAG SDK,ffavc为解码器代码。
完整demo
这个可以拿来直接用,通过iframe接入现有项目,不受技术栈的限制!!!
// 父页面 jsx
<iframe
style={{ width: '100%', border: '0px', height: '100%' }}
src='https://xxxx/pag.html'
onLoad={(e)=>{
const Iframe = e.target,
iframeWindow= (Iframe.contentWindow || Iframe.contentDocument)
iframeWindow.postMessage(pagsrc, '*') // 解决iframe跨域通信问题
}}
></iframe>
<!-- 子页面 pag.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
#pag{
width: 100%;height: 100%;
}
</style>
</head>
<body>
<canvas id="pag"></canvas>
<script src="https://xxxx/libpag.min.js"></script>
<script src="https://xxxx/ffavc.min.js"></script>
<script>
async function showUrl(e){
const url = e.data
// 实例化 PAG
const PAG = await window.libpag.PAGInit();
// 解码器
const FFAVC = await window.ffavc.FFAVCInit();
const ffavcDecoderFactory = new FFAVC.FFAVCDecoderFactory();
PAG.registerSoftwareDecoderFactory(ffavcDecoderFactory);
// 获取 PAG 素材数据
const buffer = await fetch(url).then(
(response) => response.arrayBuffer()
);
// 加载 PAG 素材为 PAGFile 对象
const pagFile = await PAG.PAGFile.load(buffer);
// 将画布尺寸设置为 PAGFile的尺寸
const canvas = document.getElementById("pag");
canvas.width = pagFile.width();
canvas.height = pagFile.height();
// 实例化 PAGView 对象
const pagView = await PAG.PAGView.init(pagFile, canvas);
pagView.setRepeatCount(0);
// 播放 PAGView
await pagView.play();
}
// iframe通信机制
window.addEventListener("message", showUrl, false);
</script>
</body>
</html>
ES Module
官方文档不完整,并且没有接入视频解码器ffavc,我是去看的github示例。
需要注意的点
- 使用 ESModule 引入的方式需要注意,像 Webpack 和 Rollup 等打包工具是默认没有打包 .wasm 文件的。
两种解决方式
配置webpack,将.wasm文件打包到dist目录下。
初始化的时候传入locateFile参数,将文件地址传入。
PAGInit({ locateFile: (file) => “https://pag.io/file/” + file, });
配置webpack
官网提供的是通过react-app-rewired配置的webpack,因为我已经eject暴露了配置文件,直接在webpack.config.js配置了,总体意思大差不差就是让程序找到./static/js/.wasm文件
npm i copy-webpack-plugin --save-dev
// 官网配置方式,eject就不用下载了
npm i react-app-rewired --save-dev
// webpack.config.js
const CopyWebpackPlugin = require('copy-webpack-plugin');
// plugin
plugins: [
new CopyWebpackPlugin({
patterns: [
{ from: path.resolve(__dirname, '../node_modules/libpag/lib/libpag.wasm'), to: './static/js/' },
{ from: path.resolve(__dirname, '../node_modules/ffavc/lib/ffavc.wasm'), to: './static/js/' }
],
}),
...other
]
完整demo
npm i libpag
// ffavc非必须根据是否需要解码器自选
npm i ffavc
import React, {useEffect, useRef} from 'react'
import { PAGInit } from "libpag";
import { FFAVCInit } from 'ffavc';
export default function Pag(props) {
const canvasEl = useRef(null)
useEffect(() => {
FFAVCInit().then((FFAVC) => {
PAGInit().then((PAG) => {
const ffavcDecoderFactory = new FFAVC.FFAVCDecoderFactory();
PAG.registerSoftwareDecoderFactory(ffavcDecoderFactory);
const url = props.src;
fetch(url)
.then((response) => response.arrayBuffer())
.then(async (buffer) => {
const pagFile = await PAG.PAGFile.load(buffer);
const canvas = canvasEl.current;
canvas.width = pagFile.width();
canvas.height = pagFile.height();
const pagView = await PAG.PAGView.init(pagFile, canvas);
pagView.setRepeatCount(0);
await pagView.play();
});
});
})
},[]);
return (
<canvas ref={canvasEl} style={{height:'100%',width:'100%'}}></canvas>
)
}
需要注意的是,官方示例用的"react": "^17.0.2"
,react18 严格模式下(<React.StrictMode>) useEffect会执行两遍,动画初始化两遍会错乱。
结语
目前效果 pc端 > 移动端浏览器 > 移动端微信浏览器,首次加载会有些慢,项目进一步优化点在 ffavc软件解码器 与 多个PAGView实例场景
更多推荐
所有评论(0)