Nemrég készítettem egy téglafalmintát a munkám részeként #PetitePatterns sorozat, egy kihívás, ahol organikus megjelenésű mintákat vagy textúrákat hozok létre SVG-ben 560 bájton belül (vagy körülbelül két tweet méretében). Ahhoz, hogy megfeleljek ennek a megkötésnek, egy olyan utat jártam be, amely megtanított néhány radikális módszert az SVG-minták optimalizálására, hogy azok a lehető legkevesebb kódot tartalmazzák anélkül, hogy az általános képminőséget befolyásolnák.
Szeretném végigvezetni a folyamaton, és megmutatni, hogyan tehetünk egy 197 bájttól kezdődő SVG-mintát egészen 44 bájtra – ez óriási, 77.7%-os csökkentés!
Az SVG minta
Ez az úgynevezett „futó kötés” téglaminta. Ez a legelterjedtebb téglaminta, amelyet biztosan látott már: minden téglasort a tégla hosszának felével eltolnak, ismétlődő lépcsőzetes mintát hozva létre. Az elrendezés meglehetősen egyszerű, SVG-ket készít <pattern>
elem tökéletesen illeszkedik kódban történő reprodukálásához.
Az SVG <pattern>
Az elem egy előre definiált grafikus objektumot használ, amely replikálható (vagy „csempézhető”) rögzített időközönként a vízszintes és függőleges tengely mentén. Lényegében egy téglalap alakú csempemintát határozunk meg, és ez megismétlődik a kitöltési terület festésekor.
Először is állítsuk be a tégla méreteit és az egyes téglák közötti rést. Az egyszerűség kedvéért használjunk tiszta, kerek számokat: a szélesség 100
és magassága 30
a téglához, és 10
a köztük lévő vízszintes és függőleges hézagokhoz.
Ezután meg kell határoznunk az „alap” lapkánkat. És a „csempék” alatt inkább mintás csempékről beszélek, mint fizikai lapokról, nem összetévesztendő a téglákkal. Használjuk a fenti kép kiemelt részét mintalapkánkként: az első sorban két egész tégla, a második sorban pedig két féltégla közé szendvicsben egy egész. Figyelje meg, hogyan és hol találhatók a rések, mert ezeket szerepeltetni kell az ismételt mintalapkában.
Használat során <pattern>
, meg kell határoznunk a mintát width
és a height
, amelyek megfelelnek az alaplap szélességének és magasságának. A méretek meghatározásához szükségünk van egy kis matematikára:
Tile Width = 2(Brick Width) + 2(Gap) = 2(100) + 2(10) = 220
Tile Height = 2(Bright Height) + 2(Gap) = 2(30) + 2(10) = 80
Rendben, szóval a mintalapkánk az 220✕80
. Azt is be kell állítanunk a patternUnits
attribútum, ahol az érték userSpaceOnUse
lényegében pixeleket jelent. Végül hozzáadunk egy id
a mintához szükséges, hogy hivatkozni lehessen rá, amikor egy másik elemet festünk vele.
<pattern id="p" width="220" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
Most, hogy meghatároztuk a csempe méreteit, a kihívás az, hogy a csempéhez tartozó kódot úgy készítsük el, hogy a grafikát a lehető legkisebb számú bájttal jelenítse meg. Reméljük, hogy a végén ez lesz:
Kezdeti jelölés (197 bájt)
Ennek a mintának a legegyszerűbb és legdeklaratívabb módja az, hogy öt téglalapot rajzolok. Alapértelmezés szerint a fill
egy SVG elem fekete és a stroke
átlátszó. Ez jól működik az SVG-minták optimalizálásához, mivel ezeket nem kell kifejezetten deklarálnunk a kódban.
Az alábbi kód minden sora egy téglalapot határoz meg. A width
és a height
mindig be vannak állítva, és a x
és a y
pozíciók csak akkor vannak beállítva, ha egy téglalap el van tolva a 0
helyzetbe.
<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"/>
A csempe legfelső sora két teljes szélességű téglát tartalmazott, a második tégla a következő helyre került x="110"
így 10
pixel rés a tégla előtt. Hasonlóan van 10
pixel rés után, mert a tégla pontnál végződik 210
pixel (110 + 100 = 210
) a vízszintes tengelyen annak ellenére, hogy a <pattern>
szélessége 220
pixel. Szükségünk van arra a kis extra helyre; különben a második tégla összeolvadna a szomszédos lapkában lévő első téglával.
A második (alsó) sorban lévő téglák el vannak tolva, így a sor két féltéglát és egy egész téglát tartalmaz. Ebben az esetben azt szeretnénk, ha a félszélességű téglák összeolvadnának, így nem marad rés sem az elején, sem a végén, lehetővé téve, hogy zökkenőmentesen folyjanak a téglákkal a szomszédos mintalapkákban. Ezen téglák beszámításánál félréseket is be kell számolnunk, így a x
értékek vannak 55
és a 165
, Ill.
Elemek újrafelhasználása, (-43B, összesen 154B)
Nem tűnik hatékonynak minden egyes téglát ilyen egyértelműen meghatározni. Nincs valami mód az SVG-minták optimalizálására az alakzatok újrafelhasználásával?
Nem hiszem, hogy széles körben köztudott, hogy az SVG-nek van a <use>
elem. Hivatkozhat vele egy másik elemre, és bárhol megjelenítheti azt a hivatkozott elemet <use>
használt. Ezzel jó néhány bájtot takaríthatunk meg, mert az első kivételével elhagyhatjuk az egyes téglák szélességének és magasságának megadását.
Hogy az említett, <use>
egy kis árral jár. Vagyis hozzá kell adnunk egy id
az újra felhasználni kívánt elemhez.
<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"/>
A legrövidebb id
Egy karakter lehetséges, ezért a „b”-t választottam téglának. A <use>
elemhez hasonlóan elhelyezhető <rect>
, A x
és a y
attribútumokat eltolásként. Mivel minden tégla teljes szélességű most, amikor átálltunk <use>
(ne feledjük, a mintalap második sorában kifejezetten feleztük a téglákat), negatívot kell használnunk x
értéket a második sorban, majd győződjön meg arról, hogy az utolsó tégla túlcsordul a csempéből a téglák közötti zökkenőmentes kapcsolat érdekében. Ezek azonban rendben vannak, mert minden, ami a mintalapkán kívül esik, automatikusan levágásra kerül.
Kiszúr néhány ismétlődő karakterláncot, amelyek hatékonyabban írhatók? Dolgozzunk ezeken a következőkben.
Átírás az elérési útra (-54B, összesen 100B)
<path>
valószínűleg az SVG legerősebb eleme. Szinte bármilyen alakzatot rajzolhat, amelynek „parancsai” vannak d
tulajdonság. 20 parancs áll rendelkezésre, de a téglalapokhoz csak a legegyszerűbbekre van szükségünk.
Itt landoltam ezzel:
<path d="M0 0h100v30h-100z M110 0h100v30h-100 M0 40h45v30h-45z M55 40h100v30h-100z M165 40h55v30h-55z"/>
Tudom, szuper furcsa számok és betűk! Mindegyiknek van jelentése, természetesen. Íme, mi történik ebben a konkrét esetben:
M{x} {y}
: Egy pontra mozog koordináták alapján.z
: Bezárja az aktuális szegmenst.h{x}
: Vízszintes vonalat húz az aktuális pontból a hosszúsággalx
jele által meghatározott iránybanx
. Kisbetűsx
relatív koordinátát jelez.v{y}
: Függőleges vonalat húz az aktuális pontból a hosszúsággaly
jele által meghatározott iránybany
. Kisbetűsy
relatív koordinátát jelez.
Ez a jelölés sokkal tömörebb, mint az előző (a sortörések és a behúzásos szóköz csak az olvashatóságot szolgálja). És, hé, sikerült kivágnunk a kezdeti méret felét, és elértük a 100 bájtot. Mégis, valami miatt úgy érzem, ez lehetne kisebb…
Mozaik átdolgozása (-38B, összesen 62B)
A mintázatlapunknak nincsenek ismétlődő részei? Nyilvánvaló, hogy az első sorban egy egész tégla ismétlődik, de mi van a második sorban? Kicsit nehezebben látható, de ha a középső téglát kettévágjuk, akkor nyilvánvalóvá válik.
Nos, a középső tégla nincs pontosan kettévágva. Van egy kis eltolás, mert a különbséggel is számolnunk kell. Egyébként most találtunk egy egyszerűbb alaplapmintát, ami kevesebb bájtot jelent! Ez azt is jelenti, hogy felére kell csökkentenünk width
a mi <pattern>
elem 220-tól 110-ig.
<pattern id="p" width="110" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
Most nézzük meg, hogyan rajzolják meg az egyszerűsített csempét <path>
:
<path d="M0 0h100v30h-100z M0 40h45v30h-45z M55 40h55v30h-55z"/>
A méret 62 bájtra csökken, ami már kevesebb, mint harmada az eredeti méretnek! De miért álljunk meg itt, amikor még többet tehetünk!
Útvonalparancsok rövidítése (-9B, összesen 53B)
Érdemes egy kicsit mélyebben belemenni a <path>
elemet, mert több tippet ad az SVG-minták optimalizálásához. Egy tévhit volt bennem, amikor dolgoztam <path>
arra vonatkozik, hogy a fill
attribútum működik. Gyerekkoromban sokat játszottam az MS Painttel, és megtanultam, hogy minden formát, amelyet egyszínűvel szeretnék kitölteni, zártnak kell lennie, azaz nincs nyitott pontja. Ellenkező esetben a festék kifolyik a formából, és mindenre kifolyik.
Az SVG-ben azonban ez nem igaz. Hadd idézzem a spec maga:
A kitöltési művelet a nyitott alútvonalakat úgy tölti ki, hogy a kitöltési műveletet úgy hajtja végre, mintha egy további „closepath” parancsot adnának az elérési úthoz, amely összeköti az alútvonal utolsó pontját az alútvonal első pontjával.
Ez azt jelenti, hogy elhagyhatjuk a bezárási útvonal parancsokat (z
), mert az alútvonalak kitöltésekor automatikusan lezártnak minősülnek.
Egy másik hasznos dolog, amit az elérési út parancsokról tudni kell, hogy nagy- és kisbetűs változatban jelennek meg. A kisbetűk azt jelentik, hogy relatív koordinátákat használnak; A nagybetűk azt jelentik, hogy a rendszer abszolút koordinátákat használ helyette.
Ez egy kicsit trükkösebb ennél a H
és a V
parancsokat, mert csak egy koordinátát tartalmaznak. Így írnám le ezt a két parancsot:
H{x}
: Vízszintes vonalat húz az aktuális ponttól a koordinátáigx
.V{y}
: Függőleges vonalat húz az aktuális ponttól a koordinátáigy
.
Amikor az első téglát rajzoljuk a mintázatlapkába, abból indulunk ki (0,0)
koordináták. Ezután húzunk egy vízszintes vonalat (100,0)
és egy függőleges vonalat (100,30)
, és végül húzzon egy vízszintes vonalat (0,30)
. Használtuk a h-100
parancsot az utolsó sorban, de ez a megfelelője H0
, ami öt helyett két bájt. Cserélhetünk két hasonló előfordulást, és párolhatjuk a mi kódunkat <path>
erre lefelé:
<path d="M0 0h100v30H0 M0 40h45v30H0 M55 40h55v30H55"/>
További 9 bájt lenyírva – mennyivel kisebbre tudunk menni?
Áthidalás (-5B, összesen 48B)
A teljesen optimalizált SVG-minta útjában álló leghosszabb parancsok a „move to” parancsok, amelyek 4, 5 és 6 bájtot foglalnak el. Az egyik korlátunk a következő:
Az elérési út adatszegmensének (ha van) egy „moveto” paranccsal kell kezdődnie.
De nem baj. Az első egyébként a legrövidebb. Ha felcseréljük a sorokat, akkor egy olyan útdefiníciót kaphatunk, ahol csak vízszintesen vagy függőlegesen kell mozognunk a téglák között. Mi lenne, ha használhatnánk a h
és a v
parancsokat ott ahelyett M
?
A fenti diagram bemutatja, hogyan rajzolható meg a három alakzat egyetlen görbével. Vegye figyelembe, hogy kihasználjuk azt a tényt, hogy a fill
művelet automatikusan bezárja a közötti nyitott részt (110,0)
és a (0,0)
. Ezzel az átrendezéssel a második sorban lévő teljes szélességű téglától balra is áthelyeztük a rést. Így néz ki a kód, soronként egy kockára bontva:
<path d="M0 0v30h50V0 h10v30h50 v10H10v30h100V0"/>
Biztosan megtaláltuk az abszolút legkisebb megoldást most, hogy 48 bájtnál tartunk, igaz?! Jól…
Számkivágás (-4B, összesen 44B)
Ha tud egy kicsit rugalmas lenni a méretek tekintetében, van még egy kis módja annak, hogy optimalizáljuk az SVG mintákat. téglaszélességgel dolgoztunk 100
pixel, de ez három bájt. Módosítva erre 90
eggyel kevesebb bájtot jelent, amikor meg kell írnunk. Hasonlóképpen résnyit használtunk 10
pixel – de ha megváltoztatjuk 8
ehelyett elmentünk egy bájtot minden egyes előforduláson.
<path d="M0 0v30h45V0 h8v30h45 v8H8v30h90V0"/>
Ez természetesen azt is jelenti, hogy a minta méreteit ennek megfelelően kell módosítanunk. Íme a végső optimalizált SVG mintakód:
<pattern id="p" width="98" height="76" patternUnits="userSpaceOnUse"> <path d="M0 0v30h45V0h8v30h45v8H8v30h90V0"/>
</pattern>
A fenti részlet második sora – a behúzásokat nem számítva – az 44 bytes. 197 bájtból jutottunk ide hat iterációban. Ez egy vaskos 77.7%-os méretcsökkenés!
Kíváncsi vagyok… ez tényleg a lehető legkisebb méret? Megvizsgáltuk az összes lehetséges módot az SVG-minták optimalizálására?
Meghívom Önt, hogy próbálja meg tovább kicsinyíteni ezt a kódot, vagy akár kísérletezzen alternatív módszerekkel az SVG-minták optimalizálására. Szeretném látni, hogy a tömeg bölcsességével megtaláljuk-e az igazi globális minimumot!
További információ az SVG-minták létrehozásáról és optimalizálásáról
Ha többet szeretne megtudni az SVG-minták létrehozásáról és optimalizálásáról, olvassa el erről szóló cikkemet minták létrehozása SVG szűrőkkel. Vagy ha meg szeretne tekinteni egy 60+ mintát tartalmazó galériát, megtekintheti a PetitePatterns CodePen Collection. Végezetül nyugodtan nézd meg oktatóanyagaim a YouTube-on hogy még mélyebbre jusson az SVG-mintákban.
Az SVG-minták optimalizálása a legkisebb méretre eredetileg megjelent CSS-trükkök. Neked kellene kapja meg a hírlevelet.
- "
- 10
- 100
- 77
- 9
- 98
- Rólunk
- Abszolút
- Fiók
- További
- Minden termék
- lehetővé téve
- már
- Másik
- megközelítés
- TERÜLET
- cikkben
- attribútumok
- elérhető
- TENGELYEK
- Bit
- Fekete
- kihívás
- változik
- zárt
- kód
- Közös
- kapcsolat
- tartalmaz
- tartalom
- koordináta
- tudott
- létrehozása
- Jelenlegi
- dátum
- mélyebb
- le-
- vége
- megalapozott
- minden
- példa
- Kivéve
- kísérlet
- Végül
- vezetéknév
- megfelelő
- áramlási
- talált
- további
- rés
- szerzés
- Globális
- tekintettel
- magasság
- segít
- itt
- Kiemelt
- Hogyan
- HTTPS
- azonosítani
- kép
- tartalmaz
- beleértve
- IT
- maga
- ismert
- szivárog
- TANUL
- tanult
- erőfölény
- vonal
- kis
- nézett
- szerelem
- KÉSZÍT
- Gyártás
- sikerült
- matematikai
- bánja
- több
- a legtöbb
- mozog
- MS
- szám
- számok
- eltolt
- Rendben
- nyitva
- optimalizált
- másképp
- Mintás
- fizikai
- pont
- pozicionált
- lehetséges
- erős
- szép
- ár
- folyamat
- biztosít
- világítás
- körül
- futás
- Mondott
- zökkenőmentes
- Series of
- készlet
- formák
- hasonló
- Egyszerű
- SIX
- Méret
- So
- megoldások
- valami
- Hely
- Spot
- kezdet
- kezdődik
- Támogatott
- beszéd
- Keresztül
- felső
- átlátszó
- oktatóanyagok
- használ
- érték
- Megnézem
- W3
- Nézz
- fogadtatás
- Mit
- belül
- nélkül
- Munka
- dolgozó
- művek
- érdemes
- youtube