canvas导出背景发黑或发白是因为未正确清空像素;必须在draw完成后调用ctx.clearrect(0,0,width,height)且type="2d",否则透明无效。

Canvas 默认背景是黑色或白色,不是“透明”,取消的本质是显式清空而非覆盖。
为什么 Canvas 导出后背景发黑或发白
这不是样式没设对,而是 canvas 元素在底层渲染时默认填充了不透明底色。即使你用 ctx.fillStyle = 'transparent' 或 CSS 设置 background: none,也完全无效——Canvas 的绘图上下文不认 CSS 背景,只依赖绘制行为本身。
- 微信小程序真机上,
type="2d"canvas 若未手动清空,导出 PNG 时透明区域会强制填黑 - App 端部分机型可能填白,H5 则表现不一,根源都是未触发“清空像素”操作
-
ctx.clearRect()是唯一可靠方式,它把指定区域所有像素的 alpha 设为 0,并重置 RGB 为 0(即纯黑+全透),这才是微信识别的“合法透明”
必须用 clearRect,且要在 draw 后、导出前调用
很多开发者在 ctx.draw() 前就调用 clearRect,结果还是糊的——因为 canvas 绘制是异步的,clearRect 可能被后续 draw 覆盖。
- 务必等绘图完成再清空:
ctx.draw(true, () => { ctx.clearRect(0, 0, width, height); }) -
width和height必须是 canvas 实际像素尺寸(注意乘pixelRatio),不能用 rpx 值 - 如果画布有缩放或 transform,
clearRect仍按原始坐标系执行,别被视觉错觉骗了
type="2d" 是前提,旧版 createCanvasContext 不行
模板中没写 type="2d",或者 JS 里没传 { type: '2d' },clearRect 可能静默失效,尤其在 iOS 小程序上。
- 模板必须写:
<canvas canvas-id="myCanvas" type="2d"></canvas> - 创建上下文必须带参数:
uni.createCanvasContext('myCanvas', this, { type: '2d' }) - 漏掉
{ type: '2d' }会导致getImageData返回的 alpha 值被截断,clearRect无法真正归零
最容易被忽略的是:清空之后如果又执行了任何 fillRect、drawImage 或文字绘制,且没设 globalAlpha 或没用 clip 限定区域,就等于重新污染了背景。保透明的关键不是“清一次”,而是“清完不再乱画”。











