阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

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

  • 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:002047

评论 1 条评论

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

图解Node(上)——直击灵魂的十条拷问

执鸢者

大前端 原理 Node

程序的机器级表示-控制

引花眠

计算机基础

linux入门系列17--邮件系统之Postfix和Dovecot

黑马腾云

Linux centos Dovecot Postfix 邮件系统

linux入门系列18--Web服务之Apache服务1

黑马腾云

Linux centos apche linux运营 centos网站部署

打通微信和钉钉服务是一种怎样的体验?

Ceelog

微信 钉钉 微信公众号 Go 语言

JVM的早期优化与晚期优化

Edison

JVM JVM虚拟机原理

Android | dagger细枝篇

哈利迪

android

架构师第十二周作业

傻傻的帅

ARTS Week14

时之虫

ARTS 打卡计划

更新丢失、写偏、幻读:数据库事务从快照隔离到可序列化

青菜年糕汤

数据库 数据库事务 分布式数据库 数据库设计 分布式系统

巧用HashMap一行代码统计单词出现次数

程序那些事

jdk hashmap 统计字数

SpringBoot+Tess4j实现牛逼的OCR识别工具

小隐乐乐

linux入门系列18--Web服务之Apache服务2

黑马腾云

Apache Linux centos linux运维

你真的懂 Java 的 main 方法吗

Rayjun

Java

ARTS打卡 第14周

引花眠

微服务 ARTS 打卡计划

架构师第十二周学习总结

傻傻的帅

基于区块链的社会治理探索

CECBC

区块链 大数据 信息技术

linux入门系列19--数据库管理系统(DBMS)之MariaDB

黑马腾云

MySQL Linux centos linux运维 MariaDB

二叉树深度和大文件排序

escray

学习 面试

Go: ElasticSearch客户端学习

陈思敏捷

elasticsearch elastic go-elasticsearch Go 语言

央行数字货币钱包上线后又秒关 兑换了的 DCEP 别担心

CECBC

数字货币 央行

ARTS Week9

丽子

ARTS 打卡计划

什么是分散式金融(DeFi)?

志学Python

去中心化金融 defi

Flink-有状态算子的扩缩容-12

小知识点

scala 大数据 flink

linux入门系列20--Web服务之LNMP架构实战

黑马腾云

php MySQL Linux centos ngnix

比特币挖矿到底挖的是什么?

CECBC

比特币 区块链 数字货币

【持续更新~】常遗忘却可以变更好的心态

01Running

个人成长

视频AI第一步-动作识别数据集

flow

Python作业留底--《菜鸟教程》Python 练习和习题

Geek_f6bfca

oeasy教您玩转linux010108到底哪个which

o

搬家,又一次和过往告别

王磊

程序人生

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