Building Iconhub: Manipulasi SVG

Bayu Hendra Winata
Javan Cipta Solusi
Published in
6 min readOct 1, 2020

Prolog

Bagi yang belum tahu, iconhub.io adalah sebuah layanan penyedia icon dalam bentuk SVG. Kita bisa melakukan modifikasi ukuran, ketebalan, dan warna icon secara langsung dan hasilnya akan di-preview secara instan untuk selanjutnya bisa diunduh ataupun disalin kode SVG-nya.

iconhub, practical stunning icons for everyone

Kenapa SVG?

Sebelum menjawab pertanyaan kenapa SVG, kita perlu sedikit menengok ke belakang dan mempelajari bagaimana web developer menampilkan icon di websitenya.

Image

Di awal tahun 2000-an (dan masih sampai sekarang), menampilkan ikon dalam bentuk gambar merupakan teknik yang paling mudah dilakukan karena sebagian browser sudah mendukung tag <img> . Menampilkan ikon tidak ada bedanya dengan menampilkan gambar biasa.

<a href="home.html">
<img src="home.png" alt="Homepage" />
</a>

Teknik ini mudah dilakukan, tapi tidak cukup fleksibel. Gambar memilki keterbatasan styling. Misalnya untuk menambahkan efek hover, kita harus membuat dua buah gambar yang berbeda dan menambahkan CSS yang sesuai. Kekurangan lain, efek hover menjadi tidak smooth karena gambar kedua baru diunduh ketika hover dilakukan, sehingga ada potensi delay ketika hover pertama kali.

Untuk mengatasai permasalahan di atas, muncul sebuah teknik baru yang disebut dengan Image Sprite. Konsepnya, semua image untuk icon dijadikan satu file, lalu gunakan CSS untuk mengatur tampilan ikon yang sesuai.

Contoh image sprite
#house {
display: block;
overflow: hidden;
position: relative;
margin: auto;
width:100%;
text-align: center;
}
#house a {
background: url("https://www.w3schools.com/css/img_navsprites_hover.gif") no-repeat 0 0%;
width: 30%;
height: 0;
padding-top: 28.7%;
background-size: 293%;
display: block;
overflow: hidden;
margin:auto;
}
#house a:hover {
background-position: 0 99.9%;
}

Contoh pemanfaatan image sprite bisa dilihat pada link https://codepen.io/heyMP/pen/awFiy.

Ribet kan? 😅

Font

Dengan CSS, kita bisa mengubah jenis font yang akan ditampilkan di web:

body {
font-family: "Verdana", sans-serif;
}

Tapi, pilihan font yang tersedia tergantung dari OS pengguna. Jika sudah terpasang, maka custom font tersebut bisa tampil. Tentu hal ini mempengaruhi konsistensi tampilan website.

Tentu akan lebih menyenangkan jika pengembang web bisa menyertakan font pilihan mereka sendiri. Inilah yang melatarbelakangi kehadiran fitur @font-face di CSS 3.

Rule CSS “@font-face” sebenarnya sudah hadir sejak tahun 1999, tapi baru di tahun 2009 mulai didukung oleh browser seperti Firefox dan Safari.

@font-face {
font-family: "Open Sans";
src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"),
url("/fonts/OpenSans-Regular-webfont.woff") format("woff");
}

Font biasanya digunakan untuk menampilkan text. Tapi, karena format font sebenarnya adalah vector graphic, maka pengembang font juga bisa membuat font berbentuk ikon.

Artikel berikut ini menjelaskan dengan lebih lengkap: https://code.tutsplus.com/tutorials/quick-tip-ever-thought-about-using-font-face-for-icons--net-11233

Sekarang, kita mengenal https://fontawesome.com/ sebagai salah satu layanan yang memanfaatkan teknik ini.

SVG

SVG adalah salah satu format standard yang digunakan untuk membuat gambar vektor. Gambar vektor bisa kita perbesar semaksimal mungkin dan tetap terjaga ketajamannya. Kebalikannya, gambar raster (gif, jpg, png) bila kita perbesar akan berkurang ketajaman gambarnya.

Gambar vektor vs raster

Berikut ini adalah contoh isi file SVG:

<svg>
<rect x="203" width="200" height="200" style="fill:slategrey; stroke:black; stroke-width:3; -webkit-transform: rotate(45deg);"/>
</svg>

Bisa kita lihat SVG sangat mirip dengan HTML, yang hanya merupakan sekumpulan tag dengan atribut khusus. Karakteristik ini menjadi penting dan merupakan salah satu kelebihan SVG dibanding font: kita bisa membuka dan mengedit SVG dengan text editor biasa. Bahkan kita bisa menyisipkan potongan kode SVG ke dalam HTML, melakukan styling seperti layaknya tag HTML yang lain.

Kelebihan lainnya, menggunakan SVG sebagai icon dibanding font:

  1. SVG bisa membuat icon multi color, sedangkan font tidak bisa.
  2. SVG bisa dibuat animasi, sedangkan font tidak bisa.
  3. SVG bisa di-embed sebagai file terpisah maupun disisipkan secara inline, sedangkan font hanya bisa diembed sebagai file terpisah.

TLDR: SVG icon adalah masa depan 😇

Manipulasi SVG

Kembali ke iconhub.io, salah satu fitur yang disediakan adalah melakukan manipuasi ikon: ukuran, ketebalan garis, dan warna.

iconhub styler

Ketiga atribut di atas, jika diterjemahkan menjadi atribut SVG menjadi:

  • Ukuran, bisa diatur dengan atribut width
  • Ketebalan (stroke), bisa diatur dengan atributstroke-width.
  • Warna, bisa diatur dengan atributstroke dan fill.

Modifikasi dengan CSS

Iterasi pertama, modifikasi dilakukan dengan membuat CSS rule secara dinamis.

// on atribut change
var stylesheet = document.createElement('style');
document.body.appendChild(stylesheet);
let hex = "#FF0000"; // get from color picker
stylesheet.innerHTML = "svg .cls-2 {stroke: " + hex + "}";

Konsepnya sederhana, ketika warna berubah, daftarkan style CSS baru secara realtime ke halaman HTML. Ingat, karena SVG ini sangat mirip dengan HTML, maka cara stylingnya pun juga sama. Kita bisa menggunakan plain CSS svg .primary {stroke: "#FF0000"}.

Kelemahan dari metode ini, style dan kode SVG menjadi terpisah. Ketika kemudian ada kebutuhan SVG yang sudah dimanipulasi bisa disalin kodenya, maka cara ini tidak bisa diterapkan.

Modifikasi Dengan Javascript

Agar SVG hasil modifikasi bisa disalin secara langsung, maka mau tidak mau kita harus memanipulasi DOM SVG secara langsung menggunakan Javascript.

Sebagaimana kita ketahui, setiap DOM html memiliki atribut style . Dari sini, kita tinggal mengeset atribut yang sesuai. Sangat sederhana.

// Definisikan DOM mana saja yang ingin dimanipulasi, menggunakan CSS selector biasa (surprise...)
selector = 'svg.icon.line-color > #primary';
// Iterasi setiap DOM SVG dengan native JS dan ubah stylenya Array.prototype.forEach.call(document.querySelectorAll(selector), function (el) {
el.style.stroke = hex;
});
// Sangat sederhana bukan?

Kode di atas akan mengubah DOM SVG secara langsung, sehingga ketika kita inspect element, kodenya langsung ikut berubah.

SVG DOM manipulation

Konsep yang sama juga berlaku untuk modifikasi ukuran dan ketebalan.

Sebenarnya ada satu library yang cukup bagus untuk berinteraksi dengan SVG, yaitu https://svgjs.com/. Dengan SVGJS, kita bisa membuat SVG baru secara on the fly dengan lebih mudah. Tapi karena saat ini kebutuhan di iconhub masih terbatas pada manipulasi style existing SVG, maka plain old Javascript masih menjadi pilihan.

Finishing Touch

Menambahkan CSS Animation

Agar transisi ukuran ikon lebih smooth, kita bisa memanfaatkan transition bawaan dari CSS.

svg.icon {
transition: width .3s ease-out,height .3s ease-out;
}

Silakan dicoba https://iconhub.io/ dan rasakan sendiri.

Persistent State

Untuk meningkatkan experience, ada kebutuhan agar modifikasi terakhir yang dilakukan oleh user tetap tersimpan meskipun user sudah menutup browser. Jadi, ketika user mengunjungi iconhub lagi, dia masih melihat state terakhir (pilihan warna, ukuran, dan stroke) sama dengan sebelumnya.

Karena belum ada fitur login, maka mau tidak mau state modifikasi ikon harus disimpan di client side.

Ada beberapa pilihan di HTML 5 untuk menyimpan data di client side (browser):

  1. Cookie, cara lama, biasanya digunakan ketika data yang disimpan perlu dikirim ke server untuk dibaca oleh backend side.
  2. IndexedDB, digunakan ketika kita perlu menyimpan data yang cukup banyak dan komplek, seperti layaknya database.
  3. sessionStorage, menyimpan key-value di browser, data hilang ketika tab/browser ditutup. Mirip dengan Cookies, bedanya sessionStorage tidak bisa dibaca oleh server side.
  4. localStorage, mirip sessionStorage, menyimpan key-value di browser, tapi data tidak hilang meskipun tab/browser ditutup. Jadi untuk menghapusnya harus dilakukan secara eksplisit, baik oleh aplikasi ataupun oleh user sendiri.

Dari karakteristik singkat di atas, maka localStorage menjadi pilihan paling tepat untuk menyimpan state di iconhub, karena yang dibutuhkan hanyalah menyimpan key-value sederhana dan persist “selamanya”.

localStorage.setItem('size', size);
Local Storage di iconhub.io

Epilog

Sekian tulisan pertama dari seri “Building iconhub.io”. Selanjutnya kita akan mengupas tentang “Slicing: Dari Figma ke HTML menggunakan TailwindCSS”.

Sudah mencoba iconhub.io? Bagi pengalamanmu lewat komentar ya ;)

iconhub.io teaser

Referensi

--

--