Skip to main content

Loops com offset e stagger

O loop básico faz uma layer repetir. Para fazer múltiplas layers repetirem com timing escalonado, criando aquela cascata de animação, você precisa de um pouco mais de matemática.

O problema do stagger em loop

Se você aplica loopOut("cycle") em 5 layers com os mesmos keyframes, todas fazem loop em sincronia. Você quer que cada uma esteja numa fase diferente do ciclo.

Solução 1: offset manual

A mais simples: coloque os keyframes em posições diferentes na timeline para cada layer.

Layer 1: keyframes no frame 0
Layer 2: keyframes no frame 5
Layer 3: keyframes no frame 10...

Tedioso para muitas layers, mas funciona perfeitamente.

Solução 2: valueAtTime com delay

Aplique a expressão em uma layer master e use valueAtTime nas outras com delay.

Na layer 1 (master): keyframes normais + loopOut("cycle")

Nas layers 2, 3, 4… (escravas):

// delay de 5 frames por layer
var delay = (thisLayer.index - 1) * 5 * thisComp.frameDuration;
thisComp.layer("Layer 1").transform.position.valueAtTime(time - delay)

Cada layer reproduz o valor da master com atraso. Como todas fazem loop, o resultado é um stagger natural.

Solução 3: phase no Math.sin

Para loops baseados em funções trigonométricas, o phase resolve tudo:

var freq = 1;
var amp = 100;
var phase = thisLayer.index * (2 * Math.PI / thisComp.numLayers);
// distribui as fases igualmente entre todas as layers
Math.sin(time * freq * 2 * Math.PI + phase) * amp

Resultado: cada layer está numa posição diferente do ciclo senoidal, criando uma onda perfeita.

Solução 4: offset no loopOut via index

var cycleDuration = 1; // segundos por ciclo
var delay = thisLayer.index * cycleDuration / thisComp.numLayers;
// implementação requer valueAtTime combinado

Stagger de onda

Para criar uma onda visual onde cada layer é um “dente de pente”:

var freq = 0.5; // ondas por segundo
var amp = 80;
var speed = 2; // velocidade de propagação da onda
// Position Y com onda que se propaga
var x = thisLayer.transform.position[0];
var phase = x / thisComp.width * Math.PI * 2 * speed;
[value[0], thisComp.height/2 + Math.sin(time * freq * 2 * Math.PI - phase) * amp]

Cada layer em X diferente terá uma fase diferente, criando onda que parece se propagar horizontalmente.

Sincronizando loops com um controlador

Para controlar o timing de todas as layers de um único lugar:

// no nulo "LOOP CONTROL", slider "Cycle Duration"
var cycleDuration = thisComp.layer("LOOP CONTROL").effect("Cycle Duration")("Slider");
var delay = thisLayer.index * cycleDuration / thisComp.numLayers;
// use no valueAtTime de uma layer master