Files
sunrise/tests/character-overlay.test.ts
T

36 lines
1.8 KiB
TypeScript

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();
});