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
+51
-16
@@ -25,29 +25,32 @@ export interface ShowcaseConfig {
|
||||
accent: string;
|
||||
/** Duração dos vídeos gravados, em segundos (os capítulos são medidos nelas). */
|
||||
durations: { desktop: number; mobile: number };
|
||||
/** Comprimento da rolagem deste projeto na vitrine, em alturas de tela. */
|
||||
/** Comprimento da rolagem deste projeto na vitrine, em alturas de tela (o mesmo em todos: ver SHOWCASE). */
|
||||
weight: number;
|
||||
chapters: readonly ShowcaseChapter[];
|
||||
}
|
||||
|
||||
/** Máximo de capítulos por projeto na vitrine: três marcas bastam para situar o visitante sem virar índice. */
|
||||
export const MAX_CHAPTERS = 3;
|
||||
/** Máximo de capítulos por projeto na vitrine: dois bastam (de onde o site parte e o trecho que o define). */
|
||||
export const MAX_CHAPTERS = 2;
|
||||
|
||||
/**
|
||||
* Ordem da vitrine = ordem do SHOWCASE para os projetos que o provedor recebe. Capítulos marcados nos quadros
|
||||
* dos próprios vídeos, no máximo MAX_CHAPTERS por projeto (os mais representativos, com os tempos originais).
|
||||
* O peso soma cerca de 3,5 alturas de tela para os quatro projetos de cliente da home (sev-modaintima,
|
||||
* lavacao-047, sc-plus e as-servicos): a vitrine inteira prende pouco a rolagem.
|
||||
* dos próprios vídeos, no máximo MAX_CHAPTERS por projeto, com os tempos originais: a abertura e o trecho principal,
|
||||
* o par que deixa menos segundos de vídeo sob o rótulo do outro (o último trecho vai até o fim do vídeo).
|
||||
*
|
||||
* O peso é o mesmo em todos, meia altura de tela por projeto, um quarto de tela por capítulo: os quatro projetos de
|
||||
* cliente da home (sev-modaintima, lavacao-047, sc-plus e as-servicos) prendem 2 telas de rolagem e a seção Projetos
|
||||
* inteira, com o título e o botão, fica em cerca de 3,4 telas (eram 4,9). Dentro do projeto a rolagem também é
|
||||
* repartida por igual entre os capítulos (ver `videoFractionAtScroll`), qualquer que seja a duração deles no vídeo.
|
||||
*/
|
||||
export const SHOWCASE: readonly ShowcaseConfig[] = [
|
||||
{
|
||||
id: "sev-modaintima",
|
||||
accent: "#c2303a",
|
||||
durations: { desktop: 14.4, mobile: 30.17 },
|
||||
weight: 0.95,
|
||||
weight: 0.5,
|
||||
chapters: [
|
||||
{ label: "Abertura", desktop: 0, mobile: 0 },
|
||||
{ label: "As favoritas", desktop: 3.6, mobile: 3.8 },
|
||||
{ label: "Coleção completa", desktop: 8, mobile: 9.2 },
|
||||
],
|
||||
},
|
||||
@@ -55,11 +58,10 @@ export const SHOWCASE: readonly ShowcaseConfig[] = [
|
||||
id: "lavacao-047",
|
||||
accent: "#4aa3ff",
|
||||
durations: { desktop: 30.07, mobile: 30.1 },
|
||||
weight: 1.1,
|
||||
weight: 0.5,
|
||||
chapters: [
|
||||
{ label: "Abertura", desktop: 0, mobile: 0 },
|
||||
{ label: "Do sujo ao brilho", desktop: 5.5, mobile: 5.6 },
|
||||
{ label: "Perguntas e contato", desktop: 24, mobile: 22 },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -67,32 +69,29 @@ export const SHOWCASE: readonly ShowcaseConfig[] = [
|
||||
id: "nutriscan",
|
||||
accent: "#2f9e5f",
|
||||
durations: { desktop: 15.67, mobile: 26.4 },
|
||||
weight: 0.8,
|
||||
weight: 0.5,
|
||||
chapters: [
|
||||
{ label: "Busca", desktop: 0, mobile: 0 },
|
||||
{ label: "Quatro etapas", desktop: 7, mobile: 8 },
|
||||
{ label: "Apoio ao projeto", desktop: 10.9, mobile: 16.3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "sc-plus",
|
||||
accent: "#22c55e",
|
||||
durations: { desktop: 14.7, mobile: 22.4 },
|
||||
weight: 0.8,
|
||||
weight: 0.5,
|
||||
chapters: [
|
||||
{ label: "Abertura", desktop: 0, mobile: 0 },
|
||||
{ label: "Áreas e projetos", desktop: 5.8, mobile: 7.6 },
|
||||
{ label: "Contato", desktop: 12.6, mobile: 19.4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "as-servicos",
|
||||
accent: "#2563eb",
|
||||
durations: { desktop: 5.07, mobile: 7.7 },
|
||||
weight: 0.6,
|
||||
weight: 0.5,
|
||||
chapters: [
|
||||
{ label: "Três áreas", desktop: 0, mobile: 0 },
|
||||
{ label: "Critérios de entrega", desktop: 1.5, mobile: 3 },
|
||||
{ label: "Contato", desktop: 2.4, mobile: 4.4 },
|
||||
],
|
||||
},
|
||||
@@ -187,6 +186,42 @@ export function desktopFractionAt(config: ShowcaseConfig, fraction: number) {
|
||||
return interpolate(chapterAnchors(config), fraction, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pontos [fração da rolagem do projeto, fração do vídeo desktop] da vitrine fixa: o capítulo `i` de `n` começa em
|
||||
* `i / n` da rolagem, quando o vídeo chega ao ponto em que o capítulo começa nele. Assim cada capítulo ganha o mesmo
|
||||
* tanto de rolagem, dure ele 0,9 s ou 24 s no vídeo (o vídeo anda mais depressa nos longos).
|
||||
*/
|
||||
function scrollAnchors(config: ShowcaseConfig): Array<[number, number]> {
|
||||
const { chapters, durations } = config;
|
||||
const points = chapters.map((chapter, i): [number, number] => [
|
||||
i / chapters.length,
|
||||
chapter.desktop / durations.desktop,
|
||||
]);
|
||||
points.push([1, 1]);
|
||||
return points;
|
||||
}
|
||||
|
||||
/** Fração do vídeo desktop (0 a 1) que a rolagem do projeto, em `progress` (0 a 1), mostra: capítulos de rolagem igual. */
|
||||
export function videoFractionAtScroll(
|
||||
config: ShowcaseConfig,
|
||||
progress: number,
|
||||
) {
|
||||
return interpolate(scrollAnchors(config), progress, 0);
|
||||
}
|
||||
|
||||
/** Capítulo em exibição quando a rolagem do projeto está em `progress` (0 a 1): `n` partes iguais. */
|
||||
export function chapterIndexAtScroll(config: ShowcaseConfig, progress: number) {
|
||||
const count = config.chapters.length;
|
||||
const index = Math.floor(Math.min(1, Math.max(0, progress)) * count + 1e-6);
|
||||
return Math.min(count - 1, index);
|
||||
}
|
||||
|
||||
/** Fração da rolagem do projeto (0 a 1) em que o capítulo `index` começa. */
|
||||
export function chapterScrollFraction(config: ShowcaseConfig, index: number) {
|
||||
const { length } = config.chapters;
|
||||
return Math.min(length - 1, Math.max(0, index)) / length;
|
||||
}
|
||||
|
||||
/** Capítulo em exibição quando o vídeo desktop está na fração `fraction`. */
|
||||
export function chapterIndexAt(config: ShowcaseConfig, fraction: number) {
|
||||
const seconds = Math.min(1, Math.max(0, fraction)) * config.durations.desktop;
|
||||
|
||||
Reference in new issue
Block a user