SVG Animation — Creative Web

SVG Animation SVG (Scalable Vector Graphics) bisa dianimasikan dengan tiga cara: SMIL (animate element bawaan SVG), CSS animation, dan JavaScript…

SVG (Scalable Vector Graphics) adalah gambar yang ditulis sebagai elemen di dalam HTML: "garis dari sini ke sana", "lingkaran di titik ini". Bayangin file potong mesin cutting stiker: isinya cuma petunjuk jalur pisau, jadi bisa dipotong sekecil label atau sebesar spanduk tanpa pecah. Di lesson ini logo Raka (garis kaos, biji kopi di dada, tulisan RAKA) kita buat dengan SVG, lalu kita animasikan: garisnya menggambar dirinya sendiri, bijinya muncul, tulisannya memudar masuk.

🧪 Tebakan cepat: garis kaos di logo panjangnya 358,9. Kalau stroke-dasharray diisi tebakan 300, lalu stroke-dashoffset dianimasikan dari 300 ke 0, apa yang terlihat di akhir: garis utuh, atau ada bagian yang gak pernah tergambar? Tebak dulu, jawabannya ada di bagian "Garis yang menggambar dirinya sendiri".

SVG, viewBox, dan path

<svg viewBox="0 0 120 140" width="240" height="280" role="img" aria-label="Logo Raka: kaos dengan biji kopi">
  <rect width="120" height="140" rx="12" fill="#1c1917" />
  <path class="kaos" d="M45 18 L25 24 L8 42 L20 54 L30 46 L30 102 L90 102 L90 46 L100 54 L112 42 L95 24 L75 18 L60 28 Z"
        fill="none" stroke="#f5e6c8" stroke-width="4" stroke-linejoin="round" />
  <g class="biji">
    <ellipse cx="76" cy="62" rx="7" ry="10" fill="#c47a3d" />
    <path d="M76 54 Q72 62 76 70" fill="none" stroke="#1c1917" stroke-width="2" />
  </g>
  <text class="teks" x="60" y="128" text-anchor="middle" font-size="18" font-weight="bold" fill="#f5e6c8">RAKA</text>
</svg>

Animasi dengan CSS, dan jebakan titik putar

Biji kopi muncul dengan membesar dari 0 sambil berputar:

.biji {
  transform-box: fill-box;   /* kotak acuan = kotak biji itu sendiri */
  transform-origin: center;
  animation: muncul 0.5s 2s ease-out both;
}
@keyframes muncul {
  from { transform: scale(0) rotate(-90deg); }
}

Di elemen SVG, transform-origin bawaannya 0 0, yaitu pojok kiri atas viewBox, dan transform-box bawaannya view-box. Jadi transform-origin: center saja berarti tengah seluruh logo (60, 70), bukan tengah biji. Diukur saat biji setengah jalan, scale(0.5) rotate(-45deg) (Chrome, Firefox dan Safari sama):

CSS di .biji Titik putar Pusat biji saat setengah jalan
tanpa transform-origin (0, 0), pojok kiri atas sekitar (49, -5): di luar logo
transform-origin: center (60, 70), tengah logo sekitar (63, 62): melayang dari tengah
transform-box: fill-box + center (76, 62), tengah biji (76, 62): diam di tempat

both di animation menahan keadaan from (ukuran 0) selama jeda 2 detik, jadi biji gak terlihat sebelum waktunya.

Garis yang menggambar dirinya sendiri

stroke-dasharray membuat garis jadi putus-putus. Satu angka berarti dash sepanjang itu, lalu celah sepanjang itu juga. stroke-dashoffset menggeser pola itu sepanjang garis. Triknya: dash dan celah dibuat sepanjang garis. Offset sepanjang garis berarti yang menutupi garis adalah celahnya (tak terlihat); offset 0 berarti dash-nya (utuh).

Panjangnya diukur dengan JavaScript:

const kaos = document.querySelector('.kaos');
console.log(kaos.getTotalLength()); // 358.8880615234375

Chrome, Firefox dan Safari memberi angka yang sama. Bulatkan ke atas (Math.ceil) jadi 359:

.kaos {
  stroke-dasharray: 359;
  stroke-dashoffset: 0;               /* keadaan dasar: garis utuh */
  animation: gambar 2s ease-out both;
}
@keyframes gambar {
  from { stroke-dashoffset: 359; }    /* awal: tersembunyi */
}
.teks { animation: pudar 0.6s 2.3s both; }
@keyframes pudar { from { opacity: 0; } }

Offset di tengah jalan = panjang × (1 - persen / 100):

Progres stroke-dashoffset Yang terlihat
0% 359 belum ada
25% 269,25 89,75 satuan pertama
50% 179,5 separuh garis
100% 0 garis utuh

Dengan tebakan 300, dash-nya 300 dan celahnya 300. Di akhir, satuan 0 sampai 300 tertutup dash, tapi 300 sampai 358,9 jatuh di celah: 58,9 satuan terakhir (kerah V dan bahu kanan) gak pernah tergambar. Itu jawaban tebakannya. Lebih aneh lagi, di awal animasi potongan yang sama malah sudah terlihat. Alternatifnya, pathLength="100" di <path> membuat garis dihitung sepanjang 100, jadi stroke-dasharray: 100 selalu pas.

SMIL: animasi di dalam SVG

SVG punya elemen animasi sendiri, ditaruh di dalam elemen yang dianimasikan:

<path class="kaos" d="..." stroke-dasharray="359" stroke-dashoffset="359">
  <animate attributeName="stroke-dashoffset" from="359" to="0" dur="2s" fill="freeze" />
</path>

CSS tetap biasanya lebih dipilih: ilmunya sama dengan animasi CSS lain, @media (prefers-reduced-motion: reduce) bisa mematikannya, dan JavaScript bisa mengendalikannya lewat element.getAnimations() (jeda, putar, lompat ke detik tertentu). Media query CSS gak menyentuh SMIL; untuk menghentikannya kamu butuh svg.pauseAnimations().

@media (prefers-reduced-motion: reduce) {
  .kaos, .biji, .teks { animation: none; } /* langsung keadaan akhir */
}

Ini jalan karena keadaan dasarnya adalah keadaan akhir (offset 0, ukuran biasa, opacity 1); keadaan awal cuma ada di from.

SVG atau canvas?

SVG Canvas
Isinya elemen di DOM pixel
Diperbesar tetap tajam harus digambar ulang dengan DPR
Klik di satu bentuk addEventListener di elemennya hit testing sendiri
Banyak benda puluhan sampai ratusan ribuan partikel tiap frame
Cocok untuk logo, ikon, ilustrasi, chart partikel, game, efek per pixel

Logo Raka cocok jadi SVG; uap dengan puluhan partikel per detik cocok di canvas.

⚠️ Jebakan yang sering ketemu

TL;DR: SVG adalah gambar vektor sebagai elemen DOM: viewBox menentukan koordinatnya, d di path berisi perintah M, L, H, V, Q, C, Z. Animasikan dengan CSS: untuk scale atau rotate di elemen SVG, pasang transform-box: fill-box plus transform-origin: center, karena bawaannya pojok viewBox. Efek menggambar garis: stroke-dasharray dan stroke-dashoffset sepanjang garis (diukur getTotalLength(), logo Raka 358,9 jadi 359), lalu animasikan offset dari panjang ke 0; di tengah jalan offset = panjang × (1 - persen / 100). SMIL (<animate>, repeatCount, fill="freeze") jalan di semua browser sekarang, tapi CSS lebih mudah dikendalikan dan dimatikan untuk prefers-reduced-motion. SVG untuk logo dan ikon, canvas untuk ribuan partikel.

Yang akan kamu pelajari