// Entrada suave das seções conforme a pessoa rola. // // O CSS que esconde antes da hora só vale sob `.js-reveal` no , marcado // por um script no . Quem cai aqui sem JS vê a página inteira. // // Há três caminhos para uma seção aparecer, e nenhum depende do outro: // // 1. o observador, que dá a animação no momento certo; // 2. uma varredura a cada rolagem, para quando o observador não dispara -- // ele não roda em página que o navegador não está desenhando, como uma // aba aberta em segundo plano; // 3. um prazo final: passado ele, o que ainda estiver escondido aparece. // // A primeira versão disto tinha uma rede só, e ela perguntava se *alguma* // seção havia aparecido. Como a primeira aparece sempre, a rede se dava por // satisfeita e todas as de baixo ficavam invisíveis -- o texto existia na // página e ninguém via. Daí a regra: cada seção precisa da própria garantia. // O agenda um resgate que apaga a marca de esconder em 3s. Chegando // aqui, o módulo está vivo e assume a responsabilidade -- então cancela. // Enquanto este arquivo não carrega, o resgate é a única coisa entre a pessoa // e uma página em branco. clearTimeout(window.__resgateRevelacao); const alvos = [...document.querySelectorAll('.reveal')]; if (alvos.length) { const mostrar = (alvo) => alvo.classList.add('is-visible'); const pendentes = () => alvos.filter((alvo) => !alvo.classList.contains('is-visible')); // Um pouco antes de entrar na tela, para o movimento terminar quando a // seção chega de fato ao olho. const jaDaParaVer = (alvo) => { const caixa = alvo.getBoundingClientRect(); return caixa.top < innerHeight * 0.92 && caixa.bottom > 0; }; const varrer = () => { for (const alvo of pendentes()) if (jaDaParaVer(alvo)) mostrar(alvo); }; if ('IntersectionObserver' in window) { const observador = new IntersectionObserver((entradas) => { for (const entrada of entradas) { if (!entrada.isIntersecting) continue; mostrar(entrada.target); // Uma vez revelada, a seção não volta a sumir: reanimar a cada rolagem // cansa e atrapalha quem só está subindo para reler algo. observador.unobserve(entrada.target); } }, { rootMargin: '0px 0px -8% 0px', threshold: 0.05 }); for (const alvo of alvos) observador.observe(alvo); } addEventListener('scroll', varrer, { passive: true }); addEventListener('resize', varrer); // Ao voltar para a aba, o observador pode ter perdido o que passou enquanto // ela estava escondida. addEventListener('visibilitychange', varrer); varrer(); // Prazo final. Conteúdo escondido por causa de enfeite é defeito, e a esta // altura é melhor entregar tudo de uma vez do que arriscar deixar algo // invisível. setTimeout(() => { for (const alvo of pendentes()) mostrar(alvo); }, 6000); }