Odpicuj mi forum - Interaktywna mapa

Awatar użytkownika

 Luxter#4127

#33112 30 wrz 2017, 18:13

Dzisiaj będzie coś naprawdę cool, czyli interaktywna mapa. Praktycznie na każdym forum taki twór może się przydać jako wizualizacja świata przedstawionego, czy alternatywny sposób nawigacji po tematach. Bez zbędnego przynudzania, zaczynajmy!

Zacznijmy może od tego, że wykorzystamy gotową bibliotekę jQuery, żeby tchnąć trochę życia w naszą mapę. Jest to konkretnie jQuery Mapael: https://www.vincentbroute.fr/mapael/ Oczywiście, jest zatrzęsienie alternatyw, ale ja w tym poradniku posłużę się akurat tym narzędziem. Przypatrzmy się teraz krok po kroku, jak stworzyć interaktywną mapę z jego wykorzystaniem.

Mapa

Najważniejszą częścią interaktywnej mapy jest mapa bazowa, czyli obrazek, który chcemy zmienić. Ja na potrzeby poradnika wybrałem mapę stanów Australii w formacie PNG: https://upload.wikimedia.org/wikipedia/ ... le.svg.png

Jak się okazuje, nasze narzędzie jQuery Mapael wymaga mapy w formacie zestawu ścieżek (gdzie jako ścieżkę rozumiem po prostu obrys każdego z obszarów). Jest to spowodowane faktem, że pod spodem kryją się HTML-owe mechanizmy SVG. Nie wdając się w zbędne szczegóły, chcemy przerobić nasze zdjęcie z formatu początkowego na format SVG. W tym celu skorzystałem z narzędzia Inkscape (taki program graficzny): https://inkscape.org/en/

Otworzyłem moją mapę PNG, a następnie wybrałem opcję Path -> Trace Bitmap i z domyślnymi wartościami wcisnąłem OK.
Obrazek

Następnie włączyłem widok XML Edit -> XML Editor oraz przeciągnąłem moje wygenerowane w poprzednim kroku ścieżki i otrzymałem taki wynik:
Obrazek

Jak widać wytworzyła się tylko jedna ścieżka dla całego obrazka, a my chcemy mieć 1 ścieżkę per każdy interesujący nas fragment. Klikamy więc Path -> Break Apart i BOOM, pojedyncza ścieżka rozbiła nam się na wiele mniejszych. Na potrzeby prostego przykładu, chcę mieć mało obszarów, ale oczywiście Wasza mapa może być ogromna. Po usunięciu większości ścieżek wynik prezentuje się tak:
Obrazek

Zwróćcie uwagę, że w otwartym wcześniej edytorze XML pozmieniałem też wartości pól "id" dla każdej ścieżki (żeby później łatwiej móc się do nich odwoływać). Lepiej mieć jakieś sensowne nazwy obszarów, niż "path3715", "path9023" które niewiele nam mówią. Z racji, że mój obrazek wynikowy ze ścieżkami jest mniejszy niż początkowy to użyłem jeszcze File -> Document Properties... -> Resize page to content... -> Resize path to drawing or selection, żeby przyciąć odpowiednio wymiary obrazka. Zapisujemy to jako plik SVG (z rozszerzeniem .svg) i gotowe. Nasza mapa jest już odpowiednio przetworzona.

Jak się okazuje, format pliku SVG jest w istocie formatem tekstowym (mimo, że przecież obrabiamy go jak plik graficzny w edytorze graficznym). Można sobie otworzyć nasz plik SVG w dowolnym edytorze tekstowym i powinniśmy zobaczyć, jak wygląda naprawdę. W moim przypadku jest to coś takiego: https://pastebin.com/1RVEHX0f

Konwersja z SVG do Mapael

Istnieje jeszcze jeden dodatkowy krok, który z naszej mapy w formacie SVG zrobi format kompatybilny z naszym narzędziem jQuery Mapael. Można albo samemu powybierać odpowiednie fragmenty i stworzyć z nich plik JavaScript, albo skorzystać z narzędzia udostępnionego tutaj: https://www.vincentbroute.fr/mapael/svg-to-mapael.php

Podajemy po prostu nazwę mapy (naszą dowolną zmyśloną nazwę), autora (nas) oraz wybieramy plik SVG. W moim przypadku jako nazwę wybrałem "Australia". Klikamy "Generate mapael map" i powinien nam się ściągnąć plik <nazwa>.js, czyli u mnie jest to australia.js. Jego zawartość w moim przypadku wygląda tak: https://pastebin.com/2FBzTpVG

jQuery Mapael

Mamy mapę, pora uczynić ją interaktywną. Na potrzeby przykładu posłużę się już dobrze znanym jsFiddle, żeby prezentować interaktywne próbki. Żeby skorzystać z naszej biblioteki jQuery Mapael musimy dodać takie oto linijki do naszego HTML-a:

Kod: Zaznacz cały

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.7/raphael.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mapael/2.1.0/js/jquery.mapael.min.js"></script>
Pierwsza dodaje jQuery (krok ten można pominąć, jeśli już mamy jQuery). Kolejne dwie to pliki związane bezpośrednio z naszą biblioteką.

Później dodalibyśmy coś w stylu:

Kod: Zaznacz cały

<script src="ścieżka do naszego pliku <nazwa>.js"></script>
żeby załączyć również naszą wygenerowaną mapę w formacie mapael. Jednakże, ja w moich przykładach nie mogę dołączać plików lokalnych, więc po prostu całą zawartość kopiuję do ćwiartki z JS.

Następnie trzeba dodać miejsce na naszą mapę w HTML:

Kod: Zaznacz cały

<div class="container">
  <div class="map">Could not load your map!</div>
</div>
Pozostaje już tylko zainicjalizowanie naszej biblioteki jQuery Mapael. Robimy to poprzez takie linijki pomiędzy znacznikami <script>tu te linijki</script>:

Kod: Zaznacz cały

$(".container").mapael({
  map: {
    name: "australia"
  }
});
Nie wdając się w zbędne szczegóły to ".container" odpowiada klasie "container" na naszym elemencie z HTML-a. ".mapael()" wywołuje funkcję biblioteczną mapael. Wszystko co jest wewnątrz jest w formacie JSON: https://pl.wikipedia.org/wiki/JSON A więc, dodajemy mapę, o nazwie "australia" (lub inną jeśli inaczej ją sobie wcześniej nazwaliście).

Efekt powinien być zbliżony do podanego: Wypróbuj

Dodałem odrobinę formatowania CSS, żeby zmniejszyć rozmiar mapki i ją wyśrodkować (Jest to stricte opcjonalnie tylko żeby przykład ładnie wyglądał).

Jak widać, mamy załączone 3 pliki JS w HTML (wy byście mieli 4, bo jeszcze jeden z naszą mapką <nazwa>.js), 3 linijki HTML-a na mapkę, 4 linijki CSS (CAŁKOWICIE OPCJONALNE), 5 linijek JS (z inicjalizacją, ja mam o wiele więcej, bo musiałem cały plik JS z naszą mapką <nazwa>.js przekopiować). I tyle, nasza mapka już jest interaktywna (możecie sobie na nią najechać kursorem i zobaczyć jak się podświetlają obszary).

TERAZ JUŻ WSZYSTKO ZALEŻY OD WAS. Odsyłam do dokumentacji https://www.vincentbroute.fr/mapael/#api-reference oraz przykładów https://www.vincentbroute.fr/mapael/#examples które pokazują możliwości narzędzia. Ja w ramach tego poradnika pokażę tylko niewielki podzbiór, tego co można zrobić.

Wartości domyślne

Wypróbuj

Jak widać dodałem wartości domyślne:

1. Dla obszarów:

Kod: Zaznacz cały

defaultArea: {
	attrs: {
	    fill: "yellow",
        stroke: "black"
    },
    attrsHover: {
        fill: "green"
    },
    text: {
        attrs: {
    	    fill: "red",
        	"font-size": 40
        },
        attrsHover: {
          	fill: "orange"
        }
    }
},
Czyli kolor tła żółty, ramka czarna, kolor tła w hoverze (po najechaniu) zielony, kolor czcionki czerwony, rozmiar czcionki 40, kolor czcionki w hoverze pomarańczowy. Kod de facto sam się opisuje i najtrudniej jest po prostu odpowiednio otwierać i zamykać klamry {}, oraz pamiętać o stawianiu przecinków pomiędzy kolejnymi atrybutami (nie trzeba po ostatnich), zgodnie ze specyfiką JSON-a.

2. Dla punktów (na mapie, które dodamy):

Kod: Zaznacz cały

defaultPlot: {
    text: {
        attrs: {
    		fill: "blue",
    		"font-size": 40
        },
        attrsHover: {
          	fill: "purple"
        }
    }
}
Kolor czcionki niebieski, rozmiar 40, po najechaniu kolor zmienia się na fioletowy.

Obszary

Wypróbuj

Dodajemy sobie formatowanie dla konkretnego obszaru (zachodniego) poprzez:

Kod: Zaznacz cały

areas: {
    "western": {
      	text: {
        	content: "Western \n Australia"
      	}
    }
},
Zwróćcie uwagę, że "western" odpowiada id jednej ze wcześniej utworzonych ścieżek (tam też było id = "western"). To się musi zgadzać, żeby biblioteka wiedziała, o który obszar nam chodzi!

Punkty

Wypróbuj

Kod: Zaznacz cały

plots: {
    'facebook': {
    	x: 500,
      	y: 240,
      	href: "https://www.facebook.com/",
      	text: {
        	content: "Fb",
        	position: "bottom",
        	attrs: {
          		opacity: 0.6
        	},
        	attrsHover: {
          		opacity: 1
        	}
    	},
    },
}
Dodaliśmy sobie punkt o nazwie "facebook" w pozycji o podanych współrzędnych x i y, przenoszący po kliknięciu na stronę facebooka, z tekstem "FB" umieszczonym POD punktem, widoczność 60%, a po najechaniu 100%. Oczywiście w moim jsFiddle przykład się popsuje przy próbie przejścia na facebooka (ale u Was, na stronce powinno działać).

I to już koniec. Pokazałem jak z mapki w zwykłym formacie stworzyć zbiór ścieżek w formacie SVG, a później jak je przekonwertować do formatu mapael. Następnie zademonstrowałem jak podpiąć bibliotekę pod naszą stronę oraz wykorzystać wygenerowaną wcześniej mapę. Dalej był przykład nadpisania domyślnego stylizowania podstawowych elementów (obszarów oraz punktów). Kolejne przykłady tyczyły się modyfikacji konkretnego obszaru (dodanie mu treści, zmiana formatowania) oraz dodania nowego punktu na mapie (z treścią oraz możliwością kliknięcia w niego). Jak wspominałem jest to tylko wierzchołek góry lodowej możliwości, m.in. możliwość zoomowania mapy, dodawanie legendy, połączenia między obszarami, zdarzenia przy dynamicznym dodawaniu obszarów, edycji, klikaniu i wiele wiele więcej. Mam nadzieję, że udało się pokazać, że stosunkowo łatwo i szybko można stworzyć naprawdę ciekawą mapę, która urozmaici fora. Enjoy!
Common sense is so rare that it should be classified as a super power. ~ Bill Murray.
Where ignorance is bliss, 'tis folly to be wise. ~ Thomas Gray.

ODPOWIEDZ ]