AMP

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.

Rzeczywisty przykład zastosowania opisanych poniżej praktyk dostępny jest tutaj.

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

  1. 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 i y, width (szerokość) i height (wysokość) oraz, ewentualnie, promienie rx i ry w celu zaokrąglenia narożników prostokątów.
  2. Niepowtarzalny identyfikator każdego miejsca, którego można użyć do dokonania rezerwacji.
  3. 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:

  1. 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 jako min-height nadrzędnego elementu div składnika amp-list.
  2. 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".

PORADA — aby zachować trochę białej przestrzeni wokół mapy miejsc, nadal czyniąc ją częścią obszaru szczypania i powiększania:

  • 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łaniem on="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>