(85) 99645-7140 nelclassico@gmail.com Praça Coronel Melquiades, 124
GSAP infinite parallax scroll Tecnologia Tutorials

A história sem fim: construindo uma experiência de rolagem infinita e contínua com GSAP e Lenis | Codrops

Demo  Código

Pronto para se tornar um especialista em GSAP? Acesse o treinamento GSAP mais abrangente do mundo, com mais de 300 aulas. Inscreva-se agora →

A maioria das experiências digitais termina quando você para de rolar.
Este recompensa você por não parar.

Neste tutorial, estamos analisando uma interação de rolagem pequena, mas poderosa, construída em torno de loop infinito, profundidade de paralaxe e controle baseado em snap. Não do ponto de vista de “olhar para este efeito legal”, mas das decisões que o tornam suave, intencional e estranhamente viciante.

A versão original foi criada para um projeto cliente de Jillian Phyllis. O resumo era simples: criar algo leve, rápido e compatível com MVP.

Que, como todos sabemos, geralmente é onde o perigo começa.

Simples pode facilmente ficar vazio. O mínimo pode facilmente se tornar esquecível. Portanto, o objetivo não era adicionar mais, mas sim fazer com que menos parecesse mais.

A resposta foi movimento.

Um loop contínuo remove a parada brusca na parte inferior da página. Parallax introduz profundidade entre as seções. O controle instantâneo dá ritmo à experiência, para que o usuário não fique apenas folheando o conteúdo como um carrinho de compras com uma roda quebrada.

Nos bastidores, tudo é movido por Lenis e GSAP. O projeto original usava Next.js, TypeScript e Styled Components, mas para este tutorial estamos reduzindo-o para HTML, CSS e JavaScript simples.

Nenhuma dependência de estrutura.
Nenhuma cerimônia desnecessária.
Apenas a interação, a arquitetura e a lógica por trás disso.

Para esta construção, três coisas importam:

  1. Loop infinito verdadeiro sem costuras visíveis #
  2. Movimento de paralaxe que adiciona profundidade, não decoração
  3. Controle de rolagem baseado em snap que parece deliberado

A partir deste ponto, percorreremos a implementação passo a passo.

Limpar código. Pequenos trechos. Sem truques de mágica.

Bem, talvez um ou dois.

[codrops_course_ad id=”115731″]

Visão geral da arquitetura

Antes de escrever qualquer código de animação, é útil compreender a forma do sistema.

Estamos criando uma experiência de rolagem contínua, mas o truque é que a página em si nunca deve parecer que está sendo reiniciada. O loop precisa acontecer de forma invisível.

A ideia central é simples:

  • Criar seções em tela cheia
  • Duplicar a primeira seção no final
  • Habilite a rolagem infinita no Lenis
  • Ajustar para cada seção
  • Animar a mídia dentro de cada seção com GSAP ScrollTrigger

Isso nos dá a base: o usuário vê uma página suave e contínua.

O navegador vê um loop cuidadosamente preparado usando um disfarce muito bom.

Configuração inicial

Quando criei isso pela primeira vez para LinkedIn , usei minha pilha usual: Next.js, TypeScript e Styled Components.

Para este tutorial, estamos fazendo exatamente o oposto.

Para este tutorial, estamos reduzindo-o para HTML, CSS e JavaScript simples e potencializando-o com Lenis e GSAP.

Suas ferramentas, suas regras. Vou guiar a estrutura.

HTML

Começamos com algumas seções em tela cheia. Três é o ponto ideal:

  • 2 parece vazio
  • 3+ parece intencional

Cada seção contém mídia. Imagens, vídeo, tela, WebGL, faça a sua escolha.

A parte importante é esta:

Duplicamos a primeira seção e a colocamos no final.

Isso é o que permite que Lenis faça um loop perfeitamente. Sem ele, você sentirá a reinicialização. Com isso, o loop desaparece.

Também ocultamos essa duplicata da tecnologia assistiva usando aria-hidden para que os leitores de tela não a leiam duas vezes.

###PRE_7f7f82a11417984993aa0ba68c336835###

CSS

Cada seção preenche a janela de visualização.

Usamos 100svh em vez de 100vh para evitar problemas na barra de ferramentas móvel do Safari.

Em termos de estrutura:

Seção: Tela inteira → Contêiner de mídia: Preencher contêiner → Mídia: Preencher contêiner.

.hero {
    position: relative;
    overflow: clip;

    display: grid;
    place-items: center;

    width: 100%;
    height: 100svh;

    & picture, & img {
        display: block;
    }

    & picture {
        position: absolute;
        inset: 0;
        z-index: -1;

        & img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
    }
}

JavaScript

Dividimos a lógica em duas partes:

  1. Sistema de rolagem
  2. Animação paralaxe

Lenis Setup

Isto é onde o loop acontece.

gsap.registerPlugin(ScrollTrigger);

const setupLenis = () => {
    const lenis = new Lenis({
        infinite: true,
    });

    const snap = new Snap(lenis, {
        type: 'mandatory',
        debounce: 500,
        duration: 0.9,
        easing: (t) => 1 - Math.pow(1 - t, 4),
    });

    const sections = document.querySelectorAll('section');

    snap.addElements(sections, {
        align: 'start',
    });

    lenis.on('scroll', ScrollTrigger.update);

    gsap.ticker.add((time) => {
        lenis.raf(time * 1000);
    });

    gsap.ticker.lagSmoothing(0);
};

Uma linha faz a maior parte da mágica:

infinite: true

Parallax

É aqui que vai de “funciona” para “sente-se bem”.

const sectionAnimation = () => {
    const heros = document.querySelectorAll('.hero');

    heros.forEach((hero) => {
        const media = hero.querySelector('picture');

        gsap.set(media, { yPercent: -50 });

        gsap.fromTo(
            media,
            { yPercent: -50 },
            {
                yPercent: 50,
                ease: 'none',
                scrollTrigger: {
                    trigger: hero,
                    start: 'top bottom',
                    end: 'bottom top',
                    scrub: true,
                },
            }
        );
    });
};

Passamos de -50% para 50%.

É isso.

Esse pequeno atraso entre a rolagem e a mídia cria profundidade. As camadas começam a interagir. A página deixa de parecer plana.

Você pode ver uma reprodução mínima disso no Codepen aqui:

Integrações Avançadas

Assim que o núcleo estiver funcionando, você pode começar a adicionar sutileza.

Para este projeto, coloquei em camadas um letreiro curvo usando um componente OSMO (Curved Marquee). Eu o personalizei fortemente para atender às minhas necessidades específicas, mas não reinventei a roda.

Às vezes, a atitude mais inteligente é saber quando não escrever mais código.

Duas marcas, velocidades diferentes, escala sutil usando ScrollTrigger.

Pequeno detalhe. Grande recompensa.

Final Polish (iOS Fix)

Tudo funciona… até você abrir o Safari no iOS.

Então a barra de ferramentas estraga o seu dia.

À medida que se expande e contrai, expõe a costura do laço. A ilusão se quebra.

Então, corrigimos corretamente.

Nested Lenis Setup

Definimos nosso próprio contêiner de rolagem:

HTML

<div class="wrapper">
    <div class="content">
        <!-- sections -->
    </div>
</div>

CSS

.wrapper {
    position: relative;
    height: 100svh;
    overflow: hidden;
}

Integração JS

Dizemos a Lenis e GSAP para usarem este contêiner:

const wrapper = document.querySelector('.wrapper');
const content = document.querySelector('.content');

const lenis = new Lenis({
    infinite: true,
    wrapper: wrapper,
    content: content,
});

ScrollTrigger.scrollerProxy(wrapper, {
    scrollTop(value) {
        if (arguments.length) {
            lenis.scrollTo(value, { immediate: true });
            return lenis.scroll;
        }
    },
    getBoundingClientRect() {
        return {
            top: 0,
            left: 0,
            width: wrapper.clientWidth,
            height: wrapper.clientHeight,
        };
    },
    pinType: 'transform',
});

E atualize as animações do ScrollTrigger:

scroller: wrapper

Agora o loop está realmente perfeito.

Sem cintilação.
Sem salto.
Nada de caos no Safari.

Conclusão

E isso é o completo sistema: uma rolagem infinita contínua em camadas com profundidade de paralaxe que muda a experiência de algo que você simplesmente navega para algo que você realmente sente. Não há arquitetura pesada ou engenharia excessiva por trás disso, apenas um punhado de ideias bem pensadas trabalhando juntas da maneira certa.

Essa é a verdadeira conclusão aqui. Raramente se trata de adicionar mais, trata-se de entender o que é importante e executá-lo com intenção. Pegue isso, adapte-o, vá além e crie algo que as pessoas realmente queiram continuar navegando.

Deixe um comentário

Seu email não será publicado. Campos obrigatórios marcados com *

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.