Erstelle einen Sitzplan
Sitzpläne sind wichtige Bestandteile von Web Apps für Ticketverkauf, die Implementierung in AMP kann jedoch schwierig sein. Lies weiter, um zu erfahren, wie du einen Sitzplan in AMP mithilfe einer Kombination verfügbarer AMP Komponenten implementierst.
Benötigte AMP Komponenten
Beginnen wir mit einer Übersicht über die benötigten Komponenten:
amp-pan-zoom
amp-pan-zoom
ermöglicht das Zoomen und Schwenken von Inhalt durch Doppeltippen und Pinchen. Diese Komponente dient als Basis für die Implementierung des Sitzplans.
amp-list
amp-list
ruft Inhalte dynamisch von einem CORS JSON Endpoint ab und rendert sie mithilfe eines vorgegebenen Templates. Mit dieser Komponente wird die aktuelle Verfügbarkeit des Sitzplans abgerufen, damit Benutzer immer die neuesten Daten erhalten.
amp-bind
amp-bind
erweitert die Seite um zusätzliche Interaktivität. Wird in diesem Fall benötigt, um mitzuverfolgen, wie viele Sitze ausgewählt wurden.
amp-selector
amp-selector
stellt ein Steuerelement dar, das ein Menü mit Optionen anzeigt, aus denen Benutzer wählen können. Der gesamte Sitzplan kann als Optionsmenü betrachtet werden, wobei jeder Sitz eine Option ist. Dies erleichtert die Gestaltung des ausgewählten Status der Sitze erheblich, da du dafür CSS Ausdrücke verwenden kannst. Der folgende Ausdruck ändert beispielsweise die Füllfarbe eines Sitzes zu Orange, sobald er ausgewählt wird.
rect[selected].seat {
fill: var(--orange-theme);
}
Anforderungen
- Um einen Sitzplan als SVG zu zeichnen, wobei jeder Sitz durch das Element
rect
dargestellt wird, benötigst du folgende Informationen zu jedem Sitz: Positionx
undy
,width
undheight
und eventuellrx
undry
, um die Ecken der Rechtecke abzurunden. - Eine eindeutige Kennung für den spezifischen Sitz, der für die Buchung verwendet werden kann.
- Ein Maß für die gesamte Breite und Höhe des Sitzplans, die im Attribut
viewbox
verwendet werden soll.
Sitzplan zeichnen
Der Sitzplan wird über amp-list
und amp-mustache
gerendert. Sobald du die Daten über den Aufruf von amp-list
erhalten hast, kannst du anhand dieser Daten die Sitze durchlaufen:
<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>
Nicht verfügbare Sitze gestalten
Im obigen Beispiel ist {{unavailable}}
der Wert eines Feldes, der vom JSON Endpoint zurückgegeben und zur Gestaltung eines nicht verfügbaren Sitzes verwendet wird. Bei diesem Ansatz ist es nicht möglich, Attribute wie option=""
zu entfernen, falls ein Sitz nicht verfügbar ist, da das Template nicht das <html>
Element aller Seiten vollständig umschließen kann.
Bei einer ausführlicheren Alternative dazu werden die Tags wie folgt wiederholt:
{{#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 }}
Dimensionierung des Sitzplans
Wenn die Größe deines Sitzplans nicht festgelegt ist, ist es schwierig, die Größe der amp-list
festzulegen, welche den Sitzplan enthält. amp-list
benötigt entweder feste Maße oder verwendet layout="fill"
(um den verfügbaren Platz des übergeordneten Containers zu nutzen). Es gibt zwei mögliche Lösungen für dieses Problem:
- Berechne den verfügbaren Platz auf der Seite, sobald du weißt, wie viel Platz die anderen Komponenten wie Header und Footer benötigen. Diese Berechnung kann in CSS mithilfe des Ausdrucks
calc
erfolgen. Dabei wird dieser Ausdruck alsmin-height
des übergeordneten div Elements deramp-list
verwendet. - Verwende ein flexibles Layout, wenn du die Höhe des Seitenlayouts kennst.
Gestaltung von amp-pan-zoom
Wenn du den im vorherigen Abschnitt beschriebenen Ansatz verwendest, muss für amp-pan-zoom
auch layout="fill"
verwendet werden.
- Füge ein umschließendes div für die SVG hinzu,
- füge Padding hinzu.
Wenn du kein umschließendes div einbaust und stattdessen dem SVG einen Außenrand (margin) gibst, werden die Ränder nicht Teil des Bereichs sein, in dem Pinchen und Zoomen möglich sind.
Verarbeitung des Status
Wenn Benutzer auf verschiedene Sitze klicken, können die id
s der ausgewählten Sitze in einer Variablen mithilfe von amp-state
verfolgt werden. Dazu kannst du entweder
- den Ausdruck
amp-bind
für jeden Sitz hinzufügen, um den ausgewählten Sitz in eine Liste einzutragen, oder amp-selector
mit der Aktionon="select:AMP.setState({selectedSeats: event.selectedOptions})"
verwenden, um alle ausgewählten Sitze in eine Liste einzutragen.
Während die zusätzliche Komponente amp-selector
beim ersten Ansatz nicht erforderlich ist, kann der Verzicht darauf den Sitzplan stark verlangsamen, da jede Instanz von amp-bind
immer dann ausgewertet wird, wenn ein Sitz ausgewählt bzw. dessen Auswahl aufgehoben wird.
Beim zweiten Ansatz kann außerdem die Duplizierung des Ausdrucks amp-bind
für jeden Sitz, den das Template rendert, reduziert werden.
Endgültige HTML Struktur
Als Referenz findest du hier den endgültigen HTML Code für den Sitzplan:
<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>