From 56050f788752f2b7196cfc422a1b16d9e3c116e9 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Tue, 30 Apr 2024 09:07:06 +1000 Subject: [PATCH] fix(ui): fix canvas scaling when window is zoomed Konva doesn't react to changes to window zoom/scale. If you open the tab at, say, 90%, then bump to 100%, the pixel ratio of the canvas doesn't change. This results in lower-quality renders on the canvas (generation is unaffected). --- invokeai/frontend/web/package.json | 1 + invokeai/frontend/web/pnpm-lock.yaml | 11 +++++++++++ .../regionalPrompts/components/StageComponent.tsx | 6 ++++++ .../src/features/regionalPrompts/util/renderers.ts | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/invokeai/frontend/web/package.json b/invokeai/frontend/web/package.json index a591e654a7..9e661e0737 100644 --- a/invokeai/frontend/web/package.json +++ b/invokeai/frontend/web/package.json @@ -101,6 +101,7 @@ "serialize-error": "^11.0.3", "socket.io-client": "^4.7.5", "use-debounce": "^10.0.0", + "use-device-pixel-ratio": "^1.1.2", "use-image": "^1.1.1", "uuid": "^9.0.1", "zod": "^3.22.4", diff --git a/invokeai/frontend/web/pnpm-lock.yaml b/invokeai/frontend/web/pnpm-lock.yaml index c0cbc59ad2..9910e32391 100644 --- a/invokeai/frontend/web/pnpm-lock.yaml +++ b/invokeai/frontend/web/pnpm-lock.yaml @@ -158,6 +158,9 @@ dependencies: use-debounce: specifier: ^10.0.0 version: 10.0.0(react@18.2.0) + use-device-pixel-ratio: + specifier: ^1.1.2 + version: 1.1.2(react@18.2.0) use-image: specifier: ^1.1.1 version: 1.1.1(react-dom@18.2.0)(react@18.2.0) @@ -13324,6 +13327,14 @@ packages: react: 18.2.0 dev: false + /use-device-pixel-ratio@1.1.2(react@18.2.0): + resolution: {integrity: sha512-nFxV0HwLdRUt20kvIgqHYZe6PK/v4mU1X8/eLsT1ti5ck0l2ob0HDRziaJPx+YWzBo6dMm4cTac3mcyk68Gh+A==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + dev: false + /use-image@1.1.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-n4YO2k8AJG/BcDtxmBx8Aa+47kxY5m335dJiCQA5tTeVU4XdhrhqR6wT0WISRXwdMEOv5CSjqekDZkEMiiWaYQ==} peerDependencies: diff --git a/invokeai/frontend/web/src/features/regionalPrompts/components/StageComponent.tsx b/invokeai/frontend/web/src/features/regionalPrompts/components/StageComponent.tsx index e3018d3da9..6f6d828c5c 100644 --- a/invokeai/frontend/web/src/features/regionalPrompts/components/StageComponent.tsx +++ b/invokeai/frontend/web/src/features/regionalPrompts/components/StageComponent.tsx @@ -19,6 +19,7 @@ import { debouncedRenderers, renderers as normalRenderers } from 'features/regio import Konva from 'konva'; import type { IRect } from 'konva/lib/types'; import { memo, useCallback, useLayoutEffect, useMemo, useState } from 'react'; +import { useDevicePixelRatio } from 'use-device-pixel-ratio'; import { v4 as uuidv4 } from 'uuid'; // This will log warnings when layers > 5 - maybe use `import.meta.env.MODE === 'development'` instead? @@ -49,6 +50,7 @@ const useStageRenderer = ( const selectedLayerIdColor = useAppSelector(selectSelectedLayerColor); const layerIds = useMemo(() => state.layers.map((l) => l.id), [state.layers]); const renderers = useMemo(() => (asPreview ? debouncedRenderers : normalRenderers), [asPreview]); + const dpr = useDevicePixelRatio({ round: false }); const onLayerPosChanged = useCallback( (layerId: string, x: number, y: number) => { @@ -196,6 +198,10 @@ const useStageRenderer = ( log.trace('Arranging layers'); renderers.arrangeLayers(stage, layerIds); }, [stage, layerIds, renderers]); + + useLayoutEffect(() => { + Konva.pixelRatio = dpr; + }, [dpr]); }; type Props = { diff --git a/invokeai/frontend/web/src/features/regionalPrompts/util/renderers.ts b/invokeai/frontend/web/src/features/regionalPrompts/util/renderers.ts index 5687f249e7..beb9fcf7b3 100644 --- a/invokeai/frontend/web/src/features/regionalPrompts/util/renderers.ts +++ b/invokeai/frontend/web/src/features/regionalPrompts/util/renderers.ts @@ -415,7 +415,7 @@ const createControlNetLayer = (stage: Konva.Stage, reduxLayer: ControlAdapterLay const konvaLayer = new Konva.Layer({ id: reduxLayer.id, name: CONTROLNET_LAYER_NAME, - imageSmoothingEnabled: false, + imageSmoothingEnabled: true, }); stage.add(konvaLayer); return konvaLayer;