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:
1 parent
8d07b8c6bb
commit
c9a0b80656
48 files changed
+7210
-1241
No files matched your search
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Leituras do aparelho que decidem o que a página carrega e anima: ponteiro de toque, pouca CPU ou memória,
|
||||
* "economizar dados" e largura de celular. Tudo roda só no navegador (no servidor, devolve o valor mais leve).
|
||||
*/
|
||||
|
||||
/** Abaixo disto (px) a página usa as versões de celular dos vídeos e capas. */
|
||||
export const MOBILE_MAX_WIDTH = 767;
|
||||
export const MOBILE_QUERY = `(max-width: ${MOBILE_MAX_WIDTH}px)`;
|
||||
|
||||
type NavigatorHints = Navigator & {
|
||||
deviceMemory?: number;
|
||||
connection?: { saveData?: boolean };
|
||||
};
|
||||
|
||||
function matches(query: string) {
|
||||
return (
|
||||
typeof window !== "undefined" &&
|
||||
typeof window.matchMedia === "function" &&
|
||||
window.matchMedia(query).matches
|
||||
);
|
||||
}
|
||||
|
||||
/** Ponteiro principal impreciso (dedo): sem rolagem suavizada nem cena 3D. */
|
||||
export const isCoarsePointer = () => matches("(pointer: coarse)");
|
||||
|
||||
export const prefersReducedMotion = () =>
|
||||
matches("(prefers-reduced-motion: reduce)");
|
||||
|
||||
/** Tela de celular: abaixo de 768 px. */
|
||||
export const isMobileViewport = () => matches(MOBILE_QUERY);
|
||||
|
||||
/** "Economizar dados" ligado: só imagens, nenhum vídeo é baixado sozinho. */
|
||||
export function isSaveData() {
|
||||
if (typeof navigator === "undefined") return false;
|
||||
return (navigator as NavigatorHints).connection?.saveData === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Aparelho que não deve montar WebGL: toque, 4 núcleos ou menos, 4 GB de memória ou menos, economia de dados
|
||||
* ou movimento reduzido. O que não é informado pelo navegador (Safari, Firefox) não conta contra o aparelho.
|
||||
*/
|
||||
export function isLowPowerDevice() {
|
||||
if (typeof navigator === "undefined") return true;
|
||||
const hints = navigator as NavigatorHints;
|
||||
return (
|
||||
isCoarsePointer() ||
|
||||
prefersReducedMotion() ||
|
||||
isSaveData() ||
|
||||
(typeof hints.hardwareConcurrency === "number" &&
|
||||
hints.hardwareConcurrency <= 4) ||
|
||||
(typeof hints.deviceMemory === "number" && hints.deviceMemory <= 4)
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user