建立座位圖
座位圖是票務人員網路應用程式的重要部分,但在 AMP 中實作可能很困難。請繼續閱讀以瞭解如何透過結合可用的 AMP 元件在 AMP 中實作座位圖。
需要的 AMP 元件
讓我們先從檢閱需要的元件開始
amp-pan-zoom
amp-pan-zoom
允許透過雙擊和雙指撥動來縮放和平移內容。此元件作為座位圖實作的基礎。
amp-list
amp-list
從 CORS JSON 端點動態擷取內容,並使用提供的範本呈現。用於擷取目前的座位圖可用性,以便使用者始終獲得最新的資料。
amp-bind
amp-bind
為頁面新增互動性。此處需要用來追蹤已選取多少座位。
amp-selector
amp-selector
代表一個控制項,可呈現選項選單並讓使用者從中選擇。整個座位圖可以視為選項選單,其中每個座位都是一個選項。透過允許您使用 CSS 表達式,它可以更輕鬆地設定已選取座位的樣式。例如,以下表達式會在選取座位後,將座位填滿橘色。
rect[selected].seat {
fill: var(--orange-theme);
}
需求條件
- 若要將座位圖繪製為 SVG,其中每個座位都以
rect
元素表示,您需要每個座位的相關資訊:位置x
和y
、width
和height
,以及可能的rx
和ry
(用於將矩形的角變成圓角)。 - 每個座位的唯一識別碼,可用於進行預訂。
- 座位圖的總寬度和高度的量值,用於
viewbox
屬性中。
繪製座位圖
座位圖透過 amp-list
和 amp-mustache
呈現。從 amp-list
呼叫接收資料後,您可以使用所述資料來逐一查看座位
<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>
設定無法使用座位的樣式
在上述範例中,{{unavailable}}
是 JSON 端點傳回的欄位值,用於設定無法使用座位的樣式。這種方法不允許您移除屬性 (例如,在座位無法使用時的 option=""
),因為範本無法包裝整個頁面的 <html>
元素。
另一種更詳細的方法是重複標記,如下所示
{{#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 }}
調整座位圖大小
除非您的座位圖大小是固定的,否則很難調整包含座位圖的 amp-list
大小。amp-list
需要固定尺寸,或使用 layout="fill"
(以使用父容器的可用空間)。有兩種方法可以解決此問題
- 在您知道其他元件 (例如標頭和頁尾) 使用的空間後,計算頁面上的可用空間。此計算可以在 CSS 中透過使用
calc
表達式來完成,並將其指定為amp-list
父 div 的min-height
。 - 在知道頁面版面配置的高度時,使用彈性版面配置。
設定 amp-pan-zoom 的樣式
如果使用先前章節中描述的方法,則 amp-pan-zoom
也需要使用 layout="fill"
。
- 為 svg 新增包裝 div
- 新增邊距
如果您沒有包裝 div,而是改為將邊界新增至 SVG,則邊界不會成為雙指撥動和縮放區域的一部分。
處理狀態
當使用者按一下不同的座位時,可以使用 amp-state
透過以下方式追蹤所選座位的 id
變數:
- 為每個座位新增
amp-bind
表達式,以將選取的座位新增至清單 - 或搭配動作
on="select:AMP.setState({selectedSeats: event.selectedOptions})"
使用amp-selector
,以便將所有選取的座位新增至清單
雖然第一種方法不需要額外的元件 amp-selector
,但它可能會使座位圖變得非常慢,因為每個 amp-bind
表達式都會在每次座位選取/取消選取時進行評估。
第二種方法也允許您減少範本將呈現的每個座位的 amp-bind
表達式的重複。
最終 HTML 結構
如需參考,以下是座位圖的最終 HTML
<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>