fix: 修复视频流画面闪烁问题

- canvas尺寸改为精确匹配bitmap尺寸,不再只增不减
- 仅在尺寸真正变化时才设置canvas.width/height(避免不必要的画布清空)
- 移除每帧绘制前的clearRect调用(消除透明闪烁)
- fit模式下用黑色fillRect替代clearRect填充边缘区域
- stretch模式下drawImage覆盖全画布,无需额外清除
This commit is contained in:
wdvipa
2026-02-15 14:57:51 +08:00
parent aaa6acfded
commit f91c6dc2eb

View File

@@ -303,13 +303,13 @@ const DeviceScreen: React.FC<DeviceScreenProps> = ({ deviceId, onScreenSizeChang
return
}
// 只在canvas内部分辨率需要增大时才更新,避免偶发小帧清空画布导致闪烁
if (canvas.width < bitmap.width || canvas.height < bitmap.height) {
canvas.width = Math.max(canvas.width, bitmap.width)
canvas.height = Math.max(canvas.height, bitmap.height)
// canvas尺寸匹配bitmap只在尺寸真正变化时才设置
// 注意设置canvas.width/height会清空画布内容所以必须紧接着绘制新帧
const needsResize = canvas.width !== bitmap.width || canvas.height !== bitmap.height
if (needsResize) {
canvas.width = bitmap.width
canvas.height = bitmap.height
}
// 每帧绘制前清除canvas可能比bitmap大
ctx.clearRect(0, 0, canvas.width, canvas.height)
switch (screenDisplay.fitMode) {
case 'fit':
@@ -377,9 +377,16 @@ const DeviceScreen: React.FC<DeviceScreenProps> = ({ deviceId, onScreenSizeChang
const drawFitMode = (ctx: CanvasRenderingContext2D, img: HTMLImageElement | ImageBitmap, canvas: HTMLCanvasElement) => {
const scale = Math.min(canvas.width / img.width, canvas.height / img.height)
const x = (canvas.width - img.width * scale) / 2
const y = (canvas.height - img.height * scale) / 2
ctx.drawImage(img, x, y, img.width * scale, img.height * scale)
const w = img.width * scale
const h = img.height * scale
const x = (canvas.width - w) / 2
const y = (canvas.height - h) / 2
// 只清除图像未覆盖的边缘区域避免全画布clearRect导致闪烁
if (x > 0 || y > 0) {
ctx.fillStyle = '#000'
ctx.fillRect(0, 0, canvas.width, canvas.height)
}
ctx.drawImage(img, x, y, w, h)
}
const drawFillMode = (ctx: CanvasRenderingContext2D, img: HTMLImageElement | ImageBitmap, canvas: HTMLCanvasElement) => {