Small program technology sharing | small program integrated pixi rendering engine

When developing applets, canvas is required for some special scenarios, but when rendering some special effects on canvas, it consumes too much performance, causing the page to freeze and the display effect is not good (dragging freezes incoherently, etc.), so a rendering engine is used to meet the demand. This article uses the pixi rendering engine in the applet.

Introduce the modified pixi

Pixi does not match the applet very well, and needs to be modified accordingly before it can be used in the applet.
In this article, spine, animate, etc. are used, which can be saved in the same folder

Download address gitee warehouse

  • pixi-animate.js

  • pixi-spine.js

  • pixi.miniprogram.js

  • unsafeEval.js (necessary, involving some event conversion)

use

Add canvas to the page

   <canvas type="webgl" id="croplandCanvas" class="cropland_canvas" bindtouchstart="touchEvent" bindtouchmove="touchEvent" bindtouchend="touchEvent" bindtouchcancel="touchEvent"></canvas>
   <canvas type="2d" id="canvas2d" class="canvas_test"></canvas>
   <canvas type="2d" id="canvas2dText" class="canvas_test"></canvas>

Special effect realization

initial definition

/** pixi 相关 */
import {
    
    
    createPIXI
} from "../libs/pixi.miniprogram";
const unsafeEval = require("../libs/unsafeEval");
const installSpine = require("../libs/pixi-spine");
const installAnimate = require("../libs/pixi-animate");

// 动画定时器
let animationFrame= null;
// pixi 实例
let storePIXI = null;
// pixi 全局舞台容器
let pixiRenderer = null;
// canvas 容器实例
let canvasInstance = null;

pixi initialization

// 获取 canvas
wx.createSelectorQuery().select('#croplandCanvas').fields({
    
    
            node: true,
            size: true
        })
            .exec((res) => {
    
    
                const canvas = res[0].node;
                canvasInstance = canvas;
                // 设置canvas实际宽高
                canvas.width = 400;
                canvas.height = 800;
                 // 方便pixi定位
                 wx.createSelectorQuery().select('#canvas2d').fields({
    
    
                    node: true,
                    size: true
                }).exec(function (res2d) {
    
    
                    const canvas2d = res2d[0].node;
                    canvas2d.width = 16;
                    canvas2d.height = 16;
                    // 方便pixi定位
                    wx.createSelectorQuery().select('#canvas2dText').fields({
    
    
                        node: true,
                        size: true
                    }).exec(async function (res2dText) {
    
    
                        const canvas2dText = res2dText[0].node;
                        canvas2dText.width = 16;
                        canvas2dText.height = 16;
                      
                       /** 传入canvas,传入canvas宽度,用于计算触摸坐标比例适配触摸位置 */
                       // PIXI 初始化 -----start
                       storePIXI = createPIXI(canvas, 400, canvas2d, canvas2dText)

                       unsafeEval(storePIXI); //适配PIXI里面使用的eval函数
                       installSpine(storePIXI); //注入Spine库
                       installAnimate(storePIXI); //注入Animate库

                       // 通过view把小程序的canvas传入
                       pixiRenderer = Store.PIXI.autoDetectRenderer({
    
    
                           width: 400,
                           height: 800,
                           'transparent': true,
                           'view': canvas
                       });
                       // PIXI 初始化 -----end
                       
       
                       // PIXI 舞台+精灵(特效实现) -----start
                       /** 创建总舞台 */ 
                       const allStage = new Store.PIXI.Container();
                       // 舞台层级开关
                       allStage.sortableChildren = true;
                       
                       /** 例子:添加一个精灵图可拖拽 */
                        const bgStage = new storePIXI.Sprite.from(线上图片地址)
                        bgStage.sortableChildren = true;
                        
                        // 添加到总舞台
                        allStage.addChild(bgStage);
                       /** 对应事件触发 */
                        baseMapPIXIEvent(bgStage);
                       // PIXI 舞台+精灵(特效实现) -----end
                      
                       
                      // 视图渲染
                      function animate() {
    
    
                          pixiRenderer.render(allStage);
                          animationFrame = canvas.requestAnimationFrame(animate);
                      }
                      animate();
                    })

pixi event binding

// 小程序事件绑定至pixi
touchEvent(e) {
    
    
        storePIXI.dispatchEvent(e)
}

// pixi 事件处理
baseMapPIXIEvent(stage) {
    
    
  stage.on("touchstart", function (e) {
    
    
        const global = e.data.global;
        console.log("touchstart-开始移动", global);
  });
  stage.on("touchmove", function (e) {
    
    
        const global = e.data.global;
        console.log("touchstart-移动中", global);
  });
  stage.on("pointerup", function (e) {
    
    
        const global = e.data.global;
        console.log("touchstart-移动结束", global);
  });
  stage.on("pointertap", function (e) {
    
    
        const global = e.data.global;
        console.log("touchstart-点击", global);
  });
}

pixi destroyed

 allStage && allStage.destroy();
 animationFrame && canvasInstance.cancelAnimationFrame(animationFrame);
 pixiRenderer && pixiRenderer.destroy();

Notice

The image size should not exceed 300k

pixi can refer to the corresponding official website documents to realize the required special effects

insert image description here

Guess you like

Origin blog.csdn.net/anyRTC/article/details/131417114