The <video> element used `max-w-full max-h-full`, which only ever shrinks oversized media. A source smaller than the window (480p on a 1080p display) rendered at its intrinsic size — a small picture floating in a black frame. Fill the container and let `object-contain` do the scaling, so the picture fits whichever axis constrains it in both directions while preserving aspect ratio. The sizing rules move to `videoFit.ts` so they are unit-testable outside the component.
58 lines
2.2 KiB
TypeScript
58 lines
2.2 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { videoFitClass, fittedVideoSize } from "./videoFit";
|
|
|
|
describe("videoFitClass", () => {
|
|
it("fills the container instead of capping at the source's intrinsic size", () => {
|
|
const cls = videoFitClass();
|
|
// max-w/max-h only shrink oversized media; a 480p source would stay a small
|
|
// box in the middle of a large window.
|
|
expect(cls).not.toContain("max-w-full");
|
|
expect(cls).not.toContain("max-h-full");
|
|
expect(cls).toContain("w-full");
|
|
expect(cls).toContain("h-full");
|
|
});
|
|
|
|
it("preserves aspect ratio while fitting (letterbox, never crop)", () => {
|
|
const cls = videoFitClass();
|
|
expect(cls).toContain("object-contain");
|
|
expect(cls).not.toContain("object-cover");
|
|
expect(cls).not.toContain("object-fill");
|
|
});
|
|
});
|
|
|
|
describe("fittedVideoSize", () => {
|
|
it("scales a 480p source up to fill a larger window (the reported bug)", () => {
|
|
// Exact 16:9 480p in a 1920x1080 window -> scales up to fill, rather than
|
|
// staying a 854x480 box in the middle.
|
|
const size = fittedVideoSize(853.33, 480, 1920, 1080);
|
|
expect(size.width).toBeCloseTo(1920, 0);
|
|
expect(size.height).toBeCloseTo(1080, 0);
|
|
});
|
|
|
|
it("fits to the constraining dimension when aspect ratios differ", () => {
|
|
// 4:3 source in a 16:9 window -> height-constrained, pillarboxed.
|
|
const size = fittedVideoSize(640, 480, 1920, 1080);
|
|
expect(size.height).toBeCloseTo(1080, 0);
|
|
expect(size.width).toBeCloseTo(1440, 0);
|
|
expect(size.width).toBeLessThan(1920);
|
|
});
|
|
|
|
it("fits to width when the source is wider than the window", () => {
|
|
// 21:9 source in a 16:9 window -> width-constrained, letterboxed.
|
|
const size = fittedVideoSize(2560, 1080, 1920, 1080);
|
|
expect(size.width).toBeCloseTo(1920, 0);
|
|
expect(size.height).toBeCloseTo(810, 0);
|
|
expect(size.height).toBeLessThan(1080);
|
|
});
|
|
|
|
it("shrinks oversized media to fit rather than overflowing", () => {
|
|
const size = fittedVideoSize(3840, 2160, 1280, 720);
|
|
expect(size.width).toBeCloseTo(1280, 0);
|
|
expect(size.height).toBeCloseTo(720, 0);
|
|
});
|
|
|
|
it("returns a zero size for unknown intrinsic dimensions", () => {
|
|
expect(fittedVideoSize(0, 0, 1920, 1080)).toEqual({ width: 0, height: 0 });
|
|
});
|
|
});
|