feat: adapt presentation canvas ratio

This commit is contained in:
lda
2026-07-06 03:48:19 +07:00 Verified
parent d9fa4c4807
commit bd2081fe8a
4 changed files with 68 additions and 27 deletions
@@ -1,6 +1,5 @@
import { act, cleanup, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it } from "vitest";
import { PRESENTATION_HEIGHT, PRESENTATION_WIDTH } from "./canvas-fit.js";
import { PresentationCanvas } from "./PresentationCanvas.js";
const setViewport = (width: number, height: number) => {
@@ -11,28 +10,36 @@ const setViewport = (width: number, height: number) => {
afterEach(() => cleanup());
describe("PresentationCanvas", () => {
it("renders one fixed 1280x720 audience canvas", () => {
it("fills a 16:9 viewport with the maximum logical width", () => {
setViewport(1280, 720);
render(<PresentationCanvas><div>Scene</div></PresentationCanvas>);
const canvas = screen.getByTestId("presentation-canvas");
expect(canvas).toHaveStyle({
width: `${PRESENTATION_WIDTH}px`,
height: `${PRESENTATION_HEIGHT}px`,
expect(screen.getByTestId("presentation-canvas")).toHaveStyle({
width: "1280px",
height: "720px",
transform: "scale(1)",
left: "0px",
top: "0px",
});
});
it("recomputes letterboxing after viewport resize", () => {
it("recomputes the logical width after resizing to 4:3", () => {
setViewport(1280, 720);
render(<PresentationCanvas><div>Scene</div></PresentationCanvas>);
setViewport(1024, 768);
act(() => window.dispatchEvent(new Event("resize")));
const canvas = screen.getByTestId("presentation-canvas");
expect(canvas).toHaveStyle({ width: "960px", height: "720px" });
expect(canvas.style.left).toBe("0px");
expect(canvas.style.top).toBe("0px");
expect(Number(canvas.style.transform.match(/scale\((.+)\)/)?.[1])).toBeCloseTo(1024 / 960);
});
it("uses an intermediate logical width instead of selecting a preset", () => {
setViewport(1200, 800);
render(<PresentationCanvas><div>Scene</div></PresentationCanvas>);
expect(screen.getByTestId("presentation-canvas")).toHaveStyle({
transform: "scale(0.8)",
left: "0px",
top: "96px",
width: "1080px",
height: "720px",
});
});
});