eb127c11c2
Keep effects pinned to map coordinates when the viewport changes; materials/NPC overlays stay screen-fixed. Co-authored-by: Cursor <cursoragent@cursor.com>
68 lines
2.0 KiB
TypeScript
68 lines
2.0 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import { describe, it } from 'node:test';
|
|
|
|
import {
|
|
DEFAULT_SCENE_VIEW_CAMERA,
|
|
sceneViewPanBy,
|
|
sceneViewZoomAt,
|
|
} from '../../shared/types/sceneView';
|
|
|
|
import { SceneViewStore } from './sceneViewStore';
|
|
|
|
describe('SceneViewStore', () => {
|
|
it('resets to default camera', () => {
|
|
const store = new SceneViewStore();
|
|
store.dispatch({ kind: 'set', camera: { scale: 2, ox: 0.2, oy: 0.8 } });
|
|
const next = store.dispatch({ kind: 'reset' });
|
|
assert.equal(next.scale, 1);
|
|
assert.equal(next.ox, 0.5);
|
|
assert.equal(next.oy, 0.5);
|
|
});
|
|
|
|
it('clamps scale and origin', () => {
|
|
const store = new SceneViewStore();
|
|
const next = store.dispatch({ kind: 'set', camera: { scale: 99, ox: -1, oy: 2 } });
|
|
assert.equal(next.scale, 8);
|
|
assert.equal(next.ox, 0);
|
|
assert.equal(next.oy, 1);
|
|
});
|
|
});
|
|
|
|
describe('sceneViewZoomAt / panBy', () => {
|
|
it('zooms toward cursor and keeps that content point under cursor', () => {
|
|
const hostW = 1000;
|
|
const hostH = 500;
|
|
const containW = 800;
|
|
const containH = 400;
|
|
const hostX = 700;
|
|
const hostY = 250;
|
|
const next = sceneViewZoomAt(DEFAULT_SCENE_VIEW_CAMERA, {
|
|
hostW,
|
|
hostH,
|
|
containW,
|
|
containH,
|
|
hostX,
|
|
hostY,
|
|
factor: 2,
|
|
});
|
|
assert.ok(next.scale > 1.5);
|
|
const displayW = containW * next.scale;
|
|
const displayH = containH * next.scale;
|
|
const left = hostW / 2 - next.ox * displayW;
|
|
const top = hostH / 2 - next.oy * displayH;
|
|
const ix = (hostX - left) / displayW;
|
|
const iy = (hostY - top) / displayH;
|
|
// At scale=1 contain is centered; cursor was at content x=(700-100)/800=0.75
|
|
assert.ok(Math.abs(ix - 0.75) < 1e-6);
|
|
assert.ok(Math.abs(iy - 0.5) < 1e-6);
|
|
});
|
|
|
|
it('pans in host pixels', () => {
|
|
const cam = { scale: 2, ox: 0.5, oy: 0.5 };
|
|
const next = sceneViewPanBy(cam, { containW: 400, containH: 200, dx: 80, dy: 0 });
|
|
// displayW=800; dx=80 → ox decreases by 0.1
|
|
assert.ok(Math.abs(next.ox - 0.4) < 1e-6);
|
|
assert.equal(next.oy, 0.5);
|
|
});
|
|
});
|