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).
This commit is contained in:
psychedelicious 2024-04-30 09:07:06 +10:00 committed by Kent Keirsey
parent c354470cd1
commit 56050f7887
4 changed files with 19 additions and 1 deletions

View File

@ -101,6 +101,7 @@
"serialize-error": "^11.0.3", "serialize-error": "^11.0.3",
"socket.io-client": "^4.7.5", "socket.io-client": "^4.7.5",
"use-debounce": "^10.0.0", "use-debounce": "^10.0.0",
"use-device-pixel-ratio": "^1.1.2",
"use-image": "^1.1.1", "use-image": "^1.1.1",
"uuid": "^9.0.1", "uuid": "^9.0.1",
"zod": "^3.22.4", "zod": "^3.22.4",

View File

@ -158,6 +158,9 @@ dependencies:
use-debounce: use-debounce:
specifier: ^10.0.0 specifier: ^10.0.0
version: 10.0.0(react@18.2.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: use-image:
specifier: ^1.1.1 specifier: ^1.1.1
version: 1.1.1(react-dom@18.2.0)(react@18.2.0) version: 1.1.1(react-dom@18.2.0)(react@18.2.0)
@ -13324,6 +13327,14 @@ packages:
react: 18.2.0 react: 18.2.0
dev: false 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): /use-image@1.1.1(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-n4YO2k8AJG/BcDtxmBx8Aa+47kxY5m335dJiCQA5tTeVU4XdhrhqR6wT0WISRXwdMEOv5CSjqekDZkEMiiWaYQ==} resolution: {integrity: sha512-n4YO2k8AJG/BcDtxmBx8Aa+47kxY5m335dJiCQA5tTeVU4XdhrhqR6wT0WISRXwdMEOv5CSjqekDZkEMiiWaYQ==}
peerDependencies: peerDependencies:

View File

@ -19,6 +19,7 @@ import { debouncedRenderers, renderers as normalRenderers } from 'features/regio
import Konva from 'konva'; import Konva from 'konva';
import type { IRect } from 'konva/lib/types'; import type { IRect } from 'konva/lib/types';
import { memo, useCallback, useLayoutEffect, useMemo, useState } from 'react'; import { memo, useCallback, useLayoutEffect, useMemo, useState } from 'react';
import { useDevicePixelRatio } from 'use-device-pixel-ratio';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
// This will log warnings when layers > 5 - maybe use `import.meta.env.MODE === 'development'` instead? // 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 selectedLayerIdColor = useAppSelector(selectSelectedLayerColor);
const layerIds = useMemo(() => state.layers.map((l) => l.id), [state.layers]); const layerIds = useMemo(() => state.layers.map((l) => l.id), [state.layers]);
const renderers = useMemo(() => (asPreview ? debouncedRenderers : normalRenderers), [asPreview]); const renderers = useMemo(() => (asPreview ? debouncedRenderers : normalRenderers), [asPreview]);
const dpr = useDevicePixelRatio({ round: false });
const onLayerPosChanged = useCallback( const onLayerPosChanged = useCallback(
(layerId: string, x: number, y: number) => { (layerId: string, x: number, y: number) => {
@ -196,6 +198,10 @@ const useStageRenderer = (
log.trace('Arranging layers'); log.trace('Arranging layers');
renderers.arrangeLayers(stage, layerIds); renderers.arrangeLayers(stage, layerIds);
}, [stage, layerIds, renderers]); }, [stage, layerIds, renderers]);
useLayoutEffect(() => {
Konva.pixelRatio = dpr;
}, [dpr]);
}; };
type Props = { type Props = {

View File

@ -415,7 +415,7 @@ const createControlNetLayer = (stage: Konva.Stage, reduxLayer: ControlAdapterLay
const konvaLayer = new Konva.Layer({ const konvaLayer = new Konva.Layer({
id: reduxLayer.id, id: reduxLayer.id,
name: CONTROLNET_LAYER_NAME, name: CONTROLNET_LAYER_NAME,
imageSmoothingEnabled: false, imageSmoothingEnabled: true,
}); });
stage.add(konvaLayer); stage.add(konvaLayer);
return konvaLayer; return konvaLayer;