创建座位图
重要提示:此文档不适用于您当前选择的格式 stories!
座位图是票务员 Web 应用程序的重要组成部分,但在 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
表达式,以将选定座位添加到列表中 - 或者使用
amp-selector
,其动作为on="select:AMP.setState({selectedSeats: event.selectedOptions})"
,以便将所有选定的座位添加到列表中
虽然第一种方法不需要额外的组件 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>