uniapp H5开发PAG 预览
需求
如图,在uniapp H5 开发中需要实现Pag 预览
实现
引入js文件
需引入以下文件 libpag.min.js libpag.umd.js libpag.wasm libpag.worker.esm.js player.jsJS代码async initPagEffect() { // 等待DOM完全渲染 await this.$nextTick(); await new Promise(resolve => setTimeout(resolve, 200)); // 仅在需要加载PAG时初始化libpag(优化性能) let PAG = null; if (this.userList.some(item => { const goodsIds = item.goodsIds; let max = 0; if (Array.isArray(goodsIds) && goodsIds.length > 0) { const valid = goodsIds.map(Number).filter(num => !isNaN(num)); max = valid.length > 0 ? Math.max(...valid) : 0; } return max !== 0 && max !== 420; })) { PAG = await window.libpag.PAGInit({ useCanvas2D: false }); } for (let index = 0; index < this.userList.length; index++) { // 1. 计算当前用户的maxGoodsId let goodsIds = this.userList[index].goodsIds; let maxGoodsId = 0; if (Array.isArray(goodsIds) && goodsIds.length > 0) { const validNumArr = goodsIds.map(item => Number(item)).filter(num => !isNaN(num)); maxGoodsId = validNumArr.length > 0 ? Math.max(...validNumArr) : 0; } console.log(`索引${index}:goodsIds最大值 = ${maxGoodsId}`); // 无有效goodsId则跳过 if (maxGoodsId === 0) { continue; } // 2. 获取容器并清空(统一逻辑) const canvasContainer = document.querySelector(`.u-pag-${index}`); if (!canvasContainer) { console.error(`索引${index}:未找到.u-pag-${index}容器`); continue; } canvasContainer.innerHTML = ''; // 清空旧内容 // 3. 分支处理:420显示图片,其他加载PAG if (maxGoodsId === 420 || maxGoodsId == 440) { // ====== 分支1:maxGoodsId=420 → 创建img元素显示图片 ====== const imgEl = document.createElement('img'); imgEl.className = 'display'; imgEl.id = `pag-canvas-${index}`; // 保持ID统一,方便定位 // 从pag_goods_id获取图片地址 imgEl.src = this.pag_goods_id[maxGoodsId]; // 设置和canvas一致的样式,保证视觉统一 imgEl.style.width = '116px';; imgEl.style.height = '32px'; imgEl.style.display = 'block'; imgEl.style.backgroundColor = 'transparent'; imgEl.style.objectFit = 'contain'; // 防止图片拉伸 // 插入图片到容器 canvasContainer.appendChild(imgEl); console.log(`索引${index}:加载图片成功(420)`); } else { // ====== 分支2:maxGoodsId≠420 → 创建canvas加载PAG ====== // 创建canvas元素 const canvasEl = document.createElement('canvas'); canvasEl.className = 'display'; canvasEl.id = `pag-canvas-${index}`; canvasEl.width = 116; // 原生宽高(px) canvasEl.height = 32; // 样式和图片保持一致 canvasEl.style.width = '116px'; canvasEl.style.height = '32px'; canvasEl.style.display = 'block'; canvasEl.style.backgroundColor = 'transparent'; // 插入canvas到容器 canvasContainer.appendChild(canvasEl); // 获取canvas并加载PAG const canvas = document.getElementById(`pag-canvas-${index}`); if (!canvas) { console.error(`索引${index}:canvas创建失败`); continue; } try { // 从pag_goods_id获取对应PAG地址 const pagUrl = this.pag_goods_id[maxGoodsId]; const res = await fetch(pagUrl); if (!res.ok) throw new Error(`PAG请求失败:${res.status}`); const buffer = await res.arrayBuffer(); const pagFile = await PAG.PAGFile.load(buffer); const pagView = await PAG.PAGView.init(pagFile, canvas); pagView.setRepeatCount(0); // 无限循环 await pagView.play(); console.log(`索引${index}:PAG播放成功(${maxGoodsId})`); } catch (err) { console.error(`索引${index}:PAG播放失败(${maxGoodsId})`, err); } } } }步骤
我的需求中需要在该元素下实现PAG预览,同时当循环得到的 goodId值为指定值时显示指定图片 1、初始化 PAG PAG = await window.libpag.PAGInit({useCanvas2D: false}); 注意:useCanvas2D 必须为False 2、找到页面中定义的 class 元素,我的如下: const canvasContainer = document.querySelector(`.u-pag-${index}`); 3、 创建canvas元素, const canvasEl = document.createElement('canvas'); canvasEl.className = 'display'; canvasEl.id = `pag-canvas-${index}`; canvasEl.width = 116; // 原生宽高(px) canvasEl.height = 32; // 样式和图片保持一致 canvasEl.style.width = '116px'; canvasEl.style.height = '32px'; canvasEl.style.display = 'block'; canvasEl.style.backgroundColor = 'transparent'; // 插入canvas到容器 canvasContainer.appendChild(canvasEl); 注意:canvas 必须JS动态创建,不可在页面中使用 uniapp 的 canvas 4、 获取canvas并加载PAG const canvas = document.getElementById(`pag-canvas-${index}`); try { // 从pag_goods_id获取对应PAG地址 const pagUrl = this.pag_goods_id[maxGoodsId]; const res = await fetch(pagUrl); if (!res.ok) throw new Error(`PAG请求失败:${res.status}`); const buffer = await res.arrayBuffer(); const pagFile = await PAG.PAGFile.load(buffer); const pagView = await PAG.PAGView.init(pagFile, canvas); pagView.setRepeatCount(0); // 无限循环 await pagView.play(); console.log(`索引${index}:PAG播放成功(${maxGoodsId})`); } catch (err) { console.error(`索引${index}:PAG播放失败(${maxGoodsId})`, err); }
注意
不使用
uniapp中的canvas问题:uniapp会在渲染完成之后将你的canvas 改成 <uni-canvas> 类似这种的元素,然后再在它的里面包一层 <canvas> 且包的那层canvas 没有指定 唯一 ID, 故当需要预览多个PAG时,无法指定 canvas