SW Core
SW Core / Animações / Frames (sprite no scroll)

Frames (sprite no scroll) Animações

Uma sequência de imagens que troca de quadro conforme a rolagem — o clássico "gire o produto 360°" — presa na tela enquanto os quadros passam.

O que é

Em vez de um vídeo, você tem várias fotos em sequência (o produto fotografado girando, as etapas de uma montagem, os cômodos de um imóvel). O Frames mostra uma de cada vez, ocupando a tela, e troca para a próxima conforme a pessoa rola: rolou para baixo, avança; rolou para cima, volta. A troca é seca, de foto em foto, como folhear.

O bloco sw-ani="frames" fica mais alto que a tela (para ter rolagem) e o palco sw-ani-frame-stage, dentro dele, fica grudado na tela enquanto isso. Os quadros podem vir de duas formas: várias imagens (cada uma com sw-ani-frame) ou um sprite — uma imagem só com todos os quadros em grade, que você põe como fundo do palco e descreve com sw-ani-frame-sprite="colunasxlinhas". Precisa do pacote de animação.

Quando usar

  • Produto girando 360° (tênis, relógio, móvel) numa página de venda.
  • Passo a passo visual: montagem, antes/depois em etapas, evolução de uma obra.
  • Tour por um lugar: cômodos de um imóvel, ambientes de um restaurante.
  • Para movimento contínuo e suave (não quadro a quadro), o caminho é um vídeo preso à rolagem, não este componente.

Comece aqui

  1. 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. 2

    O bloco, o palco (filho direto) e as imagens dentro do palco, na ordem. Os exemplos ao vivo estão logo abaixo — eles ocupam a tela inteira.

    <div sw-ani="frames" sw-ani-end="200%">
      <div sw-ani-frame-stage>
        <img sw-ani-frame src="/giro/01.webp" alt="Tênis, vista de frente">
        <img sw-ani-frame src="/giro/02.webp" alt="">
        <img sw-ani-frame src="/giro/03.webp" alt="">
        <!-- … -->
      </div>
    </div>

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. Várias imagens, uma por quadro

Este quadro ocupa a tela inteira: ao chegar nele, o palco gruda e o ponteiro gira de 30 em 30 graus conforme você rola (12 quadros). Role devagar, para baixo e para cima.

sw-ani-frame em cada quadro · sw-ani-end="200%"
<div sw-ani="frames" sw-ani-end="200%">
  <div sw-ani-frame-stage class="bg-sur">
    <div sw-ani-frame class="flx alc j-ct"><svg>…ponteiro a 0°…</svg></div>
    <div sw-ani-frame class="flx alc j-ct"><svg>…ponteiro a 30°…</svg></div>
    <!-- … 12 quadros; no seu site, normalmente <img sw-ani-frame src="…"> -->
  </div>
</div>

2. Sprite: todos os quadros numa imagem só

Uma imagem com os quadros em grade (aqui 6 colunas × 4 linhas = 24 quadros de 15°), posta como fundo do palco. O palco foi deixado quadrado, no mesmo formato de cada quadro, para a imagem não esticar. Com sw-ani-frame-count="20", só os 20 primeiros são usados. Também ocupa a tela inteira.

sw-ani-frame-sprite="6x4" · sw-ani-frame-count="20"
<style>
  .giro-sprite {
    background-image: url('/giro/sprite-6x4.webp');  /* a imagem com a grade de quadros */
    aspect-ratio: 1;             /* mesmo formato de UM quadro */
    height: auto;
    width: min(100%, 100svh);
    margin: 0 auto;
  }
</style>
<div sw-ani="frames" sw-ani-frame-sprite="6x4" sw-ani-frame-count="20" sw-ani-end="200%">
  <div sw-ani-frame-stage class="giro-sprite"></div>
</div>

Tabela de opções

PalavraO que fazExemplo
Peças
sw-ani="frames"O bloco. Ele mesmo calcula a altura (tela + rolagem dos quadros).<div sw-ani="frames">
sw-ani-frame-stageO palco que gruda na tela e mostra o quadro da vez. Filho direto do bloco. Altura da tela inteira.<div sw-ani-frame-stage>
sw-ani-frameCada quadro (normalmente uma <img>), dentro do palco, na ordem. Mínimo de 2. Ocupa o palco inteiro (foto recortada para cobrir).<img sw-ani-frame src="01.webp" alt="">
Sprite (uma imagem só)
sw-ani-frame-spriteGrade da imagem: "colunasxlinhas". A imagem vai como fundo do palco, no seu CSS.sw-ani-frame-sprite="6x4"
sw-ani-frame-countSó com sprite: quantos quadros usar (quando a grade tem espaços vazios no fim). Padrão = colunas × linhas.sw-ani-frame-count="20"
Ritmo
sw-ani-endQuanto de rolagem a sequência inteira consome (% da tela, vh ou px). Maior = troca mais devagar. Padrão: 35% por quadro, no mínimo 300%.sw-ani-end="250%"
data-sw-end-sm / -md / -lgRolagem diferente por tamanho de tela (menor que 768 px / até 1199 px / 1200 px ou mais). Escreva com data-sw-.data-sw-end-sm="150%"
O que o SW Core escreve no bloco
data-sw-frame-activeNúmero do quadro que está aparecendo (1, 2, 3…).[data-sw-frame-active="12"] .fim { … }
--sw-frame-progressVariável CSS de 0 (primeiro quadro) a 1 (último)..barra { transform: scaleX(var(--sw-frame-progress)); }
.is-activeClasse do quadro visível (no modo várias imagens).

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.

Fachada Sala de estar Vista da varanda Quintal Entrada Arredores
<div sw-ani="frames" sw-ani-end="250%">
  <div sw-ani-frame-stage>
    <img sw-ani-frame src="/imovel/fachada.webp" width="1200" height="800" alt="Fachada">
    <img sw-ani-frame src="/imovel/sala.webp" width="1200" height="800" alt="Sala de estar">
    <img sw-ani-frame src="/imovel/varanda.webp" width="1200" height="800" alt="Vista da varanda">
    <!-- … -->
  </div>
</div>
Mostrar "quadro 5 de 24" (evento sw:frame) Referência
<p id="contador">1 de 24</p>

<script>
  document.querySelector('[sw-ani="frames"]').addEventListener('sw:frame', (e) => {
    document.getElementById('contador').textContent = (e.detail.index + 1) + ' de ' + e.detail.total;
  });
</script>
Frames dentro de uma tela do Sections (com legenda que anda) Referência
<!-- dentro de um Sections, quem dá a rolagem é a TELA (sw-ani-h nela) -->
<div sw-ani="sections" sw-ani-fx="cover|fade">
  <section sw-ani-section sw-ani-h="300%">
    <div sw-ani="frames">
      <div sw-ani-frame-stage>
        <img sw-ani-frame src="/giro/01.webp" alt="">
        <img sw-ani-frame src="/giro/02.webp" alt="">
        <!-- … -->
      </div>
    </div>
    <p sw-ani="move" sw-ani-distance="60">Legenda que sobe junto com os quadros</p>
  </section>
  <section sw-ani-section>Próxima tela</section>
</div>

Eventos

sw:frame
Disparado no bloco a cada troca de quadro. e.detail.index (começa em 0) e e.detail.total.

API (JavaScript)

SWMotion.refresh()
Recalcula a altura e os quadros (use se trocar as imagens por JavaScript).

Precisa de quê

  • swcore.min.css + swcore.motion.min.css, e swcore.motion.min.js antes do swcore.min.js.

Cuidados — erros comuns

  • O palco tem que ser filho direto do bloco. Sem palco, nada acontece (aviso no console).
  • No sprite, o SW Core não coloca a imagem: ponha o background-image no palco pelo seu CSS (como no exemplo). Sem isso, o palco fica vazio.
  • No sprite, cada quadro é esticado para o tamanho do palco. Se o palco não tiver o mesmo formato de um quadro, a imagem deforma — ajuste o formato do palco (aspect-ratio).
  • sw-ani-frame-count só vale para sprite. Com várias imagens, o total é o número de sw-ani-frame.
  • Todas as imagens precisam estar carregadas para a troca ser instantânea. Comprima bem e prefira 24–36 quadros a 60.
  • Quadros com tamanhos/proporções diferentes "pulam" na troca: gere todos iguais.

O que ele não faz

  • É o componente mais pesado da família: todos os quadros ficam na página. Meça o peso total antes de publicar.
  • A troca é seca, de imagem em imagem — não existe transição suave entre quadros.
  • Quem ativou "reduzir movimento" no aparelho vê só o primeiro quadro, em uma tela, sem rolagem extra.