Hiljuti lõin oma osana telliskiviseina mustri #PetitePatterns seeria, väljakutse, kus ma loon SVG-s orgaanilise välimusega mustreid või tekstuure 560 baidi piires (ehk ligikaudu kahe säutsu suuruses). Selle piirangu täitmiseks olen läbinud teekonna, mis on õpetanud mulle radikaalseid viise SVG-mustrite optimeerimiseks nii, et need sisaldaksid võimalikult vähe koodi, ilma et see mõjutaks üldist pildikvaliteeti.
Ma tahan teid protsessist läbi viia ja näidata, kuidas saame 197 baidist algava SVG-mustri viia kõigest 44 baidini – see on tohutu 77.7% vähenemine!
SVG muster
Seda nimetatakse "jooksva sideme" tellismustriks. See on kõige levinum telliskivimuster, mida olete kindlasti varem näinud: iga telliskivirida on nihutatud poole tellise pikkusega, luues korduva astmelise mustri. Paigutus on üsna lihtne, tehes SVG-sid <pattern>
element, mis sobib selle koodis reprodutseerimiseks ideaalselt.
SVG <pattern>
element kasutab eelnevalt määratletud graafilist objekti, mida saab horisontaal- ja vertikaalteljel fikseeritud intervallidega kopeerida (või "plaadistada"). Põhimõtteliselt määratleme ristkülikukujulise plaadimustri ja seda korratakse täiteala värvimiseks.
Kõigepealt määrame tellise mõõtmed ja iga tellise vahe. Lihtsuse huvides kasutame puhtaid ümaraid numbreid: a laius 100
ja kõrgus 30
tellise jaoks ja 10
nendevaheliste horisontaalsete ja vertikaalsete vahede jaoks.
Järgmisena peame tuvastama oma "aluse" plaadi. Ja "plaadi" all räägin ma pigem mustriplaatidest kui füüsilistest plaatidest, mida ei tohi segi ajada tellistega. Kasutame mustriplaadina ülaltoodud pildi esiletõstetud osa: esimeses reas kaks tervet tellist ja teises reas üks tervik kahe pooliku tellise vahele. Pange tähele, kuidas ja kuhu lüngad on lisatud, sest need tuleb lisada korduvale mustriplaadile.
Kasutamisel <pattern>
, peame mustri määratlema width
ja height
, mis vastavad alusplaadi laiusele ja kõrgusele. Mõõtmete saamiseks vajame veidi matemaatikat:
Tile Width = 2(Brick Width) + 2(Gap) = 2(100) + 2(10) = 220
Tile Height = 2(Bright Height) + 2(Gap) = 2(30) + 2(10) = 80
Olgu, nii et meie mustriplaat on 220✕80
. Samuti peame määrama patternUnits
atribuut, kus väärtus userSpaceOnUse
tähendab sisuliselt piksleid. Lõpuks lisades an id
mustrile on vajalik, et sellele saaks viidata, kui värvime sellega mõnda muud elementi.
<pattern id="p" width="220" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
Nüüd, kui oleme paani mõõtmed määranud, on väljakutse luua paani kood viisil, mis renderdab graafikat võimalikult väikese arvu baitidega. Sellega loodame lõpuks jõuda:
Esialgne märgistus (197 baiti)
Lihtsaim ja kõige deklaratiivsem viis selle mustri taasloomiseks, mis mulle meelde tuleb, on viie ristküliku joonistamine. Vaikimisi on fill
SVG-elemendist on must ja stroke
on läbipaistev. See sobib hästi SVG-mustrite optimeerimiseks, kuna me ei pea neid koodis selgesõnaliselt deklareerima.
Alloleva koodi iga rida määratleb ristküliku. The width
ja height
on alati seatud ja x
ja y
positsioonid määratakse ainult siis, kui ristkülik on nihutatud 0
asendisse.
<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"/>
Plaadi ülemine rida sisaldas kahte täislaiuses tellist, teine tellis on paigutatud x="110"
võimaldades 10
pikslite vahe enne tellist. Samamoodi on olemas 10
pikslite vahe pärast, sest tellis lõpeb kell 210
pikslit (110 + 100 = 210
) horisontaalteljel, kuigi <pattern>
laius on 220
pikslit. Vajame seda natuke lisaruumi; vastasel juhul sulanduks teine tellis külgneva plaadi esimese tellisega.
Teise (alumise) rea tellised on nihutatud, nii et rida sisaldab kahte poolik tellist ja ühte tervet tellist. Sel juhul tahame, et poolelaiused tellised ühineksid, nii et alguses ega lõpus ei jääks tühimikku, võimaldades neil sujuvalt voolata koos külgnevate mustriplaatide tellistega. Nende telliste tasaarvestamisel peame kaasama ka pooled vahed, seega x
väärtused 55
ja 165
, Vastavalt.
Elemendi taaskasutus (-43B, kokku 154B)
Tundub ebaefektiivne iga tellist nii selgelt määratleda. Kas pole kuidagi võimalik SVG-mustreid optimeerida, kasutades kujundeid selle asemel?
Ma arvan, et pole laialt teada, et SVG-l on a <use>
element. Saate sellega viidata teisele elemendile ja renderdada viidatud elemendi kõikjal <use>
kasutatakse. See säästab üsna palju baite, sest me võime jätta määramata iga tellise laiuse ja kõrguse, välja arvatud esimese.
See ütles <use>
tuleb väikese hinnaga. See tähendab, et peame lisama a id
elemendi jaoks, mida soovime taaskasutada.
<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"/>
Lühim id
võimalik on üks märk, seega valisin telliskivi jaoks "b". The <use>
elementi saab paigutada sarnaselt <rect>
Koos x
ja y
atribuudid nihketena. Kuna nüüd on iga tellis täislaiuses, kui oleme sellele üle läinud <use>
(pidage meeles, et mustriplaadi teises reas jagasime tellised selgesõnaliselt pooleks), peame kasutama negatiivset x
väärtus teises reas, seejärel veenduge, et viimane telliskivi voolaks plaadist üle, et telliste vahel oleks sujuv ühendus. Need on siiski korras, sest kõik, mis jääb mustriplaadist välja, lõigatakse automaatselt ära.
Kas saate märgata mõnda korduvat stringi, mida saab tõhusamalt kirjutada? Töötame nende kallal järgmisena.
Teele ümberkirjutamine (-54B, kokku 100B)
<path>
on ilmselt SVG võimsaim element. Saate joonistada peaaegu iga kujundi, mille sees on "käsud". d
atribuut. Saadaval on 20 käsku, kuid ristkülikute jaoks vajame ainult lihtsamaid.
Siin ma sellega jõudsin:
<path d="M0 0h100v30h-100z M110 0h100v30h-100 M0 40h45v30h-45z M55 40h100v30h-100z M165 40h55v30h-55z"/>
Ma tean, üliveidrad numbrid ja tähed! Neil kõigil on tähendus, muidugi. Sel konkreetsel juhul toimub järgmine:
M{x} {y}
: Liigub koordinaatide alusel punkti.z
: Sulgeb praeguse segmendi.h{x}
: Joonistab praegusest punktist horisontaalse joone pikkusegax
märgiga määratletud suunasx
. Väiketähtedegax
tähistab suhtelist koordinaati.v{y}
: Joonistab praegusest punktist vertikaalse joone pikkusegay
märgiga määratletud suunasy
. Väiketähtedegay
tähistab suhtelist koordinaati.
See märgistus on palju napisõnalisem kui eelmine (reavahetused ja taande tühimik on ainult loetavuse huvides). Ja hei, meil õnnestus pool esialgsest suurusest välja lõigata, jõudes 100 baiti. Siiski paneb miski mind tundma, et see võiks olla väiksem…
Paani redaktsioon (-38B, kokku 62B)
Kas meie mustriplaadil pole korduvaid osi? Selge see, et esimeses reas kordub terve telliskivi, aga kuidas on lood teise reaga? Seda on natuke raskem näha, kuid kui lõikame keskmise tellise pooleks, muutub see ilmseks.
Noh, keskmine telliskivi pole täpselt pooleks lõigatud. Siin on väike nihe, sest peame arvestama ka lõhega. Igatahes leidsime just lihtsama alusplaadi mustri, mis tähendab vähem baite! See tähendab ka, et peame poole võrra vähendama width
meie <pattern>
element vahemikus 220 kuni 110.
<pattern id="p" width="110" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
Nüüd vaatame, kuidas lihtsustatud plaati joonistatakse <path>
:
<path d="M0 0h100v30h-100z M0 40h45v30h-45z M55 40h55v30h-55z"/>
Suurust vähendatakse 62 baidile, mis on juba vähem kui kolmandik algsest suurusest! Aga miks peatuda siin, kui saame veel rohkem ära teha!
Teekäskude lühendamine (-9B, kokku 53B)
Tasub veidi süveneda <path>
element, kuna see annab rohkem näpunäiteid SVG-mustrite optimeerimiseks. Üks eksiarvamus, millega ma töötades olen olnud <path>
puudutab seda, kuidas fill
atribuut töötab. Olles lapsepõlves palju MS Paintiga mänginud, olen õppinud, et iga kujund, mida tahan ühevärvilise värviga täita, peab olema kinnine ehk sellel ei tohi olla lahtisi kohti. Vastasel juhul lekib värv vormist välja ja valgub kõige peale.
SVG-s pole see aga tõsi. Lubage mul tsiteerida spetsifikatsioon ise:
Täitmisoperatsioon täidab avatud alamteed, sooritades täitmistoimingu nii, nagu oleks teele lisatud täiendav käsk “closepath”, et ühendada alamtee viimane punkt alamtee esimese punktiga.
See tähendab, et võime sulgemistee käsud (z
), sest alamteed loetakse täitmisel automaatselt suletuks.
Veel üks kasulik asi, mida teekäskude kohta teada saada, on see, et need on suur- ja väiketähtedega variatsioonid. Väikesed tähed tähendavad, et kasutatakse suhtelisi koordinaate; suurtähed tähendavad, et nende asemel kasutatakse absoluutseid koordinaate.
See on veidi keerulisem kui koos H
ja V
käske, kuna need sisaldavad ainult ühte koordinaati. Ma kirjeldaksin neid kahte käsku järgmiselt:
H{x}
: Joonistab horisontaaljoone praegusest punktist koordinaadinix
.V{y}
: Joonistab vertikaalse joone praegusest punktist koordinaadiniy
.
Kui joonistame mustriplaadi esimest tellist, alustame kohast (0,0)
koordinaadid. Seejärel joonistame horisontaalse joone (100,0)
ja vertikaalne joon (100,30)
ja lõpuks tõmmake horisontaaljoon (0,30)
. Me kasutasime h-100
käsu viimasel real, kuid see on samaväärne H0
, mis on kaks baiti viie asemel. Saame asendada kaks sarnast esinemist ja parendada meie koodi <path>
kuni selleni:
<path d="M0 0h100v30H0 M0 40h45v30H0 M55 40h55v30H55"/>
Veel 9 baiti on maha raseeritud – kui palju väiksemaks saame minna?
Sildamine (-5B, kokku 48B)
Pikimad käsud, mis takistavad täielikult optimeeritud SVG-mustrit, on käsud "teisalda", mis võtavad vastavalt 4, 5 ja 6 baiti. Üks meie piirang on järgmine:
Teeandmete segment (kui see on olemas) peab algama käsuga "moveto".
Aga see on okei. Esimene on igatahes kõige lühem. Kui ridu vahetame, saame välja teemääratluse, kus peame liikuma ainult kas horisontaalselt või vertikaalselt telliste vahel. Mis siis, kui saaksime kasutada h
ja v
käsud seal asemel M
?
Ülaltoodud diagramm näitab, kuidas saab kolme kujundit ühe teega joonistada. Pange tähele, et kasutame ära asjaolu, et fill
toiming sulgeb automaatselt avatud osa vahel (110,0)
ja (0,0)
. Selle ümberpaigutusega nihutasime teise rea täislaiuses tellisest vasakule ka vahe. Kood näeb välja selline, mis on endiselt jagatud üheks telliskiviks rea kohta:
<path d="M0 0v30h50V0 h10v30h50 v10H10v30h100V0"/>
Kindlasti oleme leidnud absoluutselt väikseima lahenduse nüüd, kui oleme jõudnud 48 baiti, eks? Noh…
Numbrite kärpimine (-4B, kokku 44B)
Kui saate mõõtmetega pisut paindlik olla, on veel üks väike viis SVG-mustrite optimeerimiseks. Oleme töötanud telliskivi laiusega 100
pikslit, kuid see on kolm baiti. Selle muutmine 90
tähendab, et iga kord, kui meil on vaja see kirjutada, on üks bait vähem. Samamoodi kasutasime vahet 10
pikslit – aga kui me selle muudame 8
selle asemel salvestame iga juhtumi kohta ühe baidi.
<path d="M0 0v30h45V0 h8v30h45 v8H8v30h90V0"/>
Muidugi tähendab see ka, et peame mustri mõõtmeid vastavalt kohandama. Siin on lõplik optimeeritud SVG mustri kood:
<pattern id="p" width="98" height="76" patternUnits="userSpaceOnUse"> <path d="M0 0v30h45V0h8v30h45v8H8v30h90V0"/>
</pattern>
Ülaltoodud katkendi teine rida – taandeid arvestamata – on 44 baiti. Jõudsime siia 197 baidist kuue iteratsiooniga. See on tükk Suuruse vähendamine 77.7%.!
Ma mõtlen siiski… kas see on tõesti väikseim võimalik suurus? Kas oleme uurinud kõiki võimalikke viise SVG-mustrite optimeerimiseks?
Kutsun teid üles proovima seda koodi veelgi minimeerida või isegi katsetama alternatiivsete meetoditega SVG-mustrite optimeerimiseks. Tahaksin näha, kas leiame rahvahulga tarkusega tõelise globaalse miinimumi!
Lisateavet SVG-mustrite loomise ja optimeerimise kohta
Kui soovite saada lisateavet SVG-mustrite loomise ja optimeerimise kohta, lugege minu artiklit selle kohta mustrite loomine SVG-filtritega. Või kui soovite vaadata 60+ mustri galeriid, saate vaadata PetitePatterns CodePen kollektsioon. Lõpuks olete teretulnud vaatama minu õpetused YouTube'is et aidata teil SVG-mustritega veelgi süveneda.
SVG-mustrite optimeerimine nende väikseima suuruseni algselt avaldatud CSS-nipid. Sa peaksid hankige uudiskiri.
- "
- 10
- 100
- 77
- 9
- 98
- MEIST
- absoluutne
- konto
- Täiendavad lisad
- Materjal: BPA ja flataatide vaba plastik
- Lubades
- juba
- Teine
- lähenemine
- PIIRKOND
- artikkel
- atribuudid
- saadaval
- TELGED
- Natuke
- Must
- väljakutse
- muutma
- suletud
- kood
- ühine
- ühendus
- sisaldab
- sisu
- koordineerima
- võiks
- loomine
- Praegune
- andmed
- sügavam
- alla
- lõppeb
- asutatud
- kõik
- näide
- Välja arvatud
- eksperiment
- Lõpuks
- esimene
- sobima
- voog
- avastatud
- edasi
- lõhe
- saamine
- Globaalne
- võttes
- kõrgus
- aitama
- siin
- Esiletõstetud
- Kuidas
- HTTPS
- identifitseerima
- pilt
- sisaldama
- lisatud
- IT
- ise
- teatud
- lekkima
- Õppida
- õppinud
- võimendav
- joon
- vähe
- Vaatasin
- armastus
- TEEB
- Tegemine
- juhitud
- matemaatika
- meeles
- rohkem
- kõige
- liikuma
- MS
- number
- numbrid
- tasakaalustama
- Hästi
- avatud
- optimeeritud
- muidu
- Muster
- füüsiline
- Punkt
- paigutatud
- võimalik
- võimas
- ilus
- hind
- protsess
- annab
- kvaliteet
- ümber
- jooksmine
- Ütlesin
- sujuv
- Seeria
- komplekt
- kuju
- sarnane
- lihtne
- SIX
- SUURUS
- So
- lahendus
- midagi
- Ruum
- Kaubandus-
- algus
- algab
- Toetatud
- rääkimine
- Läbi
- ülemine
- läbipaistev
- õpetused
- kasutama
- väärtus
- vaade
- W3
- Watch
- teretulnud
- M
- jooksul
- ilma
- Töö
- töö
- töötab
- väärt
- youtube