Skip to content

Commit

Permalink
ctrl-+, ctrl-- zooming
Browse files Browse the repository at this point in the history
  • Loading branch information
abrenneke committed Oct 10, 2023
1 parent 9ab5d9f commit 8c82d67
Showing 1 changed file with 42 additions and 7 deletions.
49 changes: 42 additions & 7 deletions packages/app/src/hooks/useCanvasHotkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,69 @@ import { useCanvasPositioning } from './useCanvasPositioning';
export function useCanvasHotkeys() {
const [canvasPosition, setCanvasPosition] = useRecoilState(canvasPositionState);
const viewportBounds = useViewportBounds();
const { clientToCanvasPosition } = useCanvasPositioning();
const { canvasToClientPosition } = useCanvasPositioning();

const latestHandler = useLatest((e: KeyboardEvent) => {
// If we're in an input, don't do anything
if (['input', 'textarea'].includes(document.activeElement?.tagName.toLowerCase()!)) {
return;
}

if ((e.key === '-' || e.key === '=') && (e.metaKey || e.ctrlKey) && !e.shiftKey) {
const zoomSpeed = 0.25;
const zoomFactor = e.key === '=' ? 1 + zoomSpeed : 1 - zoomSpeed;

const newZoom = canvasPosition.zoom * zoomFactor;

const viewportCenter = {
const centerOfScreenCanvasCoords = {
x: viewportBounds.left + (viewportBounds.right - viewportBounds.left) / 2,
y: viewportBounds.top + (viewportBounds.bottom - viewportBounds.top) / 2,
};

const currentMousePosCanvas = clientToCanvasPosition(viewportCenter.x, viewportCenter.y);
const newX = viewportCenter.x / newZoom - canvasPosition.x;
const newY = viewportCenter.y / newZoom - canvasPosition.y;
const { x: clientX, y: clientY } = canvasToClientPosition(
centerOfScreenCanvasCoords.x,
centerOfScreenCanvasCoords.y,
);

const newX = clientX / newZoom - canvasPosition.x;
const newY = clientY / newZoom - canvasPosition.y;

const diff = {
x: newX - currentMousePosCanvas.x,
y: newY - currentMousePosCanvas.y,
x: newX - centerOfScreenCanvasCoords.x,
y: newY - centerOfScreenCanvasCoords.y,
};

const position: CanvasPosition = {
x: canvasPosition.x + diff.x,
y: canvasPosition.y + diff.y,
zoom: newZoom,
};

setCanvasPosition(position);
}

const isArrowKey = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key);
if (isArrowKey) {
const arrowSpeed = 100;
const arrowFactor = e.shiftKey ? 10 : 1;
const arrowDirection = {
ArrowUp: { x: 0, y: 1 },
ArrowDown: { x: 0, y: -1 },
ArrowLeft: { x: 1, y: 0 },
ArrowRight: { x: -1, y: 0 },
};

const direction = arrowDirection[e.key as keyof typeof arrowDirection];
const diff = {
x: direction.x * arrowSpeed * arrowFactor,
y: direction.y * arrowSpeed * arrowFactor,
};

const position: CanvasPosition = {
x: canvasPosition.x + diff.x,
y: canvasPosition.y + diff.y,
zoom: canvasPosition.zoom,
};
setCanvasPosition(position);
}
});
Expand Down

0 comments on commit 8c82d67

Please sign in to comment.