summaryrefslogtreecommitdiff
path: root/apps/web/src/preview/preview-coords.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-04-20 11:31:17 +0200
committerMaze Winther <mazewinther@gmail.com>2026-04-20 11:31:17 +0200
commit3e89d2998588f8e35c524e523ba2ee853f0f6475 (patch)
tree57221f96c1259b3b07e3ddf8c1adefc502b9d8eb /apps/web/src/preview/preview-coords.ts
parent729d10592f4e802f91c555c309ff3ba4b119f843 (diff)
downloadopencut-3e89d2998588f8e35c524e523ba2ee853f0f6475.tar.gz
refactor: restructure files to their domains, new preview overlay system, and dep graph
Diffstat (limited to 'apps/web/src/preview/preview-coords.ts')
-rw-r--r--apps/web/src/preview/preview-coords.ts101
1 files changed, 101 insertions, 0 deletions
diff --git a/apps/web/src/preview/preview-coords.ts b/apps/web/src/preview/preview-coords.ts
new file mode 100644
index 00000000..64184990
--- /dev/null
+++ b/apps/web/src/preview/preview-coords.ts
@@ -0,0 +1,101 @@
+export interface PreviewViewportGeometry {
+ canvasHeight: number;
+ canvasWidth: number;
+ centerX: number;
+ centerY: number;
+ scale: number;
+ viewportHeight: number;
+ viewportWidth: number;
+}
+
+function getCanvasOrigin({
+ geometry,
+}: {
+ geometry: PreviewViewportGeometry;
+}): { x: number; y: number } {
+ return {
+ x: geometry.viewportWidth / 2 - geometry.centerX * geometry.scale,
+ y: geometry.viewportHeight / 2 - geometry.centerY * geometry.scale,
+ };
+}
+
+export function screenToCanvas({
+ clientX,
+ clientY,
+ geometry,
+ viewportRect,
+}: {
+ clientX: number;
+ clientY: number;
+ geometry: PreviewViewportGeometry;
+ viewportRect: DOMRect;
+}): { x: number; y: number } {
+ const overlayX = clientX - viewportRect.left;
+ const overlayY = clientY - viewportRect.top;
+
+ return {
+ x:
+ geometry.centerX +
+ (overlayX - geometry.viewportWidth / 2) / geometry.scale,
+ y:
+ geometry.centerY +
+ (overlayY - geometry.viewportHeight / 2) / geometry.scale,
+ };
+}
+
+export function canvasToOverlay({
+ canvasX,
+ canvasY,
+ geometry,
+}: {
+ canvasX: number;
+ canvasY: number;
+ geometry: PreviewViewportGeometry;
+}): { x: number; y: number } {
+ const canvasOrigin = getCanvasOrigin({ geometry });
+
+ return {
+ x: canvasOrigin.x + canvasX * geometry.scale,
+ y: canvasOrigin.y + canvasY * geometry.scale,
+ };
+}
+
+export function positionToOverlay({
+ positionX,
+ positionY,
+ geometry,
+}: {
+ positionX: number;
+ positionY: number;
+ geometry: PreviewViewportGeometry;
+}): { x: number; y: number } {
+ return canvasToOverlay({
+ canvasX: geometry.canvasWidth / 2 + positionX,
+ canvasY: geometry.canvasHeight / 2 + positionY,
+ geometry,
+ });
+}
+
+export function getDisplayScale({
+ geometry,
+}: {
+ geometry: PreviewViewportGeometry;
+}): { x: number; y: number } {
+ return {
+ x: geometry.scale,
+ y: geometry.scale,
+ };
+}
+
+export function screenPixelsToLogicalThreshold({
+ geometry,
+ screenPixels,
+}: {
+ geometry: PreviewViewportGeometry;
+ screenPixels: number;
+}): { x: number; y: number } {
+ return {
+ x: screenPixels / geometry.scale,
+ y: screenPixels / geometry.scale,
+ };
+}