小程序渲染问题

This commit is contained in:
Yeomai committed 2026-09-29 01:50:11 +08:00
1 parent 88bffaa5d0
commit 919da19be7
5 files changed
+194 -101

No files matched your search

+27 -10
View File
@@ -43,6 +43,7 @@ Page({
_ty: 0,
_fitOffset: null,
_fitSize: null,
_lastSizeCheck: 0,
_lastTime: 0,
_raf: null,
_ready: false,
@@ -80,10 +81,15 @@ Page({
wx.createSelectorQuery()
.in(this)
.select('#spineCanvas')
.fields({ node: true, size: true })
.fields({ node: true })
// 画布节点返回的 size 是缓冲区尺寸(不是当前布局尺寸),
// 所以量外面这层普通 view 来定缓冲区大小,否则布局一变画面就会被拉伸
.select('#stageBox')
.fields({ size: true })
.exec((res) => {
const hit = res && res[0]
if (!hit || !hit.node) {
const canvasHit = res && res[0]
const stageHit = res && res[1]
if (!canvasHit || !canvasHit.node) {
this.setData({
status: 'error',
errorMsg: '取不到 canvas 节点,请确认基础库支持 <canvas type="webgl">',
@@ -91,8 +97,8 @@ Page({
return
}
const canvas = hit.node
const size = hit.size || { width: 300, height: 300 }
const canvas = canvasHit.node
const size = (stageHit && stageHit.size) || { width: 300, height: 300 }
let dpr = 1
try {
@@ -158,11 +164,11 @@ Page({
if (!this._canvas || !this._gl) return
wx.createSelectorQuery()
.in(this)
.select('#spineCanvas')
.fields({ node: true, size: true })
.select('#stageBox')
.fields({ size: true })
.exec((res) => {
const hit = res && res[0]
if (!hit || !hit.node || !hit.size) return
if (!hit || !hit.size) return
const size = hit.size
if (!size.width || !size.height) return
@@ -470,6 +476,15 @@ Page({
if (!canvas || !gl || !this._skeleton) return
const now = Date.now()
// 面板内容变化(比如加载后多出播放/参数区)会改变画布显示尺寸。
// 只在加载后校对一次是不够的:那次可能跑在布局生效之前,之后就再也不会纠正,
// 缓冲区与显示区比例不一致就会让画面被拉伸。这里定期校对,尺寸没变时直接返回,开销很小。
if (now - this._lastSizeCheck > 400) {
this._lastSizeCheck = now
this.syncCanvasSize()
}
let dt = (now - this._lastTime) / 1000
this._lastTime = now
if (!(dt > 0)) dt = 0
@@ -487,8 +502,10 @@ Page({
const mvp = env.buildMVP(scale, this._tx, this._ty, W, H)
gl.viewport(0, 0, W, H)
// 深色画布背景(与 UI 的深色预览区保持一致)
gl.clearColor(0.12, 0.13, 0.16, 1)
// 透明清屏:canvas 是原生组件、层级在 WebView 之上,
// 用不透明颜色清屏会盖住压在它上面的浮层(缩放按钮、手势提示、信息徽标)。
// 背景交给舞台的 CSS 渐变,观感一致,但浮层能正常显示。
gl.clearColor(0, 0, 0, 0)
gl.clear(gl.COLOR_BUFFER_BIT)
// 预乘开关:同时影响渲染器的混色方式与 GL 混合函数
const pma = this.data.premultiplied