Jak zrobić własną ikonę SVG?
Mam pomysł na własne ikony SVG, którymi mogłabym oznaczyć tagi oraz kategorie na moim blogu. Oto mój plan:
- Sprawdzić, jakie tagi i kategorie posiada mój blog.
- Stworzyć plik(i) .svg z odpowiadającymi im ikonami.
- Zmienić motyw bloga tak, aby wyświetlał ikony obok kategorii i tagów.
Oto utworzone ikony - do ich wykonania użyłam jedynie (najlepszego na świecie) edytora tekstu:
Tagi i kategorie bloga: ripgrep
Najpierw chcę się dowiedzieć, jakich ikon będę w ogóle potrzebować. Planuję więc przeszukać wpisy na bogu i sprawdzić, ile już "wygenerowałam" tagów. Jeśli niezbyt wiele, to jest szansa, że podejmę się tworzenia własnych ikon.
Do wyszukania w metadanych postów przypisanych im tagów i kategorii używam fantastycznego programu ripgrep:
rg -IN -e "\.\. (tags:|category:)(.*)$" -r '$2' posts/ |\
tr ', ' '\n\n' |\
sort |\
uniq- Opcja
-Inie wypisuje nazw plików, w których znaleziono dopasowanie - Opcja
-Nwyłącza wypisywanie numerów wierszy w plikach, w których znaleziono dopasowanie - Opcja
-eokreśla wyrażenie regularne, którego szukam; tu: chcę uzyskać napis znajdujący się po tags: lub category:, poprzedzony dwoma kropkami i spacją (taki jest format metadanych w postach ze źródłem reStructuredText) - Opcja
-rdefiniuje tekst zastąpienia, w którym mogę się odwołać się do indeksu bądź nazwy grupy dopasowania; tu: grupa druga; pierwszą grupę stanowi alternatywa
Ponieważ posty mogą być oznaczone wieloma tagami oddzielonymi przecinkiem, używam tr do zamiany przecinkow (i - dla ujednolicenia - spacji) na znaki nowego wiersza, po czym sortję i usuwam duplikaty inkantacją sort | uniq.
Tworzenie ikon - kartka, ołówek i edytor tekstowy
Planuję zatem utworzyć sześć ikon:
- aoc (choinka świąteczna)
- blog (kartka i pióro)
- grafika (obrazek z ramką i haczykiem)
- howto (śrubokręt?)
- programowanie (klawiatura)
Spróbuję naszkicować jakieś obrazki, a później zamknąć je w kwadracie 100x100. Ogólne właściwości elementów svg znajdujących się na tej stronie są opisane następującym fragmentem css-a. Dzięki narysowanej szarej obwódce widzę wyraźnie położenie obrazka wewnątrz obszaru ikony.
svg {
stroke: rgb(0, 0, 0);
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
fill: none;
border: 1px solid darkgray;
}Każda z ikon będzie zdefiniowana wenątrz taga <svg>, którego atrybuty width i height zdefiniują wymiary ikony, przy pomocy taga defs zawierającego definicje (potencjalnie wielu) elementów; żaden z nich nie będzie jednak wyrenderowany. Dopiero użycie jednej z definicji (tag use) spowoduje jego wyrenderowanie.
Choinka
Narysuję bardzo prostą, symboliczną choinkę - trójkąt równramienny - z “soplem” u góry - w kształcie równoległoboku. Użyję do tego elementu path (ścieżki), którego atrybut d (data) będzie zawierał dyrektywy:
M x yustawiającą punkt początkowy ścieżki na (x, y)L x ydodający segment ścieżki od wcześniejszej pozycji do pozycji (x, y)Zdodający ostatni segment od bieżącej pozycji do punktu początkowego (czyli segment “zamykający” ścieżkę)
<svg width="100" height="100">
<defs>
<g id="choinka" >
<path d="
M 50 3
L 45 13
L 50 23
L 13 90
L 87 90
L 50 23
L 55 13
Z
"> </path>
</g>
</defs>
<use href="#choinka" x="0" y="0"></use>
</svg>A tu gotowy svg:
Blog - prosta ikona: kartka i pióro
Kolejna ikona to blog. Będzie to prosta kartka (prostokąt) z kilkoma liniami tekstu i proste pióro. Tag defs zawiera definicję trzech elementów: notes to prostokąt, blogline to linia, którą użyję trzy razy, za każdym razem zwiększając pozycję y, a pen to zamknięta ścieżka złożona z pięciu linii.
<svg width="100" height="100">
<defs>
<rect id="notes" x="0" y="0" width="70" height="90"/>
<line id="blogline" x1="0" y1="0" x2="40" y2="0"></line>
<path id="pen" d="M 0 10 L 6 0 L 12 10 L 12 80 L 0 80 Z" ></path>
</defs>
<use href="#notes" x="5" y="5"></use>
<use href="#blogline" x="20" y="20"></use>
<use href="#blogline" x="20" y="35"></use>
<use href="#blogline" x="20" y="50"></use>
<use href="#pen" x="85" y="12"></use>
</svg>Grafika
Ikona kategorii “grafika” to prosta ramka z haczykiem do zwieszenia na ścianie. Po zastanowieniu dodałam jeszcze trzy symboliczne kółeczka.
<svg id="icon-graphics" width="100" height="100">
<defs>
<rect id="ext" x="0" y="0" width="70" height="70"/>
<rect id="int" x="0" y="0" width="60" height="60"/>
<path id="hook" d="M 0 10 L 5 0 L 10 10 " ></path>
<g id="graphics">
<use href="#hook" x="45" y="0"></use>
<use href="#ext" x="10" y="10"></use>
<use href="#int" x="15" y="15"></use>
<circle r="10" cx="20" cy="40"/>
<circle r="5" cx="40" cy="60"/>
<circle r="8" cx="55" cy="30"/>
</g>
</defs>
<use href="#graphics" x="10" y="10"></use>
</svg>Howto i tutoriale - ikona śrubokręta
To będzie wyzwanie - jak wygląda śrubokręt? Wykorzystam jego symetrię: zbuduję grupę ścieżek opisującą prawą część śrubokręta (#screwpath), a następnie użyję tej grupy w odbicu względem osi Y (złożenie transformacji skalowania i przesunięcia) tak, aby otrzymać nową grupę (#screw) zawierającą obydwie części, prawą i lewą.
<svg id="icon-screw" width="100" height="100">
<defs>
<g id="screw" >
<g id="screwpath">
<path d="
M 50 0 L 53 0 L 55 5
L 55 10 L 53 15 L 53 60 L 60 60
L 60 65 L 53 65 L 60 70 L 60 95
L 55 97 L 50 99">
</path>
<path d="M 55 75 L 55 90"></path>
<path d="M 53 75 L 53 90"></path>
</g>
<use href="#screwpath"
transform="scale(-1, 1) translate(-100, 0)"></use>
</g>
</defs>
<use href="#screw" x="0" y="0" ></use>
</svg>Programowanie - ikona klawiatury
Załóżmy, że dobrą ikoną programowania będzie klawiatura. U góry narysuję trzy kółka (diody led), później narysuję cztery poziome linie (jedna ścieżka utworzona przez cztery fragmenty) oraz linie pionowe, spośród których dwie pierwsze i dwie ostatnie będą dłuższe (to boczne krawędzie klawiszy z prawej i lewej strony klawiatury).
Użwam dwóch nowych dyrektyw:
h <d>rysuje linię poziomą o długościod bieżącej pozycji V <y>rysuje linię pionową do współrzędnej y wynoszącej
<svg id="icon-kbd" width="100" height="100">
<defs>
<g id="kbd">
<rect x="0" y="0" width="95" height="55"></rect>
<circle r="3" cx="8" cy="9"></circle>
<circle r="3" cx="15" cy="9"></circle>
<circle r="3" cx="22" cy="9"></circle>
<path d="
M 5 15 h 80
M 5 25 h 80
M 5 35 h 80
M 5 45 h 80
"></path>
<path d="
M 5 15 V 45
M 15 15 V 45
M 25 15 V 35
M 35 15 V 35
M 45 15 V 35
M 55 15 V 35
M 65 15 V 35
M 75 15 V 45
M 85 15 V 45
"></path>
</g>
</defs>
<use href="#kbd" x="0" y="20" ></use>
</svg>Utworzenie jednego pliku .svg
Moim celem jest utworzenie jednego pliku .svg zawierającego wszystkie ikony i definicje widoków na każdą z nich.
Utworzyłam plik icons.svg, w którym zgromadziłam utworzone tutaj definicje ikon. Dodałam do niego atrybut style, aby przeglądarka miała możliwość wyrenderowania tego obrazka. Określiłam w nim również szerokość i wysokość (500px na 100px). Wyświetlam kolejne elementy zdefiniowane w defs od strony lewej do prawej, co 100 pikseli (z niewielkim przesunięciem w pionie w przypadku #graphics oraz #kbd):
<use href="#choinka" x="0" y="0"></use>
<use href="#blog-with-pen" x="100" y="0"></use>
<use href="#graphics" x="200" y="10"></use>
<use href="#screw" x="300" y="0" ></use>
<use href="#kbd" x="400" y="20" ></use>Dodatkowo, w sekcji <defs/>, utworzyłam widoki na poszczególne elementy (wykorzystując viewBox) i nadałam im opowiednie atrybuty id:
<view id="icon-aoc" viewBox="0 0 100 100"/>
<view id="icon-blog" viewBox="100 0 100 100"/>
<view id="icon-grafika" viewBox="200 10 100 100"/>
<view id="icon-howto" viewBox="300 0 100 100"/>
<view id="icon-programowanie" viewBox="400 20 100 100"/>Dzięki temu mogę w html-u użyć elementu img ze ścieżką do widoku; na przykład, aby wyświetlić jedynie klawiaturę, piszę tak:
<img src="/icons.svg#icon-kbd" width="100px" height="100px"/>Cały icons.svg:
A tutaj poszczególne fragmenty:
Fragment #icon-aoc:
Fragment #icon-blog:
Fragment #icon-grafika:
Fragment #icon-howto:
Fragment #icon-programowanie:
Żródła
Odnośniki do artykułów, z których korzystałam: