uniapp H5开发PAG 预览

xiao
xiao

uniapp H5开发PAG 预览

需求

   如图,在uniapp H5 开发中需要实现Pag 预览

图片描述

实现

  • 引入js文件

     需引入以下文件
      libpag.min.js   
      libpag.umd.js  
      libpag.wasm  
      libpag.worker.esm.js   player.js
  • JS 代码

        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 
Copyright

原创 本文由 xiao 发布于 xiao

原文链接:https://blog.joniding.com/index.php/archives/65/

许可协议CC BY-NC-ND 4.0署名-非商业性使用-禁止演绎 4.0 国际

发表评论