Yakın zamanda, projemin bir parçası olarak bir tuğla duvar deseni oluşturdum. #PetiteDesenler 560 bayt (veya yaklaşık iki tweet boyutunda) içinde SVG'de organik görünümlü desenler veya dokular oluşturduğum bir meydan okuma. Bu kısıtlamaya uymak için, genel görüntü kalitesini etkilemeden mümkün olduğunca az kod içerecek şekilde SVG kalıplarını optimize etmenin bazı radikal yollarını öğreten bir yolculuktan geçtim.
Size süreç boyunca yol göstermek ve 197 bayttan başlayıp yalnızca 44 bayta kadar uzanan bir SVG modelini nasıl alabileceğimizi göstermek istiyorum - %77.7 gibi büyük bir azalma!
SVG modeli
Bu, "çalışan bağ" tuğla deseni olarak adlandırılan şeydir. Dışarıdaki en yaygın tuğla deseni ve kesinlikle daha önce görmüş olduğunuz bir modeldir: Her bir tuğla sırası, bir tuğla uzunluğunun yarısı kadar kaydırılır ve tekrar eden kademeli bir desen oluşturur. Düzenleme oldukça basit, SVG'leri <pattern>
öğe, kodda yeniden oluşturmak için mükemmel bir uyum.
SVG <pattern>
eleman, yatay ve dikey eksenler boyunca sabit aralıklarla kopyalanabilen (veya "döşenebilen") önceden tanımlanmış bir grafik nesnesi kullanır. Esasen, dikdörtgen bir karo deseni tanımlarız ve dolgu alanını boyamak için tekrarlanır.
İlk olarak, bir tuğlanın boyutlarını ve her tuğla arasındaki boşluğu ayarlayalım. Basitlik adına, temiz, yuvarlak sayılar kullanalım: 100
ve yüksekliği 30
tuğla için ve 10
aralarındaki yatay ve dikey boşluklar için.
Ardından, “temel” döşememizi tanımlamamız gerekiyor. Ve “kiremit” derken, tuğlalarla karıştırılmaması için fiziksel karolardan ziyade desenli karolardan bahsediyorum. Yukarıdaki görüntünün vurgulanan kısmını desen döşememiz olarak kullanalım: ilk sıradaki iki tam tuğla ve ikinci sıradaki iki yarım tuğla arasına sıkıştırılmış bir bütün. Boşlukların nasıl ve nerede dahil edildiğine dikkat edin, çünkü bunların tekrarlanan desen döşemesine dahil edilmesi gerekir.
Kullanırken <pattern>
, kalıbı tanımlamalıyız width
ve height
, taban döşemesinin genişliğine ve yüksekliğine karşılık gelir. Boyutları elde etmek için biraz matematiğe ihtiyacımız var:
Tile Width = 2(Brick Width) + 2(Gap) = 2(100) + 2(10) = 220
Tile Height = 2(Bright Height) + 2(Gap) = 2(30) + 2(10) = 80
Pekala, desen döşememiz 220✕80
. biz de ayarlamalıyız patternUnits
öznitelik, değer nerede userSpaceOnUse
aslında piksel anlamına gelir. Son olarak, bir ekleyerek id
desene, onunla başka bir öğeyi boyarken referans verilebilmesi için gereklidir.
<pattern id="p" width="220" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
Artık döşeme boyutlarını oluşturduğumuza göre, zorluk, döşemenin kodunu, grafiği mümkün olan en az sayıda baytla oluşturacak şekilde oluşturmaktır. En sonunda elde etmeyi umduğumuz şey bu:
İlk biçimlendirme (197 bayt)
Aklıma gelen bu kalıbı yeniden oluşturmak için en basit ve en bildirimsel yaklaşım beş dikdörtgen çizmektir. Varsayılan olarak, fill
SVG öğesinin siyah ve stroke
şeffaftır. Bu, SVG modellerini optimize etmek için iyi çalışır, çünkü bunları kodda açıkça beyan etmek zorunda değiliz.
Aşağıdaki koddaki her satır bir dikdörtgen tanımlar. bu width
ve height
her zaman ayarlanır ve x
ve y
konumlar, yalnızca bir dikdörtgenden ötelenmişse ayarlanır. 0
pozisyon.
<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"/>
Karonun üst sırası iki tam genişlikte tuğla içeriyordu, ikinci tuğla x="110"
izin 10
tuğladan önceki boşluk pikselleri. Benzer şekilde var 10
sonra boşluk pikselleri, çünkü tuğla biter 210
piksel (110 + 100 = 210
) yatay eksende olmasına rağmen <pattern>
genişlik 220
piksel. Biraz fazladan alana ihtiyacımız var; aksi takdirde ikinci tuğla, bitişik karodaki ilk tuğla ile birleşir.
İkinci (alt) sıradaki tuğlalar, sıra iki yarım tuğla ve bir tam tuğla içerecek şekilde kaydırılır. Bu durumda, yarım genişlikteki tuğlaların birleşmesini istiyoruz, böylece başlangıçta veya sonunda boşluk kalmayacak ve bitişik desen karolarında tuğlalarla sorunsuz bir şekilde akmalarına izin verecek. Bu tuğlaları ötelerken, yarım boşlukları da dahil etmeliyiz, böylece x
değerler 55
ve 165
, Sırasıyla.
Öğe yeniden kullanımı, (-43B, toplam 154B)
Her tuğlayı bu kadar açık bir şekilde tanımlamak verimsiz görünüyor. Bunun yerine şekilleri yeniden kullanarak SVG kalıplarını optimize etmenin bir yolu yok mu?
SVG'nin yaygın olarak bilindiğini sanmıyorum. <use>
öğe. Onunla başka bir öğeye başvurabilir ve bu başvurulan öğeyi her yerde oluşturabilirsiniz. <use>
kullanıldı. Bu, epeyce bayt tasarrufu sağlar, çünkü birincisi hariç her tuğlanın genişlik ve yüksekliklerini belirtmeyi ihmal edebiliriz.
O, dedi <use>
küçük bir fiyat ile geliyor. Yani, bir eklememiz gerekiyor. id
yeniden kullanmak istediğimiz öğe için.
<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"/>
En kısa id
olası bir karakter, bu yüzden tuğla için “b” yi seçtim. bu <use>
eleman benzer şekilde konumlandırılabilir <rect>
, Birlikte x
ve y
öznitelikler ofset olarak. Artık her tuğla tam genişlikte olduğundan, <use>
(unutmayın, desen karosunun ikinci sırasındaki tuğlaları açıkça yarıya indirdik), negatif kullanmalıyız x
ikinci sıradaki değeri seçin, ardından tuğlalar arasındaki bu kesintisiz bağlantı için son tuğlanın karodan taştığından emin olun. Yine de bunlar sorun değil, çünkü desen döşemesinin dışına düşen her şey otomatik olarak kesilir.
Daha verimli yazılabilecek bazı yinelenen dizeleri görebiliyor musunuz? Sıradakiler üzerinde çalışalım.
Yola yeniden yazma (-54B, toplam 100B)
<path>
muhtemelen SVG'deki en güçlü unsurdur. İçinde "komutlar" bulunan hemen hemen her şekli çizebilirsiniz. d
bağlanmak. Kullanılabilir 20 komut var, ancak dikdörtgenler için yalnızca en basitlerine ihtiyacımız var.
İşte bununla geldiğim yer:
<path d="M0 0h100v30h-100z M110 0h100v30h-100 M0 40h45v30h-45z M55 40h100v30h-100z M165 40h55v30h-55z"/>
Biliyorum, süper tuhaf sayılar ve harfler! hepsinin anlamı var, elbette. İşte bu özel durumda neler oluyor:
M{x} {y}
: Koordinatlara göre bir noktaya hareket eder.z
: Geçerli segmenti kapatır.h{x}
: uzunluğu ile geçerli noktadan yatay bir çizgi çizer.x
işaretiyle tanımlanan yöndex
. küçük harfx
göreli bir koordinatı gösterir.v{y}
: uzunluğu ile geçerli noktadan dikey bir çizgi çizer.y
işaretiyle tanımlanan yöndey
. küçük harfy
göreli bir koordinatı gösterir.
Bu işaretleme öncekinden çok daha özlüdür (satır sonları ve girinti boşlukları yalnızca okunabilirlik içindir). Ve, hey, 100 bayta ulaşan ilk boyutun yarısını kesmeyi başardık. Yine de, bir şey bana bunun daha küçük olabileceğini hissettiriyor…
Fayans revizyonu (-38B, 62B toplam)
Desen döşememizde tekrar eden parçalar yok mu? İlk sırada bütün bir tuğlanın tekrarlandığı açık, peki ya ikinci sırada? Görmesi biraz zor ama ortadaki tuğlayı ortadan ikiye bölersek belli oluyor.
Şey, ortadaki tuğla tam olarak ikiye kesilmemiş. Hafif bir sapma var çünkü boşluğu da hesaba katmamız gerekiyor. Her neyse, daha basit bir temel döşeme deseni bulduk, bu da daha az bayt anlamına geliyor! Bu aynı zamanda yarıya indirmemiz gerektiği anlamına gelir. width
bizim <pattern>
220'den 110'a kadar eleman.
<pattern id="p" width="110" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
Şimdi basitleştirilmiş döşemenin nasıl çizildiğini görelim <path>
:
<path d="M0 0h100v30h-100z M0 40h45v30h-45z M55 40h55v30h-55z"/>
Boyut, orijinal boyutun üçte birinden daha az olan 62 bayta düşürüldü! Ama yapabileceğimiz daha çok şey varken neden burada duralım!
Yol komutlarını kısaltma (-9B, 53B toplam)
biraz daha derine inmekte fayda var <path>
öğesi, çünkü SVG modellerini optimize etmek için daha fazla ipucu sağlar. Çalışırken yaşadığım bir yanılgı <path>
nasıl olduğu ile ilgili fill
nitelik çalışır. Çocukluğumda MS Paint ile çok oynadığım için, düz bir renkle doldurmak istediğim herhangi bir şeklin kapalı olması gerektiğini, yani açık noktalarının olmadığını öğrendim. Aksi takdirde boya şeklin dışına sızacak ve her şeyin üzerine dökülecektir.
Ancak SVG'de bu doğru değildir. alıntı yapayım özellik kendisi:
Doldurma işlemi, alt yolun son noktasını alt yolun ilk noktasına bağlamak için yola ek bir "yolu kapat" komutu eklenmiş gibi doldurma işlemini gerçekleştirerek açık alt yolları doldurur.
Bu, yolu kapat komutlarını atlayabileceğimiz anlamına gelir (z
), çünkü alt yollar doldurulduklarında otomatik olarak kapalı olarak kabul edilir.
Yol komutları hakkında bilinmesi gereken bir başka yararlı şey de, bunların büyük harf ve küçük harf varyasyonlarında gelmeleridir. Küçük harfler, göreli koordinatların kullanıldığı anlamına gelir; büyük harfler, bunun yerine mutlak koordinatların kullanıldığı anlamına gelir.
ile bundan biraz daha zor H
ve V
komutlar, çünkü yalnızca bir koordinat içerirler. İşte bu iki komutu nasıl açıklayacağım:
H{x}
: Koordinat için geçerli noktadan yatay bir çizgi çizerx
.V{y}
: Koordinat için geçerli noktadan dikey bir çizgi çizery
.
Motif karoda ilk tuğlayı çizerken, (0,0)
koordinatlar. Daha sonra yatay bir çizgi çiziyoruz. (100,0)
ve dikey bir çizgi (100,30)
ve son olarak yatay bir çizgi çizin. (0,30)
. biz kullandık h-100
son satırda komut, ancak eşdeğerdir H0
, ki bu beş yerine iki bayttır. İki benzer oluşumu değiştirebilir ve kodumuzu ayrıştırabiliriz. <path>
buna kadar:
<path d="M0 0h100v30H0 M0 40h45v30H0 M55 40h55v30H55"/>
9 bayt daha traş edildi - daha ne kadar küçülebiliriz?
Köprüleme (-5B, toplam 48B)
Tam olarak optimize edilmiş bir SVG modeli için önümüzde duran en uzun komutlar, sırasıyla 4, 5 ve 6 bayt alan "taşıma" komutlarıdır. Sahip olduğumuz bir kısıtlama şudur:
Bir yol veri kesimi (varsa) bir "moveto" komutuyla başlamalıdır.
Ama sorun değil. Birincisi en kısası zaten. Satırları değiştirirsek, tuğlalar arasında yalnızca yatay veya dikey olarak hareket etmemiz gereken bir yol tanımı bulabiliriz. ya kullanabilseydik h
ve v
yerine komutlar M
?
Yukarıdaki şema, üç şeklin tek bir yolla nasıl çizilebileceğini göstermektedir. olduğu gerçeğinden yararlandığımızı unutmayın. fill
işlem arasındaki açık kısmı otomatik olarak kapatır. (110,0)
ve (0,0)
. Bu yeniden düzenleme ile ikinci sıradaki tam en tuğlanın solundaki boşluğu da taşıdık. Kodun nasıl göründüğü, yine de satır başına bir tuğlaya bölünmüş hali:
<path d="M0 0v30h50V0 h10v30h50 v10H10v30h100V0"/>
Elbette, artık 48 bayta düştüğümüze göre mutlak en küçük çözümü bulduk, değil mi?! Peki…
Rakam kırpma (-4B, toplam 44B)
Boyutlar konusunda biraz esnek olabilirseniz, SVG modellerini optimize etmenin başka bir küçük yolu daha var. Bir tuğla genişliği ile çalışıyoruz 100
piksel, ancak bu üç bayt. Bunu değiştirmek 90
yazmamız gerektiğinde bir bayt daha az anlamına gelir. Benzer şekilde, bir boşluk kullandık 10
pikseller — ama eğer onu değiştirirsek 8
bunun yerine, bu oluşumların her birine bir bayt kaydederiz.
<path d="M0 0v30h45V0 h8v30h45 v8H8v30h90V0"/>
Tabii bu aynı zamanda kalıp ölçülerini de buna göre ayarlamamız gerektiği anlamına geliyor. İşte son optimize edilmiş SVG model kodu:
<pattern id="p" width="98" height="76" patternUnits="userSpaceOnUse"> <path d="M0 0v30h45V0h8v30h45v8H8v30h90V0"/>
</pattern>
Yukarıdaki pasajdaki ikinci satır - girintileri saymaz - 44 bayt. Buraya altı yinelemede 197 bayttan geldik. Bu tıknaz %77.7 boyut küçültme!
Merak ediyorum da… bu gerçekten mümkün olan en küçük boyut mu? SVG modellerini optimize etmenin tüm olası yollarını inceledik mi?
Sizi bu kodu daha da küçültmeye ve hatta SVG modellerini optimize etmek için alternatif yöntemler denemeye davet ediyorum. Kalabalığın bilgeliği ile gerçek küresel minimumu bulup bulamayacağımızı görmek isterim!
SVG kalıpları oluşturma ve optimize etme hakkında daha fazla bilgi
SVG kalıpları oluşturma ve optimize etme hakkında daha fazla bilgi edinmek istiyorsanız, şu makalemi okuyun: SVG filtreleriyle desen oluşturma. Veya 60+ desenden oluşan bir galeriye göz atmak isterseniz, PetitePatterns CodePen Koleksiyonu. Son olarak izleyebilirsin YouTube'daki derslerim SVG modellerini daha da derinleştirmenize yardımcı olmak için.
SVG Kalıplarını En Küçük Boyutlarına Göre Optimize Etme aslen yayınlandı CSS Hileleri. Malısın bülteni al.
- "
- 10
- 100
- 77
- 9
- 98
- Hakkımızda
- kesin
- Hesap
- Ek
- Türkiye
- Izin
- zaten
- Başka
- yaklaşım
- ALAN
- göre
- öznitelikleri
- mevcut
- EKSENLER
- Bit
- Siyah
- meydan okuma
- değişiklik
- kapalı
- kod
- ortak
- bağ
- içeren
- içerik
- koordinat
- olabilir
- Oluşturma
- akım
- veri
- derin
- aşağı
- uçları
- kurulmuş
- her şey
- örnek
- Dışında
- deneme
- Nihayet
- Ad
- uygun
- akış
- bulundu
- daha fazla
- boşluk
- alma
- Küresel
- sahip olan
- yükseklik
- yardım et
- okuyun
- Vurgulanan
- Ne kadar
- HTTPS
- belirlemek
- görüntü
- dahil
- dahil
- IT
- kendisi
- bilinen
- sızıntı
- ÖĞRENİN
- öğrendim
- kaldıraç
- çizgi
- küçük
- baktı
- Aşk
- YAPAR
- Yapımı
- yönetilen
- matematik
- akla
- Daha
- çoğu
- hareket
- MS
- numara
- sayılar
- ofset
- tamam
- açık
- optimize
- aksi takdirde
- model
- fiziksel
- Nokta
- yerleştirilmiş
- mümkün
- güçlü
- güzel
- fiyat
- süreç
- sağlar
- kalite
- yuvarlak
- koşu
- Adı geçen
- sorunsuz
- Dizi
- set
- şekiller
- benzer
- Basit
- ALTINCI
- beden
- So
- çözüm
- bir şey
- uzay
- Spot
- başlama
- başlar
- destekli
- konuşma
- İçinden
- üst
- şeffaf
- Öğreticiler
- kullanım
- değer
- Görüntüle
- W3
- İzle
- karşılama
- Ne
- içinde
- olmadan
- İş
- çalışma
- çalışır
- değer
- Youtube