From f91c6dc2ebaf7d21bff3bc431c38376f68ddaeff Mon Sep 17 00:00:00 2001 From: wdvipa Date: Sun, 15 Feb 2026 14:57:51 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E6=B5=81=E7=94=BB=E9=9D=A2=E9=97=AA=E7=83=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - canvas尺寸改为精确匹配bitmap尺寸,不再只增不减 - 仅在尺寸真正变化时才设置canvas.width/height(避免不必要的画布清空) - 移除每帧绘制前的clearRect调用(消除透明闪烁) - fit模式下用黑色fillRect替代clearRect填充边缘区域 - stretch模式下drawImage覆盖全画布,无需额外清除 --- src/components/Device/DeviceScreen.tsx | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/components/Device/DeviceScreen.tsx b/src/components/Device/DeviceScreen.tsx index 7be0ae8..5b89219 100644 --- a/src/components/Device/DeviceScreen.tsx +++ b/src/components/Device/DeviceScreen.tsx @@ -303,13 +303,13 @@ const DeviceScreen: React.FC = ({ 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 = ({ 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) => {