Tworzenie mapy miejsc
Mapy miejsc są ważną częścią aplikacji internetowych automatów biletowych, ale ich implementacja w AMP może być trudna. Czytaj dalej, aby dowiedzieć się jak zaimplementować mapę miejsc w AMP, wykorzystując kombinację dostępnych składników AMP.
Niezbędne składniki AMP
Zacznijmy od przeglądu niezbędnych składników:
amp-pan-zoom
amp-pan-zoom
umożliwia powiększanie i przesuwanie zawartości za pomocą podwójnego dotknięcia i gestu szczypania. Ten składnik służy jako podstawa do implementacji mapy miejsc.
amp-list
Składnik amp-list
dynamicznie pobiera zawartość z punktu końcowego mechanizmu CORS JSON i renderuje ją za pomocą dostarczonego szablonu. Służy do pobierania bieżącej dostępności miejsc na mapie, dzięki czemu użytkownicy zawsze otrzymują najnowsze dane.
amp-bind
Składnik amp-bind
dodaje do strony interaktywność. Tutaj jest niezbędny do śledzenie liczby zajętych miejsc.
amp-selector
Składnik amp-selector
reprezentuje kontrolkę, która prezentuje menu opcji i pozwala użytkownikowi na wybór z tego menu. Cała mapa miejsc może być traktowana jako menu opcji, w którym każde miejsce jest opcją. Znacznie ułatwia to stylizację stanu zajętości miejsc, umożliwiając użycie wyrażeń CSS. Na przykład następujące wyrażenie po zajęciu miejsca wypełnia je kolorem pomarańczowym.
rect[selected].seat {
fill: var(--orange-theme);
}
Wymagania
- Aby rysować mapę miejsc jako SVG, w którym każde miejsce jest reprezentowane przez element
rect, niezbędne są następujące informacje o każdym miejscu: pozycja x
iy
,width
(szerokość) iheight
(wysokość) oraz, ewentualnie, promienierx
iry
w celu zaokrąglenia narożników prostokątów. - Niepowtarzalny identyfikator każdego miejsca, którego można użyć do dokonania rezerwacji.
- Miara całkowitej szerokości i wysokości mapy miejsc, która zostanie użyta w atrybucie
viewbox
.
Rysowanie mapy miejsc
Mapa miejsc jest renderowana za pomocą składników amp-list
oraz amp-mustache
. Po otrzymaniu danych z wywołania amp-list
można użyć owych danych do iteracji przez miejsca:
<svg preserveAspectRatio="xMidYMin slice" viewBox="0 0 {{width}} {{height}}"> {{#seats}} <rect option="{{id}}" role="button" tabindex="0" class="seat {{unavailable}}" x="{{x}}" y="{{y}}" width="{{width}}" height="{{height}}" rx="{{rx}}" ry="{{ry}}"/> {{/seats}} </svg>
Stylizacja niedostępnych miejsc
W powyższym przykładzie {{unavailable}}
jest wartością pola zwróconą przez punkt końcowy JSON i używaną do stylizacji niedostępnego miejsca. Takie podejście nie pozwala na usunięcie atrybutów takich jak option=""
w przypadku, gdy miejsce jest niedostępne, ponieważ szablon nie może otoczyć elementu całych stron <html>
.
Alternatywnym, bardziej szczegółowym podejściem jest powtarzanie znaczników w następujący sposób:
{{#available }}<rect option="" role="button" tabindex="0" class="seat" x="" y="" width="" height="" rx="" ry=""/>{{/available }} {{^available}}<rect role="button" tabindex="0" class="seat unavailable" x="" y="" width="" height="" rx="" ry=""/>{{/available }}
Ustawianie rozmiaru mapy miejsc
Jeśli rozmiar mapy miejsc nie jest ustalony, trudno jest ustawiać rozmiar składnika amp-list
zawierającego mapę miejsc. Składnik amp-list
wymaga albo podania ustalonych wymiarów, albo użycia właściwości layout="fill"
(w celu wykorzystania dostępnego miejsca w kontenerze nadrzędnym). Ten problem można rozwiązać na dwa sposoby:
- Oblicz dostępne miejsce na stronie, gdy poznasz miejsce zajmowane przez inne składniki, takie jak nagłówki i stopki. Obliczenie to można wykonać w CSS, używając wyrażenia
calc
i przypisując je jakomin-height
nadrzędnego elementu div składnikaamp-list
. - Znając wysokość układu strony, użyj układu flex.
Stylizacja składnika amp-pan-zoom
W przypadku podejścia opisanego w poprzedniej sekcji w składniku amp-pan-zoom
również należy zastosować właściwość layout="fill"
.
- Dodaj otokę div do svg
- Dodaj wypełnienie
Jeśli nie masz otoki div i zamiast tego dodasz do SVG margines, marginesy nie staną się częścią obszaru szczypania i powiększania.
Obsługa stanu
Gdy użytkownicy klikają różne miejsca, śledzenie id
wybranych miejsc w zmiennej za pomocą składnika amp-state
jest możliwe na następujące sposoby:
- Poprzez dodanie do każdego miejsca wyrażenia
amp-bind
w celu dodawania wybranych miejsc do listy - Można też użyć kontrolki
amp-selector
z działaniemon="select:AMP.setState({selectedSeats: event.selectedOptions})"
w celu dodawania wszystkich wybranych miejsc do listy
Pierwsze podejście nie wymaga dodatkowego składnika amp-selektor
, ale może bardzo spowolnić mapę miejsc, ponieważ po każdym zajęciu/zwolnieniu miejsca obliczane będzie każde wyrażenie amp-bind
.
Drugie podejście pozwala również ograniczyć dublowanie wyrażenia amp-bind
dla każdego miejsca, które będzie renderowane przez szablon.
Końcowa struktura HTML
Oto ostateczny poglądowy kod HTML mapy miejsc:
<div class="seatmap-container"> <amp-list layout="fill" src="/json/seats.json" binding="no" items="." single-item noloading> <template type="amp-mustache"> <amp-pan-zoom layout="fill" class="seatmap"> <amp-selector multiple on="select:AMP.setState({ selectedSeats: event.selectedOptions })" layout="fill"> <div class="svg-container"> <svg preserveAspectRatio="xMidYMin slice" viewBox="0 0 {{width}} {{height}}"> {{#seats}} <rect option="{{id}}" role="button" tabindex="0" class="seat {{unavailable}}" x="{{x}}" y="{{y}}" width="{{width}}" height="{{height}}" rx="{{rx}}" ry="{{ry}}"/> {{/seats}} </svg> </div> </amp-selector> </amp-pan-zoom> </template> </amp-list> </div>