fix: re-scale canvas when device pixel ratio changes

This commit is contained in:
Terry Jia
2026-04-13 22:32:06 -04:00
parent 2524846f5c
commit 6e4133c4a5
2 changed files with 74 additions and 2 deletions

View File

@@ -0,0 +1,61 @@
import { expect } from '@playwright/test'
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe('Canvas DPR scaling', { tag: ['@canvas'] }, () => {
test('Canvas buffer resizes when device pixel ratio changes', async ({
comfyPage
}) => {
await comfyPage.workflow.loadWorkflow('default')
await comfyPage.nextFrame()
const cssRect = await comfyPage.page.evaluate(() => {
const canvas = window.app!.canvas.canvas
const rect = canvas.getBoundingClientRect()
return { width: rect.width, height: rect.height }
})
await expect
.poll(
() => comfyPage.page.evaluate(() => window.app!.canvas.canvas.width),
{
message: 'Initial canvas buffer width should equal CSS width at DPR 1'
}
)
.toBe(Math.round(cssRect.width))
const viewport = comfyPage.page.viewportSize()!
const cdp = await comfyPage.page.context().newCDPSession(comfyPage.page)
try {
await cdp.send('Emulation.setDeviceMetricsOverride', {
width: viewport.width,
height: viewport.height,
deviceScaleFactor: 2,
mobile: false
})
await expect
.poll(
() => comfyPage.page.evaluate(() => window.app!.canvas.canvas.width),
{
message:
'Canvas buffer width should be 2x CSS width after DPR change'
}
)
.toBe(Math.round(cssRect.width * 2))
await expect
.poll(
() => comfyPage.page.evaluate(() => window.app!.canvas.canvas.height),
{
message:
'Canvas buffer height should be 2x CSS height after DPR change'
}
)
.toBe(Math.round(cssRect.height * 2))
} finally {
await cdp.send('Emulation.clearDeviceMetricsOverride')
await cdp.detach()
}
})
})

View File

@@ -1,7 +1,11 @@
import { useEventListener, useResizeObserver } from '@vueuse/core'
import {
useDevicePixelRatio,
useEventListener,
useResizeObserver
} from '@vueuse/core'
import _ from 'es-toolkit/compat'
import type { ToastMessageOptions } from 'primevue/toast'
import { reactive, unref } from 'vue'
import { reactive, unref, watch } from 'vue'
import { shallowRef } from 'vue'
import { useCanvasPositionConversion } from '@/composables/element/useCanvasPositionConversion'
@@ -951,6 +955,13 @@ export class ComfyApp {
}
})
// Re-scale canvas when DPR changes (e.g. moving between monitors)
const { pixelRatio } = useDevicePixelRatio()
watch(pixelRatio, () => {
const canvas = unref(this.canvasElRef)
if (canvas) this.resizeCanvas(canvas)
})
await useExtensionService().invokeExtensionsAsync('init')
await this.registerNodes()