Pliki SVG (Scalable Vector Graphics) w dobie wszechobecnych smartfonów i innych urządzeń o ekranach z wysokim ppi powinny być standardem, ale nadal ze świecą szukać przykładów ich zastosowania w komercyjnych produktach. Po części jest to wina mało świadomych deweloperów, nadal bardzo popularny jest mit o słabym wsparciu dla SVG. Jeżeli zależy nam na wsparciu IE8 nic(?) nie stoi na przeszkodzie by zainteresować się np. SVGeezy.
Z mojego doświadczenia wynika, że plik SVG, w zależności od tego jak bardzo jest złożony, może być zawsze zmniejszony o kilkadziesiąt procent. Dla ikony złożonej z 5-6 elementów jest to nawet 60-70%. Jak to możliwe?
(Nie)czysty SVG
Winna leży po stronie edytorów. Za przykład weźmy opensourcowy Inkscape i logo WEBroad. Ikona 60×64 w formacie Inkscape SVG to 3 850b.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="64px" height="64px" id="svg3054" version="1.1" inkscape:version="0.48.4 r9939" sodipodi:docname="Nowy dokument 6"> <defs id="defs3056" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="11" inkscape:cx="42.030106" inkscape:cy="31.8742" inkscape:current-layer="layer1" showgrid="true" inkscape:document-units="px" inkscape:grid-bbox="true" inkscape:window-width="1920" inkscape:window-height="1057" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" /> <metadata id="metadata3059"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer"> <path style="fill:#d70000;fill-opacity:1;fill-rule:evenodd;stroke:none" d="M 2.1469587,19.144324 C 2.7477757,10.064402 40.327302,-1.025797 46.893937,2.76281 c 6.93892,5.073804 18.16498,36.910875 14.32665,44.200722 -4.4077,8.288616 -39.727128,18.061036 -44.431678,14.14586 C 11.651025,57.672471 0.60066671,28.805927 2.1469587,19.144324 z" id="rect3003" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccc" /> <path style="fill:#eca702;fill-opacity:1;fill-rule:evenodd;stroke:none" d="M 7.5618827,16.138311 C 8.7573597,9.826203 35.691092,6.488753 39.970685,9.714543 c 4.311072,3.236788 8.631942,27.022469 5.319912,31.79869 -2.5923,5.18506 -29.120743,8.356652 -32.084354,5.203852 C 9.8981077,43.861842 5.6540957,22.775996 7.5618827,16.138311 z" id="rect3003-7" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccc" /> <path style="fill:#fff600;fill-opacity:1;fill-rule:evenodd;stroke:none" d="m 12.154016,15.047001 c 1.546443,-3.897751 19.269113,-3.64943 21.615229,-1.042245 2.327917,3.224683 3.085727,18.458081 0.371593,21.104558 -3.105071,3.002803 -19.631471,2.67902 -21.142643,0.284206 -1.768887,-2.247307 -2.887667,-16.329572 -0.844179,-20.346519 z" id="rect3003-4" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccc" /> <path style="fill:#fffcb2;fill-opacity:1;fill-rule:evenodd;stroke:none" d="m 20.268697,14.869558 c 0.940881,-2.371453 11.613036,-1.927403 13.040449,-0.341156 1.416346,1.961955 1.401857,11.219206 -0.249464,12.829367 -1.889183,1.826956 -11.800652,1.082429 -12.720083,-0.374616 -1.076223,-1.367296 -1.314195,-9.669619 -0.0709,-12.1136 z" id="rect3003-0" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccc" /> <path style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" d="m 20.360518,18.993825 c 0.702033,-1.378086 6.496464,-0.941347 7.288573,-0.0914 0.789611,1.054615 0.760123,6.163816 -0.123789,7.056318 -1.011375,1.012818 -6.596724,0.698008 -7.111029,-0.08647 -0.598837,-0.734112 -0.707659,-5.535884 -0.05376,-6.878451 z" id="rect3003-9" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccc" /> </g> </svg> |
Inkscape umożliwia również zapis do czystego SVG. Rozmiar takiego pliku to już 2 663b. Niby lepiej, ale jak podejrzymy źródło zobaczymy wiele zbędnego kodu. Jak się okazuje „czysty” to pojęcie względne.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="64" height="64" id="svg3054"> <defs id="defs3056" /> <metadata id="metadata3059"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g id="layer1"> <path d="M 2.1469587,19.144324 C 2.7477757,10.064402 40.327302,-1.025797 46.893937,2.76281 c 6.93892,5.073804 18.16498,36.910875 14.32665,44.200722 -4.4077,8.288616 -39.727128,18.061036 -44.431678,14.14586 C 11.651025,57.672471 0.60066671,28.805927 2.1469587,19.144324 z" id="rect3003" style="fill:#d70000;fill-opacity:1;fill-rule:evenodd;stroke:none" /> <path d="M 7.5618827,16.138311 C 8.7573597,9.826203 35.691092,6.488753 39.970685,9.714543 c 4.311072,3.236788 8.631942,27.022469 5.319912,31.79869 -2.5923,5.18506 -29.120743,8.356652 -32.084354,5.203852 C 9.8981077,43.861842 5.6540957,22.775996 7.5618827,16.138311 z" id="rect3003-7" style="fill:#eca702;fill-opacity:1;fill-rule:evenodd;stroke:none" /> <path d="m 12.154016,15.047001 c 1.546443,-3.897751 19.269113,-3.64943 21.615229,-1.042245 2.327917,3.224683 3.085727,18.458081 0.371593,21.104558 -3.105071,3.002803 -19.631471,2.67902 -21.142643,0.284206 -1.768887,-2.247307 -2.887667,-16.329572 -0.844179,-20.346519 z" id="rect3003-4" style="fill:#fff600;fill-opacity:1;fill-rule:evenodd;stroke:none" /> <path d="m 20.268697,14.869558 c 0.940881,-2.371453 11.613036,-1.927403 13.040449,-0.341156 1.416346,1.961955 1.401857,11.219206 -0.249464,12.829367 -1.889183,1.826956 -11.800652,1.082429 -12.720083,-0.374616 -1.076223,-1.367296 -1.314195,-9.669619 -0.0709,-12.1136 z" id="rect3003-0" style="fill:#fffcb2;fill-opacity:1;fill-rule:evenodd;stroke:none" /> <path d="m 20.360518,18.993825 c 0.702033,-1.378086 6.496464,-0.941347 7.288573,-0.0914 0.789611,1.054615 0.760123,6.163816 -0.123789,7.056318 -1.011375,1.012818 -6.596724,0.698008 -7.111029,-0.08647 -0.598837,-0.734112 -0.707659,-5.535884 -0.05376,-6.878451 z" id="rect3003-9" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> </g> </svg> |
Pierwszą czynnością jaką możemy zrobić to ręcznie wyczyścić taki kod. Wymagany jest jedynie atrybut xmlns dla elementu svg oraz przydatne będą również jego rozmiary oraz opcjonalnie viewBox. Istnieją jednak narzędzia, które oferują automatyczne optymalizowanie jednego lub wielu plików.
SVGO
SVGO to proste i co najważniejsze skuteczne narzędzie obsługiwane z poziomu konsoli, oparte na Node.js. Instalacja i sposób korzystania z narzędzia jest opisany w repozytorium projektu, przejdźmy do efektów.
Zoptymalizowane za pomocą SVGO logo WEBroad to już tylko 1 022b. Prawie 4-krotnie mniej niż pierwotnie! Kod taki jest jednak uciążliwy przy dalszej pracy np. podczas animacji na poszczególnych ścieżkach.
1 | <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><g fill-rule="evenodd"><path d="M2.147 19.144c.601-9.08 38.18-20.17 44.747-16.382 6.939 5.074 18.165 36.911 14.327 44.201-4.408 8.289-39.727 18.061-44.432 14.146-5.138-3.437-16.188-32.303-14.642-41.965z" fill="#d70000"/><path d="M7.562 16.138c1.195-6.312 28.129-9.65 32.409-6.424 4.311 3.237 8.632 27.022 5.32 31.799-2.592 5.185-29.121 8.357-32.084 5.204-3.308-2.855-7.552-23.941-5.644-30.579z" fill="#eca702"/><path d="M12.154 15.047c1.546-3.898 19.269-3.649 21.615-1.042 2.328 3.225 3.086 18.458.372 21.105-3.105 3.003-19.631 2.679-21.143.284-1.769-2.247-2.888-16.33-.844-20.347z" fill="#fff600"/><path d="M20.269 14.87c.941-2.371 11.613-1.927 13.04-.341 1.416 1.962 1.402 11.219-.249 12.829-1.889 1.827-11.801 1.082-12.72-.375-1.076-1.367-1.314-9.67-.071-12.114z" fill="#fffcb2"/><path d="M20.361 18.994c.702-1.378 6.496-.941 7.289-.091.79 1.055.76 6.164-.124 7.056-1.011 1.013-6.597.698-7.111-.086-.599-.734-.708-5.536-.054-6.878z" fill="#fff"/></g></svg> |
Korzystając z opcji --pretty możemy wygenerować „ładnie” sformatowany plik o niewiele większym rozmiarze 1 079b.
1 2 3 4 5 6 7 8 9 | <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"> <g fill-rule="evenodd"> <path d="M2.147 19.144c.601-9.08 38.18-20.17 44.747-16.382 6.939 5.074 18.165 36.911 14.327 44.201-4.408 8.289-39.727 18.061-44.432 14.146-5.138-3.437-16.188-32.303-14.642-41.965z" fill="#d70000"/> <path d="M7.562 16.138c1.195-6.312 28.129-9.65 32.409-6.424 4.311 3.237 8.632 27.022 5.32 31.799-2.592 5.185-29.121 8.357-32.084 5.204-3.308-2.855-7.552-23.941-5.644-30.579z" fill="#eca702"/> <path d="M12.154 15.047c1.546-3.898 19.269-3.649 21.615-1.042 2.328 3.225 3.086 18.458.372 21.105-3.105 3.003-19.631 2.679-21.143.284-1.769-2.247-2.888-16.33-.844-20.347z" fill="#fff600"/> <path d="M20.269 14.87c.941-2.371 11.613-1.927 13.04-.341 1.416 1.962 1.402 11.219-.249 12.829-1.889 1.827-11.801 1.082-12.72-.375-1.076-1.367-1.314-9.67-.071-12.114z" fill="#fffcb2"/> <path d="M20.361 18.994c.702-1.378 6.496-.941 7.289-.091.79 1.055.76 6.164-.124 7.056-1.011 1.013-6.597.698-7.111-.086-.599-.734-.708-5.536-.054-6.878z" fill="#fff"/> </g> </svg> |
Iconizr
Iconizr to bardziej rozbudowane narzędzie pozwalające m. in. na łączenie plików svg i zmniejszenie w ten sposób ilości zapytań do serwera. Iconizr napisany został w PHP i poza dostępem z konsoli oferuje możliwość optymalizacji plików SVG z poziomu przeglądarki. Poza samym plikiem SVG otrzymujemy również kod CSS/SCSS. Efekt jest co najmniej zadowalający.
Plik SVG:
1 2 3 | <?xml version="1.0"?> <!--Icons from directory ""--> <svg xmlns="http://www.w3.org/2000/svg" width="64" height="192" viewBox="0 0 64 192"><svg width="64" height="64" id="webroad_blue" y="0"><g fill-rule="evenodd"><path d="m2.147 19.144c0.601-9.08 38.18-20.17 44.747-16.382 6.939 5.074 18.165 36.911 14.327 44.201-4.408 8.289-39.727 18.061-44.432 14.146-5.138-3.437-16.188-32.303-14.642-41.965z" fill="#00f"/><path d="m7.562 16.138c1.195-6.312 28.129-9.65 32.409-6.424 4.311 3.237 8.632 27.022 5.32 31.799-2.592 5.185-29.121 8.357-32.084 5.204-3.308-2.855-7.552-23.941-5.644-30.579z" fill="#005dff"/><path d="m12.154 15.047c1.546-3.898 19.269-3.649 21.615-1.042 2.328 3.225 3.086 18.458 0.372 21.105-3.105 3.003-19.631 2.679-21.143 0.284-1.769-2.247-2.888-16.33-0.844-20.347z" fill="#00beff"/><path d="m20.269 14.87c0.941-2.371 11.613-1.927 13.04-0.341 1.416 1.962 1.402 11.219-0.249 12.829-1.889 1.827-11.801 1.082-12.72-0.375-1.076-1.367-1.314-9.67-0.071-12.114z" fill="#00efff"/><path d="m20.361 18.994c0.702-1.378 6.496-0.941 7.289-0.091 0.79 1.055 0.76 6.164-0.124 7.056-1.011 1.013-6.597 0.698-7.111-0.086-0.599-0.734-0.708-5.536-0.054-6.878z" fill="#fff"/></g></svg><svg width="64" height="64" id="webroad_green" y="64"><g fill-rule="evenodd"><path d="m2.147 19.144c0.601-9.08 38.18-20.17 44.747-16.382 6.939 5.074 18.165 36.911 14.327 44.201-4.408 8.289-39.727 18.061-44.432 14.146-5.138-3.437-16.188-32.303-14.642-41.965z" fill="#008f00"/><path d="m7.562 16.138c1.195-6.312 28.129-9.65 32.409-6.424 4.311 3.237 8.632 27.022 5.32 31.799-2.592 5.185-29.121 8.357-32.084 5.204-3.308-2.855-7.552-23.941-5.644-30.579z" fill="#00af00"/><path d="m12.154 15.047c1.546-3.898 19.269-3.649 21.615-1.042 2.328 3.225 3.086 18.458 0.372 21.105-3.105 3.003-19.631 2.679-21.143 0.284-1.769-2.247-2.888-16.33-0.844-20.347z" fill="#00d600"/><path d="m20.269 14.87c0.941-2.371 11.613-1.927 13.04-0.341 1.416 1.962 1.402 11.219-0.249 12.829-1.889 1.827-11.801 1.082-12.72-0.375-1.076-1.367-1.314-9.67-0.071-12.114z" fill="#0f0"/><path d="m20.361 18.994c0.702-1.378 6.496-0.941 7.289-0.091 0.79 1.055 0.76 6.164-0.124 7.056-1.011 1.013-6.597 0.698-7.111-0.086-0.599-0.734-0.708-5.536-0.054-6.878z" fill="#fff"/></g></svg><svg width="64" height="64" id="webroad_red" y="128"><g fill-rule="evenodd"><path d="m2.147 19.144c0.601-9.08 38.18-20.17 44.747-16.382 6.939 5.074 18.165 36.911 14.327 44.201-4.408 8.289-39.727 18.061-44.432 14.146-5.138-3.437-16.188-32.303-14.642-41.965z" fill="#d70000"/><path d="m7.562 16.138c1.195-6.312 28.129-9.65 32.409-6.424 4.311 3.237 8.632 27.022 5.32 31.799-2.592 5.185-29.121 8.357-32.084 5.204-3.308-2.855-7.552-23.941-5.644-30.579z" fill="#eca702"/><path d="m12.154 15.047c1.546-3.898 19.269-3.649 21.615-1.042 2.328 3.225 3.086 18.458 0.372 21.105-3.105 3.003-19.631 2.679-21.143 0.284-1.769-2.247-2.888-16.33-0.844-20.347z" fill="#fff600"/><path d="m20.269 14.87c0.941-2.371 11.613-1.927 13.04-0.341 1.416 1.962 1.402 11.219-0.249 12.829-1.889 1.827-11.801 1.082-12.72-0.375-1.076-1.367-1.314-9.67-0.071-12.114z" fill="#fffcb2"/><path d="m20.361 18.994c0.702-1.378 6.496-0.941 7.289-0.091 0.79 1.055 0.76 6.164-0.124 7.056-1.011 1.013-6.597 0.698-7.111-0.086-0.599-0.734-0.708-5.536-0.054-6.878z" fill="#fff"/></g></svg></svg> |
Plik CSS:
1 2 3 4 5 6 7 | /* Icons from directory "" */ .icon-webroad_blue,.icon-webroad_blue\:regular{background-image:url('icons/icons.svg');background-position:0 0;background-repeat:no-repeat} .icon-webroad_blue-dims{width:64px;height:64px} .icon-webroad_green,.icon-webroad_green\:regular{background-image:url('icons/icons.svg');background-position:0 -64px;background-repeat:no-repeat} .icon-webroad_green-dims{width:64px;height:64px} .icon-webroad_red,.icon-webroad_red\:regular{background-image:url('icons/icons.svg');background-position:0 -128px;background-repeat:no-repeat} .icon-webroad_red-dims{width:64px;height:64px} |
Jeżeli chodzi o samo wykorzystanie plików SVG to Chris Coyier w artykule Using SVG przedstawił już większość sposobów pracy z grafiką wektorową. Jeżeli znacie jakieś ciekawe przykłady zastosowania SVG to dajcie nam znać w komentarzach.
Tagi: grafika wektorowa • iconizr • promowany • svg • svgo
Robert
szukałem przewijania w dół strony " jak to sie nazywa", ale Progress bar takze dodam do siebie.2023-07-15 23:55:00