Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/src/editor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// import { panicProxy } from "@graphite/utility-functions/panic-proxy";

import { type JsMessageType } from "@graphite/messages";
import { createSubscriptionRouter, type SubscriptionRouter } from "@graphite/subscription-router";
import init, { setRandomSeed, wasmMemory, EditorHandle, receiveNativeMessage } from "@graphite-frontend/wasm/pkg/graphite_wasm.js";
Expand Down
41 changes: 35 additions & 6 deletions frontend/src/io-managers/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export function createInputManager(editor: Editor, dialog: DialogState, portfoli
const shakeSamples: { x: number; y: number; time: number }[] = [];
let lastShakeTime = 0;

// Get device pixel ratio for coordinate transformation
// This fixes the offset issue on high-DPI devices like iPad
const getDevicePixelRatio = () => window.devicePixelRatio || 1;

// Event listeners

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -160,9 +164,14 @@ export function createInputManager(editor: Editor, dialog: DialogState, portfoli
const inGraphOverlay = get(document).graphViewOverlayOpen;
if (!viewportPointerInteractionOngoing && (inFloatingMenu || inGraphOverlay)) return;

// Scale coordinates by device pixel ratio to fix offset on high-DPI devices like iPad
const dpr = getDevicePixelRatio();
const scaledX = e.clientX * dpr;
const scaledY = e.clientY * dpr;

const modifiers = makeKeyboardModifiersBitfield(e);
if (detectShake(e)) editor.handle.onMouseShake(e.clientX, e.clientY, e.buttons, modifiers);
editor.handle.onMouseMove(e.clientX, e.clientY, e.buttons, modifiers);
if (detectShake(e)) editor.handle.onMouseShake(scaledX, scaledY, e.buttons, modifiers);
editor.handle.onMouseMove(scaledX, scaledY, e.buttons, modifiers);
}

function onPointerDown(e: PointerEvent) {
Expand Down Expand Up @@ -190,8 +199,13 @@ export function createInputManager(editor: Editor, dialog: DialogState, portfoli
}

if (viewportPointerInteractionOngoing && isTargetingCanvas instanceof Element) {
// Scale coordinates by device pixel ratio to fix offset on high-DPI devices like iPad
const dpr = getDevicePixelRatio();
const scaledX = e.clientX * dpr;
const scaledY = e.clientY * dpr;

const modifiers = makeKeyboardModifiersBitfield(e);
editor.handle.onMouseDown(e.clientX, e.clientY, e.buttons, modifiers);
editor.handle.onMouseDown(scaledX, scaledY, e.buttons, modifiers);
}
}

Expand All @@ -208,8 +222,13 @@ export function createInputManager(editor: Editor, dialog: DialogState, portfoli

if (textToolInteractiveInputElement) return;

// Scale coordinates by device pixel ratio to fix offset on high-DPI devices like iPad
const dpr = getDevicePixelRatio();
const scaledX = e.clientX * dpr;
const scaledY = e.clientY * dpr;

const modifiers = makeKeyboardModifiersBitfield(e);
editor.handle.onMouseUp(e.clientX, e.clientY, e.buttons, modifiers);
editor.handle.onMouseUp(scaledX, scaledY, e.buttons, modifiers);
}

// Mouse events
Expand All @@ -233,8 +252,13 @@ export function createInputManager(editor: Editor, dialog: DialogState, portfoli
if (e.button === BUTTON_BACK) buttons = 8; // Back
if (e.button === BUTTON_FORWARD) buttons = 16; // Forward

// Scale coordinates by device pixel ratio to fix offset on high-DPI devices like iPad
const dpr = getDevicePixelRatio();
const scaledX = e.clientX * dpr;
const scaledY = e.clientY * dpr;

const modifiers = makeKeyboardModifiersBitfield(e);
editor.handle.onDoubleClick(e.clientX, e.clientY, buttons, modifiers);
editor.handle.onDoubleClick(scaledX, scaledY, buttons, modifiers);
}

function onMouseDown(e: MouseEvent) {
Expand Down Expand Up @@ -268,8 +292,13 @@ export function createInputManager(editor: Editor, dialog: DialogState, portfoli

if (isTargetingCanvas) {
e.preventDefault();
// Scale coordinates by device pixel ratio to fix offset on high-DPI devices like iPad
const dpr = getDevicePixelRatio();
const scaledX = e.clientX * dpr;
const scaledY = e.clientY * dpr;

const modifiers = makeKeyboardModifiersBitfield(e);
editor.handle.onWheelScroll(e.clientX, e.clientY, e.buttons, e.deltaX, e.deltaY, e.deltaZ, modifiers);
editor.handle.onWheelScroll(scaledX, scaledY, e.buttons, e.deltaX, e.deltaY, e.deltaZ, modifiers);
}
}

Expand Down
7 changes: 6 additions & 1 deletion frontend/src/utility-functions/viewports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ import { type Editor } from "@graphite/editor";

export function updateBoundsOfViewports(editor: Editor) {
const viewports = Array.from(window.document.querySelectorAll("[data-viewport-container]"));

// Get device pixel ratio to scale bounds for high-DPI devices like iPad
const dpr = window.devicePixelRatio || 1;

const boundsOfViewports = viewports.map((canvas) => {
const bounds = canvas.getBoundingClientRect();
return [bounds.left, bounds.top, bounds.right, bounds.bottom];
// Scale bounds by device pixel ratio to match scaled pointer coordinates
return [bounds.left * dpr, bounds.top * dpr, bounds.right * dpr, bounds.bottom * dpr];
});

const flattened = boundsOfViewports.flat();
Expand Down
Loading