feat: anchor companion menu above selected character
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { BoxGeometry, Group, Mesh, MeshBasicMaterial, PerspectiveCamera } from 'three';
|
||||
import { createCharacterOverlay } from '../src/ui/characterOverlay.ts';
|
||||
|
||||
test('character menu follows its subject, stays inside the viewport and hides behind the camera', () => {
|
||||
const player = new Group(), head = new Mesh(new BoxGeometry(1, 1, 1), new MeshBasicMaterial());
|
||||
head.name = 'Head'; head.position.y = 1; player.add(head);
|
||||
const camera = new PerspectiveCamera(60, 1, .1, 100);
|
||||
camera.position.set(0, 2, 5); camera.lookAt(0, 1, 0); camera.updateMatrixWorld(true);
|
||||
const canvas = { getBoundingClientRect: () => ({ left: 0, top: 0, right: 320, bottom: 320, width: 320, height: 320 }) } as unknown as HTMLCanvasElement;
|
||||
const panel = { hidden: true, style: { left: '', top: '' }, offsetWidth: 220, offsetHeight: 80 } as unknown as HTMLElement;
|
||||
const overlay = createCharacterOverlay(player, canvas, panel, 12);
|
||||
overlay.update(camera, true);
|
||||
assert.equal(panel.hidden, false);
|
||||
assert.equal(parseFloat(panel.style.left), 160);
|
||||
const firstTop = parseFloat(panel.style.top);
|
||||
player.position.x = 1;
|
||||
overlay.update(camera, true);
|
||||
assert.ok(parseFloat(panel.style.left) > 160);
|
||||
assert.ok(parseFloat(panel.style.left) + panel.offsetWidth / 2 <= 308);
|
||||
player.position.y = 1;
|
||||
overlay.update(camera, true);
|
||||
assert.ok(parseFloat(panel.style.top) < firstTop);
|
||||
assert.ok(parseFloat(panel.style.top) - panel.offsetHeight >= 12);
|
||||
player.position.z = 10;
|
||||
overlay.update(camera, true);
|
||||
assert.equal(panel.hidden, true);
|
||||
player.position.set(0, 0, 0);
|
||||
overlay.update(camera, false);
|
||||
assert.equal(panel.hidden, true);
|
||||
overlay.update(camera, true);
|
||||
assert.equal(panel.hidden, false);
|
||||
head.geometry.dispose(); (head.material as MeshBasicMaterial).dispose();
|
||||
});
|
||||
Reference in New Issue
Block a user