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

Ficha 01 · Animação CSS e performance

Conceitos, escrever CSS e corrigir animação lenta
Versão · Aluno
Tempo · 90 minutos
Cotação · 100 pontos
Aluno(a)
Turma
Data
Objectivos da ficha

Parte I · Verdadeiro ou Falso (30 pts)

Indica V ou F e justifica.

  1. Animar transform e opacity é geralmente mais performante do que animar width e left. (5 pts)
  2. O requestAnimationFrame é menos suave que o setInterval para animações. (5 pts)
  3. O Intersection Observer permite detectar quando um elemento entra no viewport sem ouvir o evento scroll continuamente. (5 pts)
  4. O media query prefers-reduced-motion serve para respeitar utilizadores que preferem menos animação. (5 pts)
  5. Uma transition em CSS é adequada para animar a mudança entre dois estados (ex: hover). (5 pts)
  6. O GSAP só funciona com a propriedade transform. (5 pts)
  1. Vtransform/opacity correm no compositor (GPU), sem reflow; width/left provocam reflow/repaint, mais caros.
  2. F — É o contrário: o requestAnimationFrame sincroniza com o refresh do ecrã (~60 fps), sendo mais suave e eficiente que setInterval.
  3. V — O Intersection Observer notifica de forma eficiente sem ouvir scroll constantemente.
  4. V — Respeita a preferência de acessibilidade de reduzir movimento (evita náuseas/desconforto).
  5. V — As transitions são ideais para animar entre dois estados (default ↔ hover/focus).
  6. F — O GSAP anima praticamente qualquer propriedade numérica (cor, opacidade, posição, etc.), não só transform.

Parte II · Escrever CSS para uma animação (35 pts)

Implementa as seguintes animações em CSS.

Exercício 1 · Botão com hover (15 pts)

Cria um botão .cta que, ao passar o rato, sobe ligeiramente (2 px), escurece o fundo e mostra uma sombra, tudo com transição suave.

.cta {
  background: #4F46E5;
  color: #fff;
  padding: 12px 24px;
  border: none;
  border-radius: 8px;
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(0,0,0,.15);
  transition: transform .2s ease, background .3s ease, box-shadow .3s ease;
  cursor: pointer;
}
.cta:hover {
  background: #4338CA;
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(0,0,0,.25);
}

(Avaliar: uso de transition nas propriedades certas, translateY no hover, escurecer + sombra.)

Exercício 2 · Loader com keyframes (20 pts)

Cria um spinner circular .loader que roda continuamente (360°), usando @keyframes.

.loader {
  width: 40px;
  height: 40px;
  border: 4px solid #e5e7eb;        /* anel claro */
  border-top-color: #4F46E5;        /* segmento colorido */
  border-radius: 50%;
  animation: rodar 0.8s linear infinite;
}

@keyframes rodar {
  to { transform: rotate(360deg); }
}

/* Acessibilidade */
@media (prefers-reduced-motion: reduce) {
  .loader { animation-duration: 1.5s; }
}

(Avaliar: @keyframes com rotate, animation infinite, círculo correcto; bónus por considerar reduced-motion.)

Parte III · Corrigir animação com problemas de performance (35 pts)

O código seguinte anima um card a deslizar e crescer, mas está "aos saltos" (não chega a 60 fps). Identifica os problemas de performance e reescreve o CSS de forma performante.

.card {
  position: absolute;
  left: 0;
  width: 200px;
  height: 120px;
  transition: left 0.4s, width 0.4s, height 0.4s;
}
.card.activo {
  left: 300px;
  width: 260px;
  height: 160px;
}

Problemas identificados (15 pts) - Anima left, width e height → cada uma provoca reflow/repaint em todos os frames, o que é caro e causa "saltos". - Estas propriedades não correm na GPU/compositor.

Solução: usar transform (20 pts)

.card {
  position: absolute;
  left: 0;
  width: 200px;
  height: 120px;
  transform: translateX(0) scale(1);
  transform-origin: left top;
  transition: transform 0.4s ease;
  will-change: transform;   /* enquanto anima */
}
.card.activo {
  /* deslocar 300px e crescer ~1.3x via scale */
  transform: translateX(300px) scale(1.3);
}

Explicação: - translateX substitui a animação de left. - scale substitui a animação de width/height (crescimento proporcional). - Apenas transform é animado → corre no compositor, atingindo 60 fps. - will-change: transform prepara a optimização (idealmente só durante a animação).

(Aceita-se nota de que o scale altera proporção; se for preciso manter dimensões exactas sem distorção, comentar o trade-off. O essencial é trocar left/width/height por transform.)