Pin (prende na tela) Animações
A seção fica grudada na tela enquanto a pessoa continua rolando — e, presa ali, as peças de dentro podem se mexer junto com a rolagem.
O que é
É o efeito de "a página para por um instante": a pessoa rola, mas aquela seção fica parada no lugar por um trecho, e depois solta e a página segue. Serve para segurar a atenção numa mensagem importante ou para contar algo em etapas: com a seção parada, o título pode sair de lado, a foto crescer, um selo girar — tudo comandado pela rolagem.
Você marca a seção com sw-ani="pin". Ela prende quando o topo dela encosta no topo da tela (ou onde você mandar com sw-ani-start) e fica presa pelo tanto de rolagem de sw-ani-end — 100% é uma tela de rolagem, o padrão é 300% (três telas). Filhos com sw-ani="move" andam até os valores que você der (sw-ani-x, -y, -scale, -rot, -opacity) enquanto ela está presa; com a palavra scrub eles seguem a rolagem para frente e para trás. Precisa do pacote de animação.
Quando usar
- Mensagem principal que não pode passar batida (lançamento, promoção).
- "Como funciona" em etapas: seção parada enquanto as peças se mexem.
- Produto em destaque: a foto cresce enquanto a pessoa rola.
- Se você só quer que um título/menu acompanhe a rolagem sem parar a página, o certo é o Fixed.
- Para várias telas cheias trocando uma pela outra, o certo é o Sections.
Comece aqui
-
1
Coloque o SW Core e o pacote de animação. O JS da animação vai antes do
swcore.min.js.<link rel="stylesheet" href="swcore/swcore.min.css"> <link rel="stylesheet" href="swcore/swcore.motion.min.css"> <!-- fim do <body> --> <script src="swcore/swcore.motion.min.js"></script> <script src="swcore/swcore.min.js"></script> -
2
Marque a seção e diga por quanto tempo ela fica presa (
100%= uma tela de rolagem). Os exemplos ao vivo estão logo abaixo — eles prendem de verdade enquanto você rola.<section sw-ani="pin" sw-ani-end="100%"> <h2>Lançamento: o novo cardápio de verão</h2> </section>
Todas as variações
Cada quadro abaixo é o componente de verdade, rodando. O código embaixo é exatamente o que está no quadro: copie e cole.
1. Prende e solta
Estes quadros prendem de verdade: ao chegar neles, a caixa gruda na tela e se solta da moldura enquanto você rola; depois volta ao lugar. Role devagar.
<div sw-ani="pin" sw-ani-end="60%" class="bg-g-pri p-xg r-m t-ct t-g fw6">Fico preso enquanto você rola</div>
<div sw-ani="pin" sw-ani-start="top 30%" sw-ani-end="60%" class="bg-g-sec p-xg r-m t-ct t-g fw6">Prendo no terço de cima da tela</div>
<div sw-ani="pin" sw-ani-start="late" sw-ani-end="60%" class="bg-g-drk p-xg r-m t-ct t-g fw6">Prendo lá embaixo</div>
2. Peças que se mexem enquanto está preso
Cada filho com sw-ani="move" anda até os valores que você der, enquanto a seção está presa. Com a palavra scrub no pin, eles seguem a rolagem (vão e voltam com ela); sem scrub, fazem o movimento sozinhos, rapidinho, quando o pin começa.
<div sw-ani="pin scrub" sw-ani-end="100%">
<div sw-ani="move" sw-ani-x="120">anda 120 px para a direita</div>
<div sw-ani="move" sw-ani-y="-60">sobe 60 px</div>
<div sw-ani="move" sw-ani-scale="1.5">cresce 50%</div>
<div sw-ani="move" sw-ani-rot="180">gira meia volta</div>
<div sw-ani="move" sw-ani-opacity="0">some</div>
</div>
<div sw-ani="pin" sw-ani-end="60%">
<div sw-ani="move" sw-ani-rot="360">gira</div>
<div sw-ani="move" sw-ani-scale="1.4">cresce</div>
</div>
3. Movimento preso à rolagem, sem prender a seção
Fora de um pin, sw-ani="move" vira um deslocamento que acompanha a rolagem enquanto o elemento atravessa a tela (e sw-ani="rotate" um giro). A página não para. Role devagar.
<div sw-ani="move" class="bg-g-pri p-m r-m t-ct">move</div>
<div sw-ani="move" sw-ani-distance="160" class="bg-g-sec p-m r-m t-ct">160 px</div>
<div sw-ani="move" sw-ani-dir="horizontal" class="bg-g-suc p-m r-m t-ct">de lado</div>
<div sw-ani="rotate" class="bg-g-inf p-m r-m t-ct">gira</div>
Tabela de opções
| Palavra | O que faz | Exemplo |
|---|---|---|
| A seção presa | ||
sw-ani="pin" | Liga o efeito na seção. | <section sw-ani="pin"> |
scrub | Palavra junto do pin: os movers seguem a rolagem para frente e para trás. | sw-ani="pin scrub" |
sw-ani-scrub | Número de segundos de "atraso macio" dos movers atrás da rolagem (em vez de colado). | sw-ani-scrub="1" |
sw-ani-end | Por quanto de rolagem ela fica presa: % da tela, vh ou px. Padrão 300% (três telas). | sw-ani-end="100%" |
sw-ani-start | Onde prende: padrão top top (topo da seção no topo da tela). Aceita os apelidos early (top 94%), normal (top 86%), late (top 70%) ou "parte-da-seção parte-da-tela". | sw-ani-start="top 30%" |
data-sw-end-sm / -md / -lg | Duração diferente por tamanho de tela (menor que 768 px / até 1199 px / 1200 px ou mais). Escreva assim mesmo, com data-sw-. | data-sw-end-sm="60%" |
| Peças dentro (movers) | ||
sw-ani="move" | Num filho da seção presa: ele anda enquanto ela está presa. | <div sw-ani="move" …> |
sw-ani-x | Para onde anda na horizontal: número (px), %, vw, rem… Negativo = para a esquerda. | sw-ani-x="-300" |
sw-ani-y | Para onde anda na vertical. Negativo = para cima. | sw-ani-y="-80" |
sw-ani-scale | Tamanho final (0,1 a 5). 1 = igual. | sw-ani-scale="1.4" |
sw-ani-rot | Giro final em graus (−1080 a 1080). | sw-ani-rot="90" |
sw-ani-opacity | Transparência final (0 = some, 1 = inteiro). | sw-ani-opacity="0" |
| Fora do pin | ||
sw-ani="move" | Desloca enquanto o elemento atravessa a tela. | <div sw-ani="move"> |
sw-ani-distance | Quanto anda para cada lado, em px. Padrão 80. | sw-ani-distance="160" |
sw-ani-dir | vertical (padrão) ou horizontal. | sw-ani-dir="horizontal" |
sw-ani="rotate" | Dá uma volta (360°) enquanto atravessa a tela. | <div sw-ani="rotate"> |
sw-ani-rotation | Rotate: quantos graus gira na travessia (-3600 a 3600; negativo gira ao contrário). Padrão 360. | sw-ani-rotation="90" |
Receitas prontas — usos reais
Situações que aparecem em quase todo site. Copie a que servir.
Essa seção prende a tela de verdade e se solta da moldura enquanto você rola — role bem devagar pra ver o efeito.
Chegou o verão
Cardápio novo
<section sw-ani="pin scrub" sw-ani-end="150%" class="h-v flx f-cl j-ct alc gap-6 bg-g-drk t-ct p-xg">
<p sw-ani="move" sw-ani-y="-40" sw-ani-opacity="0">Chegou o verão</p>
<h2 sw-ani="move" sw-ani-scale="1.35">Cardápio novo</h2>
<div class="flx gap-4">
<span sw-ani="move" sw-ani-x="-120" sw-ani-rot="-12">Açaí</span>
<span sw-ani="move" sw-ani-x="120" sw-ani-rot="12">Sorvetes</span>
</div>
</section>
Essa seção prende a tela de verdade e se solta da moldura enquanto você rola — role bem devagar pra ver o efeito.
<div sw-ani="pin" sw-ani-start="top 30%" sw-ani-end="120%" class="bg-sur bd r-m p-xg flx f-cl gap-4 ov-hi">
<div sw-ani="marquee scrub" sw-ani-speed="90"><span>PROMOÇÃO DE INVERNO · ATÉ 40% OFF · </span></div>
<div sw-ani="marquee scrub" sw-ani-dir="right" sw-ani-speed="160"><span>SÓ ATÉ DOMINGO · FRETE GRÁTIS · </span></div>
</div>
Essa seção prende a tela de verdade e se solta da moldura enquanto você rola — role bem devagar pra ver o efeito.
Como funciona em 3 passos
1. Escolha · 2. Pague · 3. Receba em casa
<section sw-ani="pin" sw-ani-end="100%" id="etapas" class="h-v flx f-cl j-ct alc gap-4">
<h2>Como funciona em 3 passos</h2>
<p>1. Escolha · 2. Pague · 3. Receba em casa</p>
<progress id="barra" max="1" value="0"></progress>
</section>
<script>
// enquanto está presa, o pin avisa o progresso (0 = acabou de prender, 1 = vai soltar)
document.getElementById('etapas').addEventListener('sw:progress', (e) => {
document.getElementById('barra').value = e.detail.progress;
});
</script>
Eventos
sw:progresse.detail.progress vai de 0 (acabou de prender) a 1 (vai soltar).API (JavaScript)
SWMotion.refresh()Precisa de quê
swcore.min.css+swcore.motion.min.css, eswcore.motion.min.jsantes doswcore.min.js.
Cuidados — erros comuns
- A duração vem de
sw-ani-end.sw-ani-durnão faz nada no pin. - Os movers vão até o valor, a partir de onde estão:
sw-ani-x="-800"faz a peça sair para a esquerda, não entrar. Para "entrar", posicione a peça fora no seu CSS e mande-a para0. - Sem a palavra
scrub, os movers não acompanham a rolagem: fazem o movimento sozinhos, uma vez, quando a seção prende. - Um elemento em volta com
transform,filterouoverflow: hiddenatrapalha: a seção pode "pular" ou ficar presa dentro dele em vez de na tela. - Se você mudar a altura da página depois que ela carregou (conteúdo que chega por AJAX, acordeão aberto), chame
SWMotion.refresh(), senão o pin prende no lugar errado. - Mais de três telas presas cansa: quem tem pressa sente que "a página não anda", principalmente no celular.
O que ele não faz
- Quem ativou "reduzir movimento" no aparelho vê a seção presa, mas os movers ficam parados.

