perf(movimento): vitrine e 3D mais leves, WebGL por software lembrado na sessão e suporte ao WebKit
This commit is contained in:
1 parent
9fd1570426
commit
8903f3c57e
28 files changed
+854
-406
No files matched your search
@@ -4,6 +4,8 @@ import {
|
||||
chapterAnchors,
|
||||
chapterFraction,
|
||||
chapterIndexAt,
|
||||
chapterIndexAtScroll,
|
||||
chapterScrollFraction,
|
||||
desktopFractionAt,
|
||||
getOgImagePath,
|
||||
getScrubSource,
|
||||
@@ -12,6 +14,7 @@ import {
|
||||
mobileFractionAt,
|
||||
PROJECT_VIDEO_IDS,
|
||||
SHOWCASE,
|
||||
videoFractionAtScroll,
|
||||
} from "./project-showcase";
|
||||
|
||||
const MAX_BYTES = 3 * 1024 * 1024;
|
||||
@@ -20,21 +23,33 @@ const publicFile = (path: string) => join(process.cwd(), "public", path);
|
||||
const HOME_IDS = ["sev-modaintima", "lavacao-047", "sc-plus", "as-servicos"];
|
||||
|
||||
describe("showcase length", () => {
|
||||
it.each(SHOWCASE)("$id has at most three chapters", (config) => {
|
||||
expect(MAX_CHAPTERS).toBe(3);
|
||||
it.each(SHOWCASE)("$id has at most two chapters", (config) => {
|
||||
expect(MAX_CHAPTERS).toBe(2);
|
||||
expect(config.chapters.length).toBeLessThanOrEqual(MAX_CHAPTERS);
|
||||
expect(config.chapters.length).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
|
||||
it("pins the four home projects for about three and a half screens at most", () => {
|
||||
it("gives every project the same scroll, half a screen for its two chapters", () => {
|
||||
expect(SHOWCASE.map((config) => config.weight)).toEqual(
|
||||
SHOWCASE.map(() => 0.5),
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps the whole Projects section within about three and a half screens", () => {
|
||||
// o casco da vitrine tem (pin: 1 tela menos o cabeçalho) + (soma dos pesos) telas; o título e o botão de Projetos
|
||||
// somam ~468 px (0,52 tela de 900 px) fora dela, e o cabeçalho fixo tem 68 px
|
||||
const SCREEN = 900;
|
||||
const HEADER = 68;
|
||||
const OUTSIDE = 468;
|
||||
const total = SHOWCASE.filter((config) => HOME_IDS.includes(config.id))
|
||||
.map((config) => config.weight)
|
||||
.reduce((sum, weight) => sum + weight, 0);
|
||||
expect(HOME_IDS.every((id) => SHOWCASE.some((c) => c.id === id))).toBe(
|
||||
true,
|
||||
);
|
||||
expect(total).toBeLessThanOrEqual(3.5);
|
||||
expect(total).toBeGreaterThan(2);
|
||||
const section = SCREEN - HEADER + total * SCREEN + OUTSIDE;
|
||||
expect(section / SCREEN).toBeLessThanOrEqual(3.5);
|
||||
expect(total).toBeGreaterThan(1.5);
|
||||
});
|
||||
|
||||
it("keeps the NutriScan configuration for /cases", () => {
|
||||
@@ -90,13 +105,72 @@ describe("showcase chapters", () => {
|
||||
expect(chapterIndexAt(lavacao, 0)).toBe(0);
|
||||
expect(chapterIndexAt(lavacao, 3 / lavacao.durations.desktop)).toBe(0);
|
||||
expect(chapterIndexAt(lavacao, 10 / lavacao.durations.desktop)).toBe(1);
|
||||
expect(chapterIndexAt(lavacao, 25 / lavacao.durations.desktop)).toBe(2);
|
||||
expect(chapterIndexAt(lavacao, 25 / lavacao.durations.desktop)).toBe(1);
|
||||
expect(chapterIndexAt(lavacao, 1)).toBe(lavacao.chapters.length - 1);
|
||||
expect(chapterIndexAt(lavacao, 2)).toBe(lavacao.chapters.length - 1);
|
||||
expect(chapterIndexAt(lavacao, -1)).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("showcase scroll: every chapter gets the same share", () => {
|
||||
const lavacao = SHOWCASE.find((config) => config.id === "lavacao-047");
|
||||
const asServicos = SHOWCASE.find((config) => config.id === "as-servicos");
|
||||
if (!lavacao || !asServicos) throw new Error("projeto fora da vitrine");
|
||||
|
||||
it.each(SHOWCASE)(
|
||||
"$id: each chapter starts at its own time of the video, at i/n of the scroll",
|
||||
(config) => {
|
||||
config.chapters.forEach((chapter, i) => {
|
||||
expect(
|
||||
videoFractionAtScroll(config, chapterScrollFraction(config, i)),
|
||||
).toBeCloseTo(chapter.desktop / config.durations.desktop, 9);
|
||||
});
|
||||
expect(videoFractionAtScroll(config, 0)).toBe(0);
|
||||
expect(videoFractionAtScroll(config, 1)).toBe(1);
|
||||
},
|
||||
);
|
||||
|
||||
it("splits a 30 s project with a 5.5 s first chapter in half of the scroll, not in 18% and 82%", () => {
|
||||
const half = videoFractionAtScroll(lavacao, 0.5);
|
||||
|
||||
expect(half).toBeCloseTo(5.5 / lavacao.durations.desktop, 9);
|
||||
// dentro de cada metade o vídeo anda de forma linear
|
||||
expect(videoFractionAtScroll(lavacao, 0.25)).toBeCloseTo(half / 2, 9);
|
||||
expect(videoFractionAtScroll(lavacao, 0.75)).toBeCloseTo((half + 1) / 2, 9);
|
||||
});
|
||||
|
||||
it("only goes forward, even for a project whose chapters are very different in length", () => {
|
||||
let last = -1;
|
||||
for (let progress = 0; progress <= 1; progress += 0.01) {
|
||||
const fraction = videoFractionAtScroll(asServicos, progress);
|
||||
expect(fraction).toBeGreaterThanOrEqual(last);
|
||||
last = fraction;
|
||||
}
|
||||
});
|
||||
|
||||
it("reads the chapter from the scroll: n equal parts, clamped", () => {
|
||||
expect(chapterIndexAtScroll(lavacao, 0)).toBe(0);
|
||||
expect(chapterIndexAtScroll(lavacao, 0.49)).toBe(0);
|
||||
expect(chapterIndexAtScroll(lavacao, 0.5)).toBe(1);
|
||||
expect(chapterIndexAtScroll(lavacao, 1)).toBe(lavacao.chapters.length - 1);
|
||||
expect(chapterIndexAtScroll(lavacao, 3)).toBe(lavacao.chapters.length - 1);
|
||||
expect(chapterIndexAtScroll(lavacao, -1)).toBe(0);
|
||||
// a conta de ponto flutuante na fronteira (1/3 de 3 partes) não derruba o capítulo
|
||||
const three = {
|
||||
...lavacao,
|
||||
chapters: [...lavacao.chapters, lavacao.chapters[1]],
|
||||
};
|
||||
expect(chapterIndexAtScroll(three, 1 / 3)).toBe(1);
|
||||
});
|
||||
|
||||
it("gives the scroll fraction where a chapter starts (and clamps the index)", () => {
|
||||
expect(chapterScrollFraction(lavacao, 0)).toBe(0);
|
||||
expect(chapterScrollFraction(lavacao, 1)).toBe(0.5);
|
||||
expect(chapterScrollFraction(lavacao, 9)).toBe(0.5);
|
||||
expect(chapterScrollFraction(lavacao, -2)).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("showcase assets", () => {
|
||||
it("picks the version for the device", () => {
|
||||
expect(getShowcaseAssets("nutriscan", "desktop").poster).toBe(
|
||||
|
||||
Reference in new issue
Block a user