在微信小程序里跑起 PIXI.js:一份从第一帧到交互画面的完整实战指南

📅 2026/8/22 19:46:02
在微信小程序里跑起 PIXI.js:一份从第一帧到交互画面的完整实战指南
在微信小程序里跑起 PIXI.js一份从第一帧到交互画面的完整实战指南【免费下载链接】pixi-miniprogram一个可运行于微信小程序的PIXI引擎通过模拟window环境有些功能小程序无法模拟就直接修改了PIXI引擎代码最终使得PIXI引擎正常运行在小程序上项目地址: https://gitcode.com/gh_mirrors/pi/pixi-miniprogram在微信小程序里用 PIXI.jsPIXI.js 小程序适配器 pixi-miniprogram 是最直接的路子小程序运行时没有 window、没有 document也没有 eval引擎面向浏览器做的假设在启动瞬间就会失效。这个项目在小程序内模拟出一整套浏览器环境凡是小程序实在模拟不了的环节就直接改引擎源码让 WebGL 画布能稳定出帧。下面从拿到仓库代码一路讲到带触摸交互的画面。三分钟把适配器接进小程序它能做的事把源码变成一个小程序可以直接引入的文件。拿代码并本地编译git clone https://gitcode.com/gh_mirrors/pi/pixi-miniprogram cd pixi-miniprogram npm install npm run build编译结束后把根目录dist下的产物pixi.miniprogram.js拷进你小程序项目的libs/文件夹在页面 wxml 里声明渲染画布type必须写webglcanvas typewebgl idgameCanvas/canvas白话说webpack 把改造过的引擎打包成单文件小程序端只需要引用这一个文件其余都不用管。⚡ 跑通第一帧canvas、renderer 与 stage先认三个角色renderer 是负责把场景画进画布的画手stage 是场景的根容器你要画的一切都挂在它下面canvas 的宽高是物理像素750 的设计宽度则是自定义坐标系这样不同机型上布局与触摸都不会错位。import {createPIXI} from ../../libs/pixi.miniprogram const patchEval require(../../libs/unsafeEval) const attachSpine require(../../libs/pixi-spine) const myTween require(../../libs/myTween) let PIXI这段把四个依赖拉进来第一个负责搭好虚拟环境并返回引擎对象patchEval 顶替小程序里不可用的 eval剩下两个分别为骨骼动画和缓动做准备。const {screenWidth, screenHeight} wx.getSystemInfoSync() const designW 750 const designH Math.round(designW * screenHeight / screenWidth) wx.createSelectorQuery().select(#gameCanvas).node().exec(([r]) { const canvas r.node canvas.width screenWidth canvas.height screenHeight PIXI createPIXI(canvas, designW) patchEval(PIXI) attachSpine(PIXI) })白话说取出 canvas 节点把它拉伸成全屏物理尺寸再连同设计宽度一起交给 createPIXI拿到适配后的引擎随后两次 patch 分别补齐 eval 缺口与 Spine 能力。const renderer PIXI.autoDetectRenderer({ view: canvas, width: designW, height: designH, backgroundAlpha: 1, premultipliedAlpha: true, preserveDrawingBuffer: true }) const stage new PIXI.Container() const hero PIXI.Sprite.from(img/hero.png) stage.addChild(hero) function loop() { canvas.requestAnimationFrame(loop) renderer.render(stage) } loop()白话说view: canvas这一项把小程序画布直接接成渲染目标循环里每帧调一次 render若用了 myTween记得在 render 前多调一行 myTween.update()。跑到这里精灵已经上屏——第一帧完成。 往舞台上放东西精灵、文本、图形与补间动画精灵是最常用的对象浏览器里能画的图这里同样能画。const label new PIXI.Text(HP 100, {fill: #ff5533, fontSize: 40}) label.y 80 stage.addChild(label) const panel new PIXI.Graphics() panel.beginFill(0x2244ff) panel.drawRoundedRect(40, 140, 220, 90, 12) panel.endFill() stage.addChild(panel)这段往舞台里放了动态文本和一个圆角矩形面板改 text 属性能实时刷新文案Graphics 适合临时绘制形状。帧动画则把一串纹理排好交给 AnimatedSprite 再调用 playconst frames [] for (let i 1; i 8; i) frames.push(PIXI.Texture.from(img/run i .png)) const runner new PIXI.AnimatedSprite(frames) runner.animationSpeed 0.2 runner.play() stage.addChild(runner)补间交给内置的 myTween 缓动库Quad、Back、Bounce 等曲线都有只需给出目标对象和结束时的属性值myTween.to(hero, 1.2, { y: 600, ease: myTween.Quad.Out, onEnd: () myTween.to(hero, 1.2, {y: 0, ease: myTween.Back.Out}) })让画布听话触摸事件透传流程它能做的事把小程序的触摸回调翻译成引擎认得的指针事件。小程序触摸不走浏览器事件系统必须手动喂进去——wxml 里绑好四种触摸js 里统一转发canvas typewebgl idgameCanvas bindtouchstartonTouch bindtouchmoveonTouch bindtouchendonTouch bindtouchcancelonTouch /onTouch(evt) { PIXI.dispatchEvent(evt) }白话说createPIXI 的第二个参数 designW 就是为它准备的——引擎按设计宽度 / 物理宽度的比例把触摸的 x/y 换算成标准客户端坐标再压进虚拟窗口的事件队列。此后把eventMode设为static的对象就能收到指针按下、抬起事件。遇到点了屏幕引擎没反应按这个顺序查canvas 是否绑全了四种触摸处理函数里有没有真正调用转发目标对象是否设置了 eventMode资源加载与进阶能力Spine、Animate、遮罩小程序的文件系统读不到本地 fnt / json这两类文件必须放到服务器用网络地址引用PIXI.Assets.add(scoreFont, https://cdn.example.com/score.fnt) PIXI.Assets.add(heroSkel, https://cdn.example.com/hero.json) PIXI.Assets.load([scoreFont, heroSkel]).then((res) { const skel new PIXI.spine.Spine(res.heroSkel.spineData) skel.state.setAnimation(0, idle, true) stage.addChild(skel) })白话说先用 add 登记网络资源再用 load 批量加载回调里拿到解析好的数据骨骼动画直接交给 Spine 运行时驱动不用自己写插值。其余可以点亮的能力Spine初始化时调用注入函数即可骨骼动画随用随取示例目录里还备有适配 3.8 运行时的 pixi-spine-3.8 文件Animate同样注入引擎后Adobe Animate 导出的片段可以直接上舞台遮罩WebGL 的原生遮罩不直接可用示例用 shader 实现——把目标颜色与遮罩颜色逐像素相乘遮罩形状要画成白色才不会给目标染色Live2D 与音频较新的构建已加入这两项对应的注入脚本都在示例目录的 libs 里。遮罩的核心只是给白色形状生成纹理再挂到目标对象上const maskShape new PIXI.Graphics() maskShape.beginFill(0xffffff) maskShape.drawCircle(100, 100, 100) maskShape.endFill() const maskTex renderer.generateTexture(maskShape) panel.filters [new PIXI.Filter(null, frag, {maskTex, dimensions: [200, 200]})]完整的片元着色器文本在示例代码里照搬后替换 maskTex、dimensions 两个 uniform 即可。⚠️ 避坑清单版本兼容与已知限制基础库版本当前构建依赖新版离屏画布接口基础库版本需达到 2.16.1 以上若用户还在老版本基础库上改用 v1.0 产物届时 createPIXI 要多传两个 2d canvas一个供 Graphics 渲染、一个供 Text 渲染视频不支持引擎模拟不了视频元素直播流、视频类素材别指望引擎不挂全局适配后的引擎只存在于 createPIXI 的返回值里凡是期望全局 PIXI 的第三方配套库都得显式把引擎对象传进去上面的 Spine / Animate 注入就是这么干的fnt / json本地文件读不到必须走网络所以上面的资源加载才全部用 URL截图renderer 里的 preserveDrawingBuffer 选项就是为此保留的它让帧缓冲在渲染后不清空才能用 toDataURL 取到当前画面。下一步看哪个示例、去哪提问题 用微信开发者工具直接打开仓库里的 example 目录示例工程运行一遍本文出现的帧动画、遮罩、补间、触摸转发都在其中值得通读一次想改行为时入口在 src 目录window.js 是虚拟环境的搭建处touchEvent.js 负责触摸坐标换算README 顶部维护了完整更新日志背景透明、Graphics 显示异常等修复都标了日期升级前先看一眼遇到解不了的 bug到仓库提 issue附上基础库版本、canvas 类型和一张截图处理会快很多。【免费下载链接】pixi-miniprogram一个可运行于微信小程序的PIXI引擎通过模拟window环境有些功能小程序无法模拟就直接修改了PIXI引擎代码最终使得PIXI引擎正常运行在小程序上项目地址: https://gitcode.com/gh_mirrors/pi/pixi-miniprogram创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考