fix(navegacao): foco em âncora de outra página, vitrine acessível e 3D mais leve
Foco cai no destino ao chegar de outra página; âncoras ignoram ?tipo=; movimento reduzido salta em todos os cliques; cronômetro da janela ampliada; degradê no topo de Projetos e legendas do mergulho com intervalos testados; vitrine acima da barra de cookies e com 2 paradas por projeto; reel-list.css no global; 3D montado em tarefas curtas, limitado a ~30 qps e estático com WebGL por software; pôsteres da vitrine de 330 para 158 KB; SC Plus regravado; scripts sem funções acima de complexidade 10.
This commit is contained in:
1 parent
9e2d65a926
commit
204ebd5fa5
49 files changed
+2197
-606
No files matched your search
@@ -76,6 +76,23 @@ export function ProjectLightbox({
|
||||
const [fraction, setFraction] = useState(0);
|
||||
const [duration, setDuration] = useState(0);
|
||||
|
||||
// lê a duração e aplica o ponto pendente da troca de aparelho; vale para o `loadedmetadata` e para o vídeo que já
|
||||
// chegou com os metadados (cache, preload): nesse caso o evento passou antes de alguém ouvir e não volta
|
||||
const readMetadata = useCallback(() => {
|
||||
const video = videoRef.current;
|
||||
if (!video) return;
|
||||
setDuration(video.duration);
|
||||
if (pendingFraction.current !== null) {
|
||||
video.currentTime = pendingFraction.current * video.duration;
|
||||
pendingFraction.current = null;
|
||||
}
|
||||
}, []);
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: o <video> é outro elemento a cada projeto/aparelho (key)
|
||||
useEffect(() => {
|
||||
if ((videoRef.current?.readyState ?? 0) >= 1) readMetadata();
|
||||
}, [config.id, device, readMetadata]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!reducedMotion) return;
|
||||
wantsToPlay.current = false;
|
||||
@@ -108,8 +125,10 @@ export function ProjectLightbox({
|
||||
let id = 0;
|
||||
const tick = () => {
|
||||
const current = videoRef.current;
|
||||
if (current?.duration)
|
||||
if (current?.duration) {
|
||||
setDuration(current.duration);
|
||||
setFraction(current.currentTime / current.duration);
|
||||
}
|
||||
id = requestAnimationFrame(tick);
|
||||
};
|
||||
id = requestAnimationFrame(tick);
|
||||
@@ -157,16 +176,6 @@ export function ProjectLightbox({
|
||||
onNavigate(next);
|
||||
};
|
||||
|
||||
const handleMetadata = () => {
|
||||
const video = videoRef.current;
|
||||
if (!video) return;
|
||||
setDuration(video.duration);
|
||||
if (pendingFraction.current !== null) {
|
||||
video.currentTime = pendingFraction.current * video.duration;
|
||||
pendingFraction.current = null;
|
||||
}
|
||||
};
|
||||
|
||||
const handleTime = () => {
|
||||
const video = videoRef.current;
|
||||
if (video?.duration) setFraction(video.currentTime / video.duration);
|
||||
@@ -219,7 +228,7 @@ export function ProjectLightbox({
|
||||
poster={assets.poster}
|
||||
width={assets.width}
|
||||
height={assets.height}
|
||||
onLoadedMetadata={handleMetadata}
|
||||
onLoadedMetadata={readMetadata}
|
||||
onPlay={() => setPlaying(true)}
|
||||
onPause={() => setPlaying(false)}
|
||||
onTimeUpdate={handleTime}
|
||||
|
||||
Reference in new issue
Block a user