需设置 canvas style="position: fixed;" 并在 manifest.json 中开启 mp-weixin.canvas2d,仅 cover-view/cover-image 可覆盖其上,且须用 v-show 控制显隐、按 dpr 动态适配宽高。

uni-app 小程序里 canvas 总盖在所有组件上面,怎么降级?
这是小程序原生限制导致的——canvas(尤其是 type="2d" 或 type="webgl")默认是 native 层渲染,z-index 无效,会穿透所有 view、cover-view 甚至原生按钮。uni-app 无法绕过这个底层规则,只能借力小程序的「同层渲染」机制。
启用 canvas 同层渲染必须加 style="position: fixed;"
uni-app 的 canvas 组件若想参与同层渲染(即和 cover-view 等原生覆盖层共存),必须满足两个硬性条件:
-
canvas的style中必须显式设置position: fixed;(仅fixed有效,absolute不行) - 必须在
manifest.json的「微信小程序配置」里开启mp-weixin.canvas2d(H5 和 App 端不生效) - 不能用
v-if控制显示/隐藏,要用v-show或 CSSdisplay切换,否则同层上下文会被销毁
示例写法:
<canvas canvas-id="myCanvas" style="position: fixed; top: 100rpx; left: 50rpx; width: 300rpx; height: 200rpx;"></canvas>
cover-view 和 cover-image 是唯一能盖在 canvas 上的组件
普通 view 在 canvas 同层模式下依然会被压在下面;只有微信原生提供的 cover-view 和 cover-image 才能真正叠在 canvas 之上。但注意:
-
cover-view不支持background-image、border-radius(部分基础圆角可用,但不可靠) - 它只接受有限样式:
width/height/top/left/color/font-size等,且单位必须是rpx或px(%无效) - 事件绑定要谨慎——
cover-view的在某些安卓机上可能失灵,建议加 <code>catchtouchstart兜底
真机调试时 Canvas 坐标偏移、缩放错乱?检查 pixelRatio 和宽高设置
同层 canvas 渲染后,getBoundingClientRect() 返回的坐标和实际绘制区域常不一致,根本原因是:小程序把 canvas 容器尺寸(CSS像素)和绘图上下文尺寸(物理像素)混用了。
- 务必用
query.select('#myCanvas').boundingClientRect()拿真实布局尺寸,别信offsetWidth - 创建 2D context 时,手动设置
width/height为rect.width * pixelRatio和rect.height * pixelRatio - 微信开发者工具里
pixelRatio默认是 1,真机通常是 2 或 3,不处理会导致图形模糊或裁剪
关键代码片段:
const query = wx.createSelectorQuery().in(this);
query.select('#myCanvas').boundingClientRect();
query.exec((res) => {
const rect = res[0];
const dpr = wx.getSystemInfoSync().pixelRatio;
const ctx = wx.createCanvasContext('myCanvas', this);
// 这里必须按 dpr 缩放 canvas 内部分辨率
ctx.canvas.width = rect.width * dpr;
ctx.canvas.height = rect.height * dpr;
});同层渲染不是开关一开就万事大吉,position: fixed 的定位基准、cover-view 的样式残缺、真机 pixelRatio 的动态适配——这三处漏掉任何一点,canvas 都会重新“飘”起来。

















