fix(ui): floor all pixel coords

This prevents rendering objects with sub-pixel positioning, which looks soft
This commit is contained in:
psychedelicious 2024-04-20 16:46:54 +10:00 committed by Kent Keirsey
parent 944690ac8e
commit e4024bdeb9
2 changed files with 38 additions and 10 deletions

View File

@ -1,6 +1,5 @@
import { useStore } from '@nanostores/react';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition';
import {
$cursorPosition,
$isMouseDown,
@ -17,8 +16,25 @@ const getIsFocused = (stage: Konva.Stage) => {
return stage.container().contains(document.activeElement);
};
export const getScaledFlooredCursorPosition = (stage: Konva.Stage) => {
const pointerPosition = stage.getPointerPosition();
const stageTransform = stage.getAbsoluteTransform().copy();
if (!pointerPosition || !stageTransform) {
return;
}
const scaledCursorPosition = stageTransform.invert().point(pointerPosition);
return {
x: Math.floor(scaledCursorPosition.x),
y: Math.floor(scaledCursorPosition.y),
};
};
const syncCursorPos = (stage: Konva.Stage) => {
const pos = getScaledCursorPosition(stage);
const pos = getScaledFlooredCursorPosition(stage);
if (!pos) {
return null;
}
@ -47,7 +63,13 @@ export const useMouseEvents = () => {
}
// const tool = getTool();
if (tool === 'brush' || tool === 'eraser') {
dispatch(rpLayerLineAdded({ layerId: selectedLayerId, points: [pos.x, pos.y, pos.x, pos.y], tool }));
dispatch(
rpLayerLineAdded({
layerId: selectedLayerId,
points: [Math.floor(pos.x), Math.floor(pos.y), Math.floor(pos.x), Math.floor(pos.y)],
tool,
})
);
}
},
[dispatch, selectedLayerId, tool]
@ -79,7 +101,7 @@ export const useMouseEvents = () => {
}
// const tool = getTool();
if (getIsFocused(stage) && $isMouseOver.get() && $isMouseDown.get() && (tool === 'brush' || tool === 'eraser')) {
dispatch(rpLayerPointsAdded({ layerId: selectedLayerId, point: [pos.x, pos.y] }));
dispatch(rpLayerPointsAdded({ layerId: selectedLayerId, point: [Math.floor(pos.x), Math.floor(pos.y)] }));
}
},
[dispatch, selectedLayerId, tool]
@ -117,7 +139,13 @@ export const useMouseEvents = () => {
return;
}
if (tool === 'brush' || tool === 'eraser') {
dispatch(rpLayerLineAdded({ layerId: selectedLayerId, points: [pos.x, pos.y, pos.x, pos.y], tool }));
dispatch(
rpLayerLineAdded({
layerId: selectedLayerId,
points: [Math.floor(pos.x), Math.floor(pos.y), Math.floor(pos.x), Math.floor(pos.y)],
tool,
})
);
}
}
},

View File

@ -1,6 +1,6 @@
import { getStore } from 'app/store/nanostores/store';
import { rgbColorToString } from 'features/canvas/util/colorToString';
import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition';
import { getScaledFlooredCursorPosition } from 'features/regionalPrompts/hooks/mouseEventHooks';
import type { Layer, RegionalPromptLayer, RPTool } from 'features/regionalPrompts/store/regionalPromptsSlice';
import {
$isMouseOver,
@ -168,13 +168,13 @@ const renderRPLayer = (
// Create a `dragmove` listener for this layer
if (onLayerPosChanged) {
konvaLayer.on('dragend', function (e) {
onLayerPosChanged(rpLayer.id, e.target.x(), e.target.y());
onLayerPosChanged(rpLayer.id, Math.floor(e.target.x()), Math.floor(e.target.y()));
});
}
// The dragBoundFunc limits how far the layer can be dragged
konvaLayer.dragBoundFunc(function (pos) {
const cursorPos = getScaledCursorPosition(stage);
const cursorPos = getScaledFlooredCursorPosition(stage);
if (!cursorPos) {
return this.getAbsolutePosition();
}
@ -207,8 +207,8 @@ const renderRPLayer = (
// Update the layer's position and listening state
konvaLayer.setAttrs({
listening: tool === 'move', // The layer only listens when using the move tool - otherwise the stage is handling mouse events
x: rpLayer.x,
y: rpLayer.y,
x: Math.floor(rpLayer.x),
y: Math.floor(rpLayer.y),
// There are rpLayers.length layers, plus a brush preview layer rendered on top of them, so the zIndex works
// out to be the layerIndex. If more layers are added, this may no longer be true.
zIndex: rpLayerIndex,