导言
苦恼于前端动画不够复杂,老大去b站逛了下,找了好几个动画解决方案,有svg和pag以及其他什么来着,一眼就看中了PAG,因为三个字母很短,也有腾讯背书,想必会好使一点吧?蛮记录一下,有刚好看到本文章并且有意见的老哥希望可以留言让我改进一下。
一.什么是PAG
PAG是一套完整的动效工作流解决方案,目标是降低或消除动效相关的研发成本,能够一键将设计师在AE中制作的动效内容导出成素材文件,并快速上线应用于几平所有的主流平台。
关于PAG在掘金已经有很多文章说明了,其中包括优缺点以及框架源码等。这边简单记录一下第一次使用PAG的流程
二.使用
安装libpag插件
npm i libpag
vue2.xx安装rollup-plugin-copy插件并配置(已经安装的可以省略)
npm i rollup-plugin-copy
然后在build的webpack.dev.conf配置
...
plugins: [
...
// copy custom static assets
new CopyWebpackPlugin([
...
{
from: path.resolve(__dirname, '../node_modules/libpag/lib/libpag.wasm'),
to: config.build.assetsPublicPath,
}
])
]
...
然后在build的webpack.prod.conf配置
...
plugins:[
...
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../node_modules/libpag/lib/libpag.wasm'),
to: config.build.assetsSubDirectory,
},
])
]
vue3.xx rollup-plugin-copy的配置
const path = require('path');
const config = require('./config');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
configureWebpack: {
entry: {
app: './src/main.js',
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
},
plugins: [
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, './node_modules/libpag/lib/libpag.wasm'),
to: config.build.assetsPublicPath,
},
]),
],
},
publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
};
使用前封装一下
import { PAGInit } from 'libpag'
// pag文件(支持本地相对路径), canvas 的id名,播放次数
const initPag2 = async (url, id, num=0) => {
PAGInit().then((PAG) => {
fetch(url)
.then((response) => response.blob())
.then(async (blob) => {
const file = new window.File([blob], url.replace(/(.*\/)*([^.]+)/i, '$2'));
const pagFile = await PAG.PAGFile.load(file);
document.getElementById(id).width = pagFile.width();
document.getElementById(id).height = pagFile.height();
const pagView = await PAG.PAGView.init(pagFile,`#${id}`);
//循环次数
pagView.setRepeatCount(num);
await pagView.play();
});
});
}
export default initPag2
使用封装的方法:这里的url似乎不能填写相对路径,填写网络路径是没问题的,比如pag.art/file/like.p…
<template>
<div id="container">
<canvas class="canvas" id="pag"></canvas>
</div>
</template>
<script>
import initPag from '@/utils/pagInit.js'
export default {
name: "pagTest",
mounted() {
initPag('./static/testHtml/test1.pag', 'pag')
},
methods: {
},
};
</script>
<style scoped>
#container {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
也可以在index.html直接引入,无需其他配置
<script src="https://cdn.jsdelivr.net/npm/libpag@latest/lib/libpag.min.js"></script>
然后封装一下
export const initPag = async (url, id, num=0) => {
// 实例化 PAG
const PAG = await window.libpag.PAGInit()
// 获取 PAG 素材数据
// https://pag.art/file/like.pag
const buffer = await fetch(url).then((response) => {
console.log(response);
return response.arrayBuffer()
}
)
// 加载 PAG 素材为 PAGFile 对象
const pagFile = await PAG.PAGFile.load(buffer)
// 将画布尺寸设置为 PAGFile的尺寸
const canvas = document.getElementById(id)
canvas.width = pagFile.width()
canvas.height = pagFile.height()
// 实例化 PAGView 对象
const pagView = await PAG.PAGView.init(pagFile, canvas)
// 循环播放
pagView.setRepeatCount(num)
await pagView.play()
}