Saya baru-baru ini membuat pola dinding bata sebagai bagian dari #PetitePola series, sebuah tantangan di mana saya membuat pola atau tekstur yang terlihat organik di SVG dalam 560 byte (atau kira-kira seukuran dua tweet). Agar sesuai dengan batasan ini, saya telah melalui perjalanan yang telah mengajari saya beberapa cara radikal untuk mengoptimalkan pola SVG sehingga mereka mengandung kode sesedikit mungkin tanpa mempengaruhi kualitas gambar secara keseluruhan.
Saya ingin memandu Anda melalui proses dan menunjukkan kepada Anda bagaimana kami dapat mengambil pola SVG yang dimulai dari 197 byte hingga hanya 44 byte — pengurangan sebesar 77.7%!
Pola SVG
Inilah yang disebut pola bata “ikatan berjalan”. Ini adalah pola bata yang paling umum di luar sana, dan yang pasti pernah Anda lihat sebelumnya: setiap baris bata diimbangi dengan setengah panjang bata, menciptakan pola terhuyung-huyung yang berulang. Pengaturannya cukup sederhana, membuat SVG <pattern>
elemen yang sangat cocok untuk mereproduksinya dalam kode.
SVG <pattern>
elemen menggunakan objek grafik yang telah ditentukan sebelumnya yang dapat direplikasi (atau "dipetakan") pada interval tetap sepanjang sumbu horizontal dan vertikal. Pada dasarnya, kami mendefinisikan pola ubin persegi panjang dan itu akan diulang untuk mengecat area isian.
Pertama, mari kita atur dimensi bata dan jarak antara masing-masing bata. Demi kesederhanaan, mari gunakan angka bulat yang bersih: lebar 100
dan tinggi 30
untuk batu bata, dan 10
untuk celah horizontal dan vertikal di antara mereka.
Selanjutnya, kita harus mengidentifikasi ubin "dasar" kita. Dan dengan "ubin" saya berbicara tentang ubin pola daripada ubin fisik, tidak menjadi bingung dengan batu bata. Mari kita gunakan bagian yang disorot dari gambar di atas sebagai ubin pola kita: dua bata utuh di baris pertama, dan satu utuh diapit di antara dua setengah bata di baris kedua. Perhatikan bagaimana dan di mana celah dimasukkan, karena itu perlu dimasukkan dalam ubin pola berulang.
Ketika menggunakan <pattern>
, kita harus mendefinisikan polanya width
dan height
, yang sesuai dengan lebar dan tinggi ubin dasar. Untuk mendapatkan dimensi, kita perlu sedikit matematika:
Tile Width = 2(Brick Width) + 2(Gap) = 2(100) + 2(10) = 220
Tile Height = 2(Bright Height) + 2(Gap) = 2(30) + 2(10) = 80
Baiklah, jadi ubin pola kita adalah 220✕80
. Kita juga harus mengatur patternUnits
atribut, di mana nilai userSpaceOnUse
dasarnya berarti piksel. Akhirnya, menambahkan id
untuk pola itu diperlukan agar bisa menjadi acuan saat kita melukis elemen lain dengannya.
<pattern id="p" width="220" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
Sekarang kita telah menetapkan dimensi petak, tantangannya adalah membuat kode untuk petak dengan cara yang membuat grafik dengan jumlah byte sekecil mungkin. Inilah yang kami harapkan pada akhirnya:
Markup awal (197 byte)
Pendekatan paling sederhana dan paling deklaratif untuk membuat ulang pola ini yang muncul di benak saya adalah menggambar lima persegi panjang. Secara default, fill
dari elemen SVG berwarna hitam dan stroke
transparan. Ini bekerja dengan baik untuk mengoptimalkan pola SVG, karena kita tidak harus secara eksplisit mendeklarasikannya dalam kode.
Setiap baris dalam kode di bawah ini mendefinisikan persegi panjang. Itu width
dan height
selalu diatur, dan x
dan y
posisi hanya diatur jika persegi panjang diimbangi dari 0
posisi.
<rect width="100" height="30"/>
<rect x="110" width="100" height="30"/>
<rect y="40" width="45" height="30"/>
<rect x="55" y="40" width="100" height="30"/>
<rect x="165" y="40" width="55" height="30"/>
Baris atas ubin berisi dua batu bata lebar penuh, batu bata kedua diposisikan untuk x="110"
memungkinkan 10
piksel celah sebelum bata. Demikian pula ada 10
piksel celah setelahnya, karena bata berakhir di 210
piksel (110 + 100 = 210
) pada sumbu horizontal meskipun <pattern>
lebarnya 220
piksel. Kami membutuhkan sedikit ruang ekstra; jika tidak, bata kedua akan bergabung dengan bata pertama di ubin yang berdekatan.
Batu bata di baris kedua (bawah) diimbangi sehingga baris berisi dua setengah bata dan satu bata utuh. Dalam hal ini, kami ingin bata setengah lebarnya menyatu sehingga tidak ada celah di awal atau akhir, memungkinkan mereka mengalir mulus dengan bata di ubin pola yang berdampingan. Saat mengimbangi batu bata ini, kami juga harus memasukkan setengah celah, sehingga x
nilai adalah 55
dan 165
, Masing-masing.
Penggunaan kembali elemen, (-43B, total 154B)
Tampaknya tidak efisien untuk mendefinisikan setiap batu bata secara eksplisit. Apakah tidak ada cara untuk mengoptimalkan pola SVG dengan menggunakan kembali bentuknya?
Saya tidak berpikir bahwa SVG memiliki <use>
elemen. Anda dapat mereferensikan elemen lain dengannya dan merender elemen yang direferensikan itu di mana pun <use>
digunakan. Ini menghemat beberapa byte karena kita dapat menghilangkan menentukan lebar dan tinggi setiap bata, kecuali yang pertama.
Yang mengatakan, <use>
datang dengan sedikit harga. Artinya, kita harus menambahkan id
untuk elemen yang ingin kita gunakan kembali.
<rect id="b" width="100" height="30"/>
<use href="#b" x="110"/>
<use href="#b" x="-55" y="40"/>
<use href="#b" x="55" y="40"/>
<use href="#b" x="165" y="40"/>
Terpendek id
mungkin adalah satu karakter, jadi saya memilih "b" untuk bata. Itu <use>
elemen dapat diposisikan mirip dengan <rect>
, Dengan x
dan y
atribut sebagai offset. Karena setiap bata lebarnya penuh sekarang setelah kita beralih ke <use>
(ingat, kami secara eksplisit membagi dua batu bata di baris kedua ubin pola), kami harus menggunakan negatif x
nilai di baris kedua, lalu pastikan bata terakhir meluap dari ubin untuk koneksi mulus antar bata. Ini tidak apa-apa, karena apa pun yang berada di luar ubin pola akan otomatis terpotong.
Dapatkah Anda menemukan beberapa string berulang yang dapat ditulis dengan lebih efisien? Mari kita kerjakan yang berikutnya.
Menulis ulang ke jalur (-54B, total 100B)
<path>
mungkin adalah elemen paling kuat di SVG. Anda dapat menggambar hampir semua bentuk dengan "perintah" di dalamnya d
atribut. Ada 20 perintah yang tersedia, tetapi kita hanya membutuhkan yang paling sederhana untuk persegi panjang.
Di sinilah saya mendarat dengan itu:
<path d="M0 0h100v30h-100z M110 0h100v30h-100 M0 40h45v30h-45z M55 40h100v30h-100z M165 40h55v30h-55z"/>
Saya tahu, angka dan huruf yang sangat aneh! Semuanya punya arti, tentu saja. Inilah yang terjadi dalam kasus khusus ini:
M{x} {y}
: Berpindah ke suatu titik berdasarkan koordinat.z
: Menutup segmen saat ini.h{x}
: Menarik garis horizontal dari titik saat ini, dengan panjangx
dalam arah yang ditentukan oleh tandax
. Huruf kecilx
menunjukkan koordinat relatif.v{y}
: Menarik garis vertikal dari titik saat ini, dengan panjangy
dalam arah yang ditentukan oleh tanday
. Huruf kecily
menunjukkan koordinat relatif.
Markup ini jauh lebih singkat daripada yang sebelumnya (jeda baris dan spasi lekukan hanya untuk keterbacaan). Dan, hei, kami telah berhasil memotong setengah dari ukuran awal, mencapai 100 byte. Tetap saja, ada sesuatu yang membuatku merasa ini bisa lebih kecil…
Revisi ubin (-38B, total 62B)
Bukankah ubin pola kami memiliki bagian yang berulang? Jelas bahwa di baris pertama seluruh bata diulang, tetapi bagaimana dengan baris kedua? Agak sulit untuk dilihat, tetapi jika kita memotong bata tengah menjadi dua, itu menjadi jelas.
Nah, batu bata tengah tidak benar-benar dipotong menjadi dua. Ada sedikit penyeimbangan karena kami juga harus memperhitungkan celahnya. Bagaimanapun, kami baru saja menemukan pola ubin dasar yang lebih sederhana, yang berarti lebih sedikit byte! Ini juga berarti kita harus membagi dua width
dari kami <pattern>
elemen dari 220 hingga 110.
<pattern id="p" width="110" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
Sekarang mari kita lihat bagaimana ubin yang disederhanakan digambar dengan <path>
:
<path d="M0 0h100v30h-100z M0 40h45v30h-45z M55 40h55v30h-55z"/>
Ukurannya dikurangi menjadi 62 byte, yang sudah kurang dari sepertiga dari ukuran aslinya! Tapi mengapa berhenti di sini ketika ada lebih banyak lagi yang bisa kita lakukan!
Memperpendek perintah jalur (-9B, total 53B)
Ada baiknya untuk masuk lebih dalam ke <path>
elemen karena memberikan lebih banyak petunjuk untuk mengoptimalkan pola SVG. Satu kesalahpahaman yang saya miliki ketika bekerja dengan <path>
adalah tentang bagaimana fill
atribut bekerja. Setelah banyak bermain dengan MS Paint di masa kecil saya, saya telah belajar bahwa setiap bentuk yang ingin saya isi dengan warna solid harus ditutup, yaitu tidak memiliki titik terbuka. Jika tidak, cat akan bocor keluar dari bentuknya dan tumpah ke segala sesuatu.
Di SVG, bagaimanapun, ini tidak benar. Izinkan saya mengutip spesifikasi diri:
Operasi pengisian mengisi subpath terbuka dengan melakukan operasi pengisian seolah-olah perintah "closepath" tambahan ditambahkan ke path untuk menghubungkan titik terakhir subpath dengan titik pertama subpath.
Ini berarti kita dapat menghilangkan perintah close path (z
), karena subpath dianggap otomatis ditutup saat diisi.
Hal lain yang berguna untuk diketahui tentang perintah jalur adalah bahwa mereka datang dalam variasi huruf besar dan kecil. Huruf kecil berarti bahwa koordinat relatif digunakan; huruf besar berarti koordinat absolut digunakan sebagai gantinya.
Ini sedikit lebih rumit dari itu dengan H
dan V
perintah karena mereka hanya menyertakan satu koordinat. Inilah cara saya menggambarkan dua perintah ini:
H{x}
: Menarik garis horizontal dari titik saat ini ke koordinatx
.V{y}
: Menarik garis vertikal dari titik saat ini ke koordinaty
.
Saat kita menggambar bata pertama di ubin pola, kita mulai dari (0,0)
koordinat. Kami kemudian menggambar garis horizontal ke (100,0)
dan garis vertikal ke (100,30)
, dan akhirnya, tarik garis horizontal ke (0,30)
. Kami menggunakan h-100
perintah di baris terakhir, tetapi itu setara dengan H0
, yang merupakan dua byte, bukan lima. Kami dapat mengganti dua kejadian serupa dan mengupas kode kami <path>
sampai ini:
<path d="M0 0h100v30H0 M0 40h45v30H0 M55 40h55v30H55"/>
9 byte lainnya dipangkas — seberapa kecil kita bisa pergi?
Menjembatani (-5B, total 48B)
Perintah terpanjang yang menghalangi pola SVG yang sepenuhnya dioptimalkan adalah perintah "pindah ke" yang masing-masing mengambil 4, 5, dan 6 byte. Salah satu kendala yang kami miliki adalah bahwa:
Segmen data jalur (jika ada) harus dimulai dengan perintah "moveto".
Tapi tidak apa-apa. Yang pertama adalah yang terpendek. Jika kita menukar baris, kita dapat menemukan definisi jalur di mana kita hanya perlu bergerak secara horizontal atau vertikal di antara bata. Bagaimana jika kita bisa menggunakan h
dan v
perintah di sana alih-alih M
?
Diagram di atas menunjukkan bagaimana tiga bentuk dapat digambar dengan satu jalur. Perhatikan bahwa kami memanfaatkan fakta bahwa fill
operasi secara otomatis menutup bagian terbuka antara (110,0)
dan (0,0)
. Dengan penataan ulang ini, kami juga memindahkan celah ke kiri bata lebar penuh di baris kedua. Begini tampilan kodenya, masih dipecah menjadi satu bata per baris:
<path d="M0 0v30h50V0 h10v30h50 v10H10v30h100V0"/>
Tentunya, kami telah menemukan solusi terkecil mutlak sekarang setelah kami turun menjadi 48 byte, bukan?! Sehat…
Pemangkasan digit (-4B, total 44B)
Jika Anda bisa sedikit fleksibel dengan dimensi, ada sedikit cara lain untuk mengoptimalkan pola SVG. Kami telah bekerja dengan lebar bata 100
piksel, tapi itu tiga byte. Mengubahnya menjadi 90
berarti satu byte lebih sedikit setiap kali kita perlu menulisnya. Demikian pula, kami menggunakan celah 10
piksel — tetapi jika kita mengubahnya menjadi 8
sebagai gantinya, kami menyimpan satu byte pada setiap kejadian tersebut.
<path d="M0 0v30h45V0 h8v30h45 v8H8v30h90V0"/>
Tentu saja, ini juga berarti kita harus menyesuaikan dimensi pola yang sesuai. Inilah kode pola SVG akhir yang dioptimalkan:
<pattern id="p" width="98" height="76" patternUnits="userSpaceOnUse"> <path d="M0 0v30h45V0h8v30h45v8H8v30h90V0"/>
</pattern>
Baris kedua dalam cuplikan di atas — tidak termasuk lekukan — adalah 44 byte. Kami sampai di sini dari 197 byte dalam enam iterasi. Itu gemuk Pengurangan ukuran 77.7%!
Saya bertanya-tanya ... apakah ini benar-benar ukuran sekecil mungkin? Sudahkah kita melihat semua cara yang mungkin untuk mengoptimalkan pola SVG?
Saya mengundang Anda untuk mencoba dan memperkecil kode ini lebih lanjut, atau bahkan bereksperimen dengan metode alternatif untuk mengoptimalkan pola SVG. Saya ingin melihat apakah kita dapat menemukan minimum global yang sebenarnya dengan kebijaksanaan orang banyak!
Lebih lanjut tentang membuat dan mengoptimalkan pola SVG
Jika Anda tertarik untuk mempelajari lebih lanjut tentang membuat dan mengoptimalkan pola SVG, baca artikel saya tentang membuat pola dengan filter SVG. Atau, jika Anda ingin melihat galeri 60+ pola, Anda dapat melihat Koleksi Pena Kode PetitePatterns. Terakhir, selamat menonton tutorial saya di youtube untuk membantu Anda lebih mendalami pola SVG.
Mengoptimalkan Pola SVG ke Ukuran Terkecil awalnya diterbitkan pada Trik CSS. Kamu harus dapatkan buletin.
- "
- 10
- 100
- 77
- 9
- 98
- Tentang Kami
- Mutlak
- Akun
- Tambahan
- Semua
- Membiarkan
- sudah
- Lain
- pendekatan
- DAERAH
- artikel
- atribut
- tersedia
- kapak
- Bit
- Black
- menantang
- perubahan
- tertutup
- kode
- Umum
- koneksi
- mengandung
- Konten
- mengkoordinasikan
- bisa
- membuat
- terbaru
- data
- lebih dalam
- turun
- berakhir
- mapan
- segala sesuatu
- contoh
- Kecuali
- eksperimen
- Akhirnya
- Pertama
- cocok
- aliran
- ditemukan
- lebih lanjut
- celah
- mendapatkan
- Aksi
- memiliki
- tinggi
- membantu
- di sini
- Disorot
- Seterpercayaapakah Olymp Trade? Kesimpulan
- HTTPS
- mengenali
- gambar
- memasukkan
- termasuk
- IT
- Diri
- dikenal
- bocor
- BELAJAR
- belajar
- leveraging
- baris
- sedikit
- tampak
- cinta
- MEMBUAT
- Membuat
- berhasil
- matematika
- keberatan
- lebih
- paling
- pindah
- MS
- jumlah
- nomor
- mengimbangi
- Oke
- Buka
- dioptimalkan
- jika tidak
- pola
- fisik
- Titik
- diposisikan
- mungkin
- kuat
- cukup
- harga pompa cor beton mini
- proses
- menyediakan
- kualitas
- bulat
- berjalan
- Tersebut
- mulus
- Seri
- set
- bentuk
- mirip
- Sederhana
- ENAM
- Ukuran
- So
- larutan
- sesuatu
- Space
- Spot
- awal
- dimulai
- Didukung
- pembicaraan
- Melalui
- puncak
- jelas
- tutorial
- menggunakan
- nilai
- View
- W3
- Menonton
- selamat datang
- Apa
- dalam
- tanpa
- Kerja
- kerja
- bekerja
- bernilai
- Youtube