Site: shown names follow the camera; touch tests fail on console and request errors (R2.2)

This commit is contained in:
ZacharyZhang-NY committed 2026-10-09 01:11:59 -04:00
1 parent a9f093ca26
commit 41fe64c74d
3 files changed
+29 -1

No files matched your search

+23
View File
@@ -46,6 +46,9 @@ let errors: string[] = [];
test.beforeEach(async ({ page }) => {
errors = [];
page.on("pageerror", (e) => errors.push(String(e)));
page.on("console", (m) => m.type() === "error" && errors.push(m.text()));
page.on("requestfailed", (r) => errors.push(`${r.url()} ${r.failure()?.errorText}`));
page.on("response", (r) => r.status() >= 400 && errors.push(`${r.url()} ${r.status()}`));
await page.goto("/");
await expect(page.locator(".model .hit-face:not(.ground)").first()).toBeAttached();
});
@@ -141,3 +144,23 @@ test("holding Enter sinks the focused building until release", async ({ page })
await page.keyboard.up("Enter");
await expect(page.locator(".block.pressed")).toHaveCount(0);
});
test("a focused name follows the model when the window narrows", async ({ page }) => {
await page.setViewportSize({ width: 760, height: 1000 });
await page.locator(".doors a").nth(3).focus();
await page.setViewportSize({ width: 390, height: 844 });
await expect
.poll(() => page.evaluate(() => document.documentElement.scrollWidth - innerWidth))
.toBe(0);
const where = () => page.evaluate(() => {
const name = document.querySelector<HTMLElement>(".tour .caption.shown")!.getBoundingClientRect();
const tops = [...document.querySelectorAll('.block[data-part="ElyPDF"] .outline')].map((o) => o.getBoundingClientRect());
const left = Math.min(...tops.map((r) => r.left));
const right = Math.max(...tops.map((r) => r.right));
return { centre: name.left + name.width / 2, left, right, inside: name.left >= 0 && name.right <= innerWidth };
});
await expect.poll(async () => (await where()).inside).toBe(true);
const placed = await where();
expect(placed.centre).toBeGreaterThanOrEqual(placed.left);
expect(placed.centre).toBeLessThanOrEqual(placed.right);
});
+5 -1
View File
@@ -23,6 +23,7 @@ export function touch(host: HTMLElement, svg: SVGSVGElement, parts: Map<string,
caption.setAttribute("aria-hidden", "true");
host.append(caption);
const follow = () => place(caption, host, svg, blocks);
const show = () => {
const up = state.hover || state.focus;
for (const b of blocks) {
@@ -30,7 +31,10 @@ export function touch(host: HTMLElement, svg: SVGSVGElement, parts: Map<string,
b.classList.toggle("pressed", up && state.press);
}
caption.classList.toggle("shown", up);
if (up) place(caption, host, svg, blocks);
// The camera announces each move on the host.
if (up) host.addEventListener("moved", follow);
else host.removeEventListener("moved", follow);
if (up) follow();
};
const set = (change: Partial<typeof state>) => {
Object.assign(state, change);
+1
View File
@@ -319,6 +319,7 @@ export function tour(hero: HTMLElement): { section: HTMLElement; host: HTMLEleme
const tx = cam.ax - cam.s * (cam.cx - origin[0]);
const ty = cam.ay - cam.s * (cam.cy - origin[1]);
world.style.transform = `matrix(${cam.s}, 0, 0, ${cam.s}, ${tx}, ${ty})`;
host.dispatchEvent(new Event("moved"));
const fade = still() ? (p < 0.5 ? 1 : 0) : Math.max(0, 1 - p / HOLD);
hero.style.opacity = String(fade);
hero.style.visibility = fade > 0 ? "" : "hidden";