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
@@ -1,3 +1,43 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
/** Telas dos projetos (vitrine e capas): nenhum efeito pode ficar por cima delas. */
|
||||
const PROJECT_SCREENS = ".ds-reel, .ds-frame, .ds-bframe, .ds-phone";
|
||||
|
||||
/** Grão de filme sobre a página. Some enquanto qualquer tela de projeto está à vista (data-over-projects). */
|
||||
export default function FilmGrain() {
|
||||
return <div aria-hidden="true" className="film-grain" />;
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const grain = ref.current;
|
||||
if (!grain) return;
|
||||
let frame = 0;
|
||||
const update = () => {
|
||||
frame = 0;
|
||||
const over = Array.from(document.querySelectorAll(PROJECT_SCREENS)).some(
|
||||
(screen) => {
|
||||
const rect = screen.getBoundingClientRect();
|
||||
return (
|
||||
rect.height > 0 && rect.bottom > 0 && rect.top < window.innerHeight
|
||||
);
|
||||
},
|
||||
);
|
||||
if (over) grain.dataset.overProjects = "";
|
||||
else delete grain.dataset.overProjects;
|
||||
};
|
||||
const queue = () => {
|
||||
if (!frame) frame = requestAnimationFrame(update);
|
||||
};
|
||||
update();
|
||||
window.addEventListener("scroll", queue, { passive: true });
|
||||
window.addEventListener("resize", queue);
|
||||
return () => {
|
||||
cancelAnimationFrame(frame);
|
||||
window.removeEventListener("scroll", queue);
|
||||
window.removeEventListener("resize", queue);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <div ref={ref} aria-hidden="true" className="film-grain" />;
|
||||
}
|
||||
Reference in new issue
Block a user