perf(movimento): uma transição, 3D leve e vídeo certo por aparelho

Passagens com fade e 32 px, cena anterior termina em opacidade 0, sem visibility nem clip-path. 3D do hero como fundo ambiente, sob demanda e desligado em toque, aparelho fraco, saveData e movimento reduzido. Lenis fora do toque e salto direto em âncoras distantes. Vitrine só de clientes, até 3 capítulos, fixa só no desktop e carrossel no celular; vídeo só do projeto em cena com preload metadata. Rótulos mono a partir de 12 px e limão só no contato.
This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 03:32:23 -03:00
1 parent 8d07b8c6bb
commit c9a0b80656
48 files changed
+7210 -1241

No files matched your search

+61 -1
View File
@@ -18,6 +18,10 @@ beforeEach(() => {
afterEach(() => {
jest.restoreAllMocks();
Object.defineProperty(navigator, "connection", {
configurable: true,
value: undefined,
});
});
describe("ProjectVideo", () => {
@@ -31,7 +35,7 @@ describe("ProjectVideo", () => {
expect(element).toHaveAttribute("autoplay");
expect(element).toHaveAttribute("loop");
expect(element).toHaveAttribute("playsinline");
expect(element).toHaveAttribute("preload", "none");
expect(element).toHaveAttribute("preload", "metadata");
expect(element).toHaveAttribute("poster", video.poster);
expect(element?.muted).toBe(true);
expect(element).toHaveAttribute("data-ready", "false");
@@ -70,6 +74,62 @@ describe("ProjectVideo", () => {
expect(element).toHaveAttribute("data-ready", "true");
});
it("does not even request the poster while the card is far from the screen", () => {
const { container, rerender } = render(
<ProjectVideo
video={video}
title="Demo"
active={false}
showPoster={false}
/>,
);
expect(container.querySelector("video")).not.toHaveAttribute("poster");
rerender(
<ProjectVideo video={video} title="Demo" active={false} showPoster />,
);
expect(container.querySelector("video")).toHaveAttribute(
"poster",
video.poster,
);
});
it("swaps to the sources of the new device when the version changes", () => {
const mobile = getShowcaseAssets("nutriscan", "mobile");
const { container, rerender } = render(
<ProjectVideo video={video} title="Demo" active />,
);
const loads = jest.mocked(HTMLMediaElement.prototype.load).mock.calls
.length;
rerender(<ProjectVideo video={mobile} title="Demo" active />);
expect(
[...container.querySelectorAll("source")].map((source) =>
source.getAttribute("src"),
),
).toEqual(mobile.sources.map((source) => source.src));
expect(
jest.mocked(HTMLMediaElement.prototype.load).mock.calls.length,
).toBeGreaterThan(loads);
});
it("shows only the poster, with no video element, when the data saver is on", () => {
Object.defineProperty(navigator, "connection", {
configurable: true,
value: { saveData: true },
});
const { container } = render(
<ProjectVideo video={video} title="Demo" active />,
);
expect(container.querySelector("video")).toBeNull();
expect(container.querySelector("source")).toBeNull();
expect(
screen.getByRole("img", { name: "Captura de tela de Demo" }),
).toBeInTheDocument();
expect(HTMLMediaElement.prototype.play).not.toHaveBeenCalled();
});
it("shows only the poster, with no video element, when the user prefers reduced motion", () => {
reducedMotion = true;
const { container } = render(