Partilhar: WhatsApp
aulify
UC UC02650 · T. Multimédia

Ficha 02 · Planear as animações de uma landing page

Scroll, hover e transições com pseudo-código
Versão · Aluno
Tempo · 90 minutos
Cotação · 100 pontos
Aluno(a)
Turma
Data
Objectivos da ficha

Parte I · Verdadeiro ou Falso (20 pts)

Indica V ou F e justifica.

  1. O ScrollTrigger (GSAP) permite ligar o progresso de uma animação ao scroll (scrub). (5 pts)
  2. As timelines do GSAP servem para sequenciar e sincronizar várias animações. (5 pts)
  3. O efeito de parallax cria sensação de profundidade movendo camadas à mesma velocidade. (5 pts)
  4. Uma landing page deve funcionar mesmo que as animações estejam desativadas. (5 pts)
  1. V — Com scrub: true, a animação progride conforme o scroll (ligada à posição, não ao tempo).
  2. V — As timelines orquestram sequências com timing relativo (sobreposição, atraso, ordem).
  3. F — O parallax move as camadas a velocidades diferentes (fundo mais lento) para criar profundidade.
  4. V — Progressive enhancement: o conteúdo e a navegação devem funcionar sem depender de animação.

Parte II · Planear as animações (40 pts)

Recebes a estrutura de uma landing page de uma app:

[Header fixo: logo + menu + botão "Descarregar"]
[Hero: título + subtítulo + botão + mockup do telemóvel]
[Funcionalidades: 3 cards]
[Números: 3 estatísticas (ex: 10k utilizadores)]
[Testemunhos: carrossel]
[CTA final + footer]

Planeia as animações interactivas da página, organizadas por tipo: ao carregar (hero), por scroll e por hover. Para cada animação, indica o elemento, o gatilho e o efeito. (40 pts)

Plano de animações (referência)

Ao carregar — Hero (14 pts) | Elemento | Gatilho | Efeito | |---|---|---| | Logo + menu | load | fade-in de cima (timeline) | | Título | load | slide-up + fade, primeiro | | Subtítulo | load | slide-up + fade, com atraso (-0.3s) | | Botão | load | scale de 0.9→1 + fade, por último | | Mockup | load | slide da direita + fade |

(Sequenciar com uma timeline GSAP.)

Por scroll (14 pts) | Elemento | Gatilho | Efeito | |---|---|---| | 3 cards de funcionalidades | entram no viewport (Intersection Observer) | fade-up em cascata (stagger) | | Estatísticas | entram no viewport | contador a animar de 0 ao valor | | Secções de imagem | scroll | leve parallax do fundo | | Header | scroll para baixo | encolher/adicionar sombra |

Por hover (12 pts) | Elemento | Gatilho | Efeito | |---|---|---| | Cards | mouseenter | elevar (translateY) + sombra | | Botões | hover | mudar cor + subir 2px | | Links do menu | hover | sublinhado a crescer | | Setas do carrossel | hover | scale + cor |

Acessibilidade: todas as animações reduzidas/desligadas sob prefers-reduced-motion.

(Avaliar: cobertura dos três tipos, elementos coerentes com a estrutura, gatilhos correctos.)

Parte III · Pseudo-código de uma animação por scroll (40 pts)

Escolhe a animação dos 3 cards de funcionalidades (fade-up em cascata quando entram no viewport) e escreve o pseudo-código (ou código real) que a implementa, garantindo: (a) só animam quando entram; (b) animam em cascata (stagger); (c) respeitam prefers-reduced-motion. (40 pts)

Pseudo-código / código (referência)

Opção A — Intersection Observer + CSS (cascata via delay)

.card { opacity: 0; transform: translateY(30px); transition: .6s ease; }
.card.visivel { opacity: 1; transform: translateY(0); }
.card:nth-child(1).visivel { transition-delay: 0s; }
.card:nth-child(2).visivel { transition-delay: .15s; }
.card:nth-child(3).visivel { transition-delay: .3s; }

@media (prefers-reduced-motion: reduce) {
  .card { transition: none; opacity: 1; transform: none; }
}
const cards = document.querySelectorAll('.card');
const obs = new IntersectionObserver((entries) => {
  entries.forEach(e => {
    if (e.isIntersecting) {
      e.target.classList.add('visivel');
      obs.unobserve(e.target);   // anima só uma vez
    }
  });
}, { threshold: 0.2 });

cards.forEach(c => obs.observe(c));

Opção B — GSAP + ScrollTrigger (stagger nativo)

gsap.registerPlugin(ScrollTrigger);

const reduz = matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!reduz) {
  gsap.from('.card', {
    y: 30, opacity: 0, duration: 0.6, stagger: 0.15,
    scrollTrigger: { trigger: '.funcionalidades', start: 'top 80%' }
  });
}

Critérios: - (a) Anima ao entrar no viewport (observer / ScrollTrigger start). - (b) Cascata (stagger via delay ou stagger). - (c) Trata prefers-reduced-motion. - Animar opacity + transform (performante). - Bónus: animar só uma vez (unobserve).