Files
Termix/plugins/homepage/tests/frontend/canvas/canvasGeometry.test.ts
T

81 lines
2.4 KiB
TypeScript

import { describe, it, expect } from "vitest";
import {
screenToCanvas,
canvasToScreen,
zoomAroundPoint,
} from "../../../src/frontend/canvas/canvasGeometry.js";
const PAN = { x: 100, y: 200 };
const ZOOM = 2;
describe("screenToCanvas", () => {
it("inverts canvasToScreen", () => {
const canvas = { x: 50, y: 75 };
const screen = canvasToScreen(canvas.x, canvas.y, PAN, ZOOM);
const back = screenToCanvas(screen.x, screen.y, PAN, ZOOM);
expect(back.x).toBeCloseTo(canvas.x);
expect(back.y).toBeCloseTo(canvas.y);
});
it("accounts for pan offset", () => {
const result = screenToCanvas(100, 200, PAN, 1);
expect(result.x).toBe(0);
expect(result.y).toBe(0);
});
it("accounts for zoom", () => {
const result = screenToCanvas(300, 400, PAN, ZOOM);
expect(result.x).toBe((300 - 100) / 2);
expect(result.y).toBe((400 - 200) / 2);
});
});
describe("canvasToScreen", () => {
it("maps origin with pan offset", () => {
const result = canvasToScreen(0, 0, PAN, ZOOM);
expect(result.x).toBe(100);
expect(result.y).toBe(200);
});
it("scales by zoom", () => {
const result = canvasToScreen(10, 20, PAN, ZOOM);
expect(result.x).toBe(120);
expect(result.y).toBe(240);
});
});
describe("zoomAroundPoint", () => {
it("keeps the mouse point on the same canvas coordinate", () => {
const mouseX = 400;
const mouseY = 300;
const pan = { x: 0, y: 0 };
const oldZoom = 1;
const newZoom = 2;
const newPan = zoomAroundPoint(mouseX, mouseY, pan, oldZoom, newZoom);
// Canvas coordinate under mouse before zoom
const canvasBefore = screenToCanvas(mouseX, mouseY, pan, oldZoom);
// Canvas coordinate under mouse after zoom with newPan
const canvasAfter = screenToCanvas(mouseX, mouseY, newPan, newZoom);
expect(canvasAfter.x).toBeCloseTo(canvasBefore.x);
expect(canvasAfter.y).toBeCloseTo(canvasBefore.y);
});
it("returns correct pan for zoom-out", () => {
const mouseX = 200;
const mouseY = 150;
const pan = { x: 50, y: 50 };
const oldZoom = 2;
const newZoom = 1;
const newPan = zoomAroundPoint(mouseX, mouseY, pan, oldZoom, newZoom);
const canvasBefore = screenToCanvas(mouseX, mouseY, pan, oldZoom);
const canvasAfter = screenToCanvas(mouseX, mouseY, newPan, newZoom);
expect(canvasAfter.x).toBeCloseTo(canvasBefore.x);
expect(canvasAfter.y).toBeCloseTo(canvasBefore.y);
});
});