写点什么

超大型场馆的绘座选座解决方案

  • 2020-03-20
  • 本文字数:3420 字

    阅读完需:约 11 分钟

超大型场馆的绘座选座解决方案

超大型场馆座位图的加载与渲染在行业内始终是个不小的挑战,很多团队在面对绘座选座技术研发时,都难以支撑超大型场馆的座位图在浏览器端快速、稳定地渲染。如果你是奋斗在现场娱乐、剧院演出和电影院线相关行业内的一名开发者,那么文章将帮助你更多的了解大场馆座位图技术,同时可以帮助你扩展绘座选座核心功能开发的思路。

一、业务场景

麦座是一套完善的数字化运营系统,连接内容和场馆,提供票务生产、票务销售、现场管理和演出运营等能力,绘座选座是麦座的核心能力之一,从建设场馆到规划票房再到门店销售。目前可支持的十万座位量级的场馆,包括剧院、演唱会、体育赛事等多个垂类。



本文将介绍麦座的绘座、票房规划、锁座和门店销售等场景是如何通过技术手段实现业务需求的,以及超大型场馆的座位图是如何打破性能边界,给用户呈现出更流畅的交互体验。

二、功能场景

麦座的座位图相关的业务可以分为“绘座”和“选座”两大功能场景。选座就是通过用户事件绑定选中的座位进而完成接下来的业务逻辑,而绘座包括绘制座位、设置楼层、看台、舞台、出口等信息,绘制座位同时又涉及到如何给块级座位进行变形处理。那么,绘制的座位是如何填满看台区域的呢?又是如何将现场千变万化的座位排布展示出来的呢?下面我们带着疑问来看看麦座的解决方案。


1. 绘座


  • Svg 导入、校验;

  • 编辑场馆信息:可对舞台、楼层、看台、区域和场馆入口等进行设置;

  • 添加座位:主要针对座位的物理属性进行设置,包含但不限于座位类型、所在区域、楼层信息、排数、列数、排序规则;

  • 块级座位变形:间距调整,可通过座位 x,y 轴的数值进行调整;

  • 旋转:将所选座位集合设置成为一个临时块,将其作为矩形矩阵。向上取整,获取离矩阵中心最近的座位,将其设做圆心,其他座位以圆心座位进行 rotate 旋转;


  • 错位:根据角度进行奇偶排位移错位;


  • 倾斜:将所选座位集合设置成为一个临时块,将其作为矩形矩阵。第一排不改变位移,从第二排开始,每一排根据上一排进行等比例位移;


  • 弧形:

  • 应用贝塞尔曲线:贝塞尔曲线是用一系列点来控制曲线状态的,我将这些点简单分为两类:数据点、控制点。通过调整控制点,贝塞尔曲线形状会发生变化;

  • 中弧算法:二阶曲线:



  • 左/右弧算法:三阶曲线:




2. 选座


  • 票房规划:规划票档、保留票、套票和打印座位图;


  • 锁票:根据业务场景可分为单场次锁票和跨场次锁票,跨场次锁票可支持在相同场馆的不同场次内进行锁票;

  • 门店销售:彩虹图、高级筛选、购物车和下单;


三、效率提升(按区域加载方案)

麦座的选座场景在两万以上座位量的大型体育赛事上,座位图页面加载缓慢、操作座位时出现卡顿等情况。


实现座位按区域加载,使用户在拖拽、缩放的同时惰性加载所需要展示区域内的座位,加快首屏渲染时间,在用户无感知的情况下加载其余区域的座位。解决因数据量庞大引起的页面加载缓慢、卡顿等体验问题。


技术实现(以规划票房场景为例):


1)展示当前浏览器窗口内所有看台/区域的座位按区域加载。


看台内座位的关键技术是获取到当前浏览器窗口内所展示出来的看台/区域。那么如何来做呢?首先我们设定一个矩形区域,同步浏览器视窗的范围,然后可以通过 getBBox()获取矩形区域内部的看台元素,最后遍历看台区域并与矩形区域进行对比,可以根据业务需要来设定重叠多少面积触发加载内部座位的逻辑。


2)预加载浏览器窗口附近的看台/区域的座位,保证在用户移动底图时可以更快速地浏览视窗以外的其他座位。


预加载的初衷是减少异步加载的耗时,提高用户体验。这里的预加载并非 applicationCache,而是一种巧妙的提前加载方案:如之前说过的如何实现获取浏览器视窗内的所有看台区域,在这个基础上我们可以在对比的过程中将实际的 SVG 面板缩小一定的比例,比如 80%,那么得到的看台区域和视窗矩形重叠的部分会增加,更会有实际视窗外的看台被视作与矩形有重叠,就是这样我们可以提前拿到视窗外且遍布在视窗周边的看台区域,把这些区域提前加载出来从而实现预加载。


3)以座位维度单点绘制座位。


早期麦座座位图场景绘制座位的维度是看台,也就是从服务端获取的数据是看台集合,而看台到座位需要遍历看台、区域、块、排。在浏览器渲染座位之前,做了很多数据包装的工作,而且操作的数据量是很庞大的,性能与绘制效率均受到了不同程度的影响。


升级前(全量加载)升级后(按区域加载)
可支持座位量小于 3 万可支持 10 万
首屏渲染时间10 秒以上2 秒以内
组件化技术组件封装,降低业务耦合度,降低开发、维护成本
数据结构各场景不一致统一座位、商品模型,统一各场景数据结构
CPU 性能峰值 145.9峰值 69.1
接口响应时长10 秒以上2 秒以内
6 万座位渲染总时长几十秒3 秒以内

四、架构设计

业界普遍采取的技术实现方案有三种:Dom 渲染、Svg 渲染和 Svg+Canvas 渲染。基本的架构设计思路如下:



本文解决方案采用 Grid 思路:将座位坐标进行按照一定范围,比如 2000(经测算这个范围 2000*2000 比较合适)进行网化,也就是将元素坐标在 0 到 2000 的放到一个网格、2001 到 4000 的放到一个网格,以此类推。


五、性能提升

1. 座位图快照


  • 目的:提高页面加载速度;

  • 产物:利用 canvas 快照能力,将非焦点区域的座位图以图片的形势展示出来,减少不必要的 canvas 渲染。


2. 全场景数据打通


  • 目的:加载与渲染速度提升;

  • 产物:画座、票房规划、单场次/跨场次锁座、门店销售、打印座位图打通获取场次、票档信息、座位数据的结构,座位由原来的看台维度的加载变化成座位单点加载,规避了大量的深层 map 结构解析与数据包装。


3. 局部异步渲染


  • 目的:降低引起重绘的 cpu 使用率;

  • 产物:设置票档、保留票、套票、高亮等操作,将所选中的座位设置成临时方形矩阵,重绘矩阵内部的座位。


4. Canvas 拆分


  • 目的:减少页面加载渲染卡顿;

  • 产物: Canvas 宽高大于一定数值(经过测试这个数值在大多数浏览器下是 5000)时,就会出现卡顿问题,demo 之所以不会比较流畅,是因为模拟的十万座位数据比较密集, Canvas 没有设置到那么大,将多个小的 Canvas 拼接,然后再绘制座位,按照座位坐标确定座位该绘制到具体的 Canvas 上。


5. 组件化沉淀


  • 目的:提高多处相似能力的可复用性,降低技术成本。低耦合,高维护性;

  • 产物:鹰眼图组件、座位变形组件、票房规划相关组件、创建座位组件等等。

六、辅助工具

1)圈选:通过鼠标右键圈选自定义矩形块,选中矩形块内的座位集合;


2)套索:类似于 Photoshop 套索工具,可以通过打点完成不规则图形的圈选,选中多边形区域内的座位集合;


3)增量选座:增量添加已选座位,可以通过不同的选座工具做增量添加;


4)Svg 校验:团队内部根据一套完善的 Svg 规范定义,对新绘制的 Svg 进行校验,目的是过滤掉一些不符合规范的 Svg 底图,避免到线上出现比例有误影响缩放效果和底图显示出现问题的情况,同时避免出现因为 Svg 底图的问题导致已生产完毕的场次重新生产的情况;


5)标尺。


辅助绘座对其排、列的标尺工具,可随意切换颜色。


七、新领域:“全景、3D”思路与初探

现有的一些技术资源介绍:


1)ThreeJs:被称作 3D 大哥的 threejs 封装了 webgl 很多核心方法,通过做三个核心“场景(scene)”、“相机(camera)”和“渲染器(renderer)”完成 3D 效果,需要自己造轮子、自己搬砖,看案例性能上需要做很多优化工作,坑也需要自己一点点去踩;


2)Aframe:入手相对容易,还可以支持 VR 模式观看,但比较鸡肋,不支持放大缩小,移动端视角不支持移动;


3)jQuery-VRview:开源插件很多,但功能大多都未必不合适我们要的场景,需要探索一下资源库碰碰运气;


4)Pannellum:国外的一个插件,图片宽度最大限制 4086,图片放大后有失真、像素感严重的情况,尤其是移动端;


5)Krpano:但是据说很好用,市面上很多全景 VR 公司用的都是这个。缺点是本地生产,如果需要上传,有 linux 版本,可能需要 java 帮助,是收费的。


3D 全景展示目标看台的视角/视野效果:图片资源要求比较严格,可能需要专业的设备和“摄影师”,具体是受 webgl 规范影响,图片的宽度有要求,所以涉及到图片的裁减与拼接,图片质量直接影响分辨率和抗锯齿程度。


用户视角:鼠标悬浮展示当前看台的视觉效果,主要是图片展示给用户一个直观感受,类似于国外网站 seatsMaster 的效果。


作者介绍


阿里文娱高级前端工程师 弋辰


相关阅读


电影垂直行业的云智开放平台如何炼成?


阿里工程师带你了解 B 端垂类营销中心如何设计?


云智前端技术如何赋能场馆院线?


60 秒售出 5 万张票!电影节抢票技术揭秘


电影行业提升 DCP 传输效率,还能这样做!


2020-03-20 10:002725

评论 1 条评论

发布
用户头像
弋辰牛逼
2020-03-27 14:15
回复
没有更多了
发现更多内容

一道React面试题把我整懵了

beifeng1996

React

vue项目性能优化-前端加分项

bb_xiaxia1998

Vue

软件测试 | 测试开发 | Pb协议的接口测试

测吧(北京)科技有限公司

测试

Java进阶(三十七)java 自动装箱与拆箱

No Silver Bullet

Java 9月月更 自动装箱 拆箱

P5~P9应该具备的核心能力是什么

博文视点Broadview

源码学习之MyBatis的底层查询原理

京东科技开发者

Java sql 源码 mybatis mybatis源码

SBOM:缓解软件供应链风险的关键

SEAL安全

DevSecOps 软件供应链 SBOM 软件供应链安全

面试官让你说说react状态管理?

beifeng1996

React

禅道项目管理软件App使用

禅道项目管理

项目管理 App 禅道

keep move!滑动窗口中位数与滑动魔方

掘金安东尼

算法 9月月更

西安前端培训班学习哪家比较好

小谷哥

从URL输入到页面展现到底发生什么?

loveX001

JavaScript

面向对象设计原则,历久弥新

有态度的马甲

国庆节,零代码帮你搞定假期美食菜单,体验赢定制好礼

华为云开发者联盟

人工智能 企业号九月金秋榜

软件测试 | 测试开发 | Python 自动化测试(三): pytest 参数化测试用例构建

测吧(北京)科技有限公司

测试

new Vue的时候到底做了什么

bb_xiaxia1998

Vue

UI 自动化测试应不应该投入?有没有前途?怎样做最明智?

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | UI 自动化测试实战(二)| 测试数据的数据驱动

测吧(北京)科技有限公司

测试

Python 测试开发实战进阶,技能对标阿里 P6+,挑战年薪 50W+!

测吧(北京)科技有限公司

测试

Ohos-MPChart——支持多种图表绘制的组件

OpenHarmony开发者

OpenHarmony

软件测试 | 测试开发 | Junit5 架构、新特性及基本使用(常用注解与套件执行)

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | Jenkins 踩坑 | job 创建、参数化、定时构建及时区偏差问题解决

测吧(北京)科技有限公司

测试

小程序化:系统集成行业降本增效的破局思考

FinClip

sentinel-dashboard-apollo 1.8.5 发布,支持 apollo 持久化的定制版

铁匠

orbeon form 通过 url 的方式同第三方应用集成的开发明细

汪子熙

Java SAP commerce form 9月月更

仅需30行代码,轻松集成HMS Core视频编辑服务屏幕录制能力

HarmonyOS SDK

编辑 视频

一键实现设备高稳定高安全管理——设备管理运维类

阿里云AIoT

分布式数据库 安全 监控 物联网 存储

软件测试 | 测试开发 | Python 自动化测试(四):数据驱动

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | PageObject(PO)设计模式在 UI 自动化中的实践总结(以 QQ 邮箱登陆为例)

测吧(北京)科技有限公司

测试

【开发者说】携住数智酒店,用原子化服务创造全新入住体验

HarmonyOS开发者

HarmonyOS

互联网进入存量博弈时代,小程序技术创造移动应用新机遇

FinClip

finclip

超大型场馆的绘座选座解决方案_文化 & 方法_阿里巴巴文娱技术_InfoQ精选文章