摘要:那麼新繪座的目標就變得很明確了,我們就是要在 Canvas 上繪製出想要的場館座位圖,然後以 SVG 的格式把圖形保存起來,用以選座、售票。新繪座系統的撤回功能實現原理:設計一個“歷史數據”數組,數組裏的每個元素,記錄一個操作步驟對應的被編輯座位數據以及座位位置信息,回退時,找到對應操作步驟的數組元素,重繪座位位置,這樣就回退了整個操作。

一、背景

  1. 網絡售票需要畫座:購票所見即所得

大麥主要業務是票務,包括演唱會、體育賽事、音樂節等,品類繁多。賣票就要畫場館、畫座位,大家都在網上買過電影票,這不難理解。雖然可以拿電影售票做類比,但底層難度差異很大。沒有 10W 座的電影院,卻有 10W 座的演唱會,而且演出 / 體育類場館變化多,座位不固定,場景非常複雜,想隨心所欲畫出 10W 座的場館,挑戰相當大。

  1. 大麥繪座演進:從示意圖到實際場景圖

大麥以前的繪座系統,是安裝版的程序,畫座位只能一個看臺一個看臺的畫,看臺之間完全無關聯,畫出來幾乎每個看臺都長一個模樣,座位只有相對位置的示意圖,沒有角度、距離,更談不上精確定位。

圖 1:老版繪座頁面(已淘汰)

大麥網從 2017 年,開始設計新版繪座系統。這裏沒有修補,沒有重構,新版繪座完全重來,連技術棧也由.NET 換成了 Java,由 C/S 換成了 B/S。

新繪座以 SVG 矢量圖爲核心,通過 Canvas 進行繪製,在演進的過程中攻克了大量的性能卡點和技術難點,最終打造成型,堪以重任。

圖 2:新繪座頁面

圖 3:座位效果圖

二、新繪座:Flash 走了,Canvas 來了

  1. Flash 已死,來到路口,別無選擇

新繪座已誕生 2 年多,現在回首,這條路似乎早已註定。

老版繪座和選座是基於 Flash 的,悲劇的是,Adobe 宣稱 Flash 2020 年後,將不再維護,相關技術會在 2020 年底全部退役,大麥的繪座和選座系統,都被迫轉型。

Flash 只是原因之一,看過競爭對手的產品,會發現 SVG 是條不錯的道路,即使沒有 Flash 這一出,大麥網也會朝這個方向邁進。

  1. 技術選型

1)任何過度使用 DOM 的應用,都不會快經過技術調研,發現國外一些場館座位繪製,選用的是 SVG 方案,每個座位都是一個獨立

的 SVG 元素。但如果直接把 SVG 搬到瀏覽器,無法支持幾萬座位的場館,因爲瀏覽器無法支持過多的 DOM 數量,並且,一旦 DOM 數量太多,操作一定是低效的,“任何過度使用 DOM 的應用,都不會太快”。

於是,技術同學想到了 Canvas,Canvas 是瀏覽器上的一個畫布,無論上面繪製多少元素,對於瀏覽器而言,都只是一個 DOM 元素。

對於不瞭解 Canvas 的同學,我們可以簡單做個說明,Canvas 在瀏覽器上,就是下面一個標籤:

複製代碼

<canvas id="myCanvas"width="200"height="100"style="border:1px solid #000000;">
</canvas>

在 Canvas 上繪圖,就是使用 JS 獲取 Canvas 對象,使用封裝好的方法進行繪製。Canvas 畫布上的圖形變化,完全通過擦除 + 重繪的方式展現。

那麼新繪座的目標就變得很明確了,我們就是要在 Canvas 上繪製出想要的場館座位圖,然後以 SVG 的格式把圖形保存起來,用以選座、售票。

2)Canvas 也不是銀彈:單個 Canvas 的大小是有限制的,超限之後也會卡頓

選型初期,技術同學使用 Canvas+SVG 做了個 Demo,模擬了 10W 座位的渲染,並實現了拖拽、縮放。但真正作爲畫座組件開發的時候,發現座位達到 2W 就出現了卡頓,因爲 Canvas 的寬高達到一定的數值,就會出現卡頓。於是,沿着化整爲零的思路,技術同學將整個畫布,分成了多份 Canvas,形成了一個 Canvas 矩陣,通過對每個 Canvas 的操作,完美解決了單個 Canvas 過大引起卡頓的問題。

關於 Canvas 繪圖組件,大家可以在網上搜到很多資料,這裏不再贅述。

  1. 新版繪座上線初期:青蘋果

剛上線的新版繪座,就像個青澀的蘋果,雖然漂亮,卻沒那麼好喫。

最突出的問題有 2 個:第 1 個是變形難用,由於算法比較初級,座位矩陣變形很難滿足用戶需求;第 2 個是接口速度慢,打開一個 1W 座的場館,好幾分鐘,超過 5W,直接崩潰,根本無法支持。

爲什麼理想很豐滿,結果卻差強人意呢?根源在於第一版只重功能,忽略了算法效率。與服務端的接口調用,都是整個場館級別的,幾萬座位數據,加上關聯的看臺、票、以及狀態等,一個碩大的數據包在前後端丟來丟去,系統不堪重負,用戶受盡折磨。

  1. 艱苦改進之旅

新繪座上線後,立刻啓動了改進優化工程,主要攻克的難關有三點:頁面響應時間;座位自由組合變形;打印順序計算。

1)交互 + 接口優化,進入秒開時代

首先要解決接口慢的問題,解決效率低的一大法寶:化整爲零。

從一次 load 一個場館的數據,改成一次 load 幾個看臺的數據。服務端數據隨着前端視口(頁面可視範圍)的變化,逐漸加載,類似地圖常用的“拉框查詢”。前端交互也從全加載,改爲按視口取數據。僅此一項優化,幾萬座大場館的系統響應速度,立刻由幾分鐘,降到了 1~2s,小場館更是瞬時打開,系統好用了不少。

這裏面最重要的一個技術點,就是視口計算,原理如下:

前端首先獲取到屏幕視口在 Canvas 畫布上的座標,然後和看臺的外接矩形進行碰撞檢測,兩個矩形一旦相交,就說明該看臺已暴露在視口之內,於是就加載該看臺的數據。

從接口優化開始,新繪座逐漸走向成熟。

圖 4:按視口加載原理圖

2)合併座位矩陣,自由變形座位自由變形包括傾斜、錯位、排距、座距、旋轉、弧度等多種操作。除了弧度變形,其它基本上是一些數學上的座標計算,我們不贅述,這裏重點說一下弧度變形。

新弧度變形,運用貝塞爾二階曲線原理,根據用戶的數據輸入,計算出相應的貝塞爾曲線,再把每排座位,均勻排列到曲線上。下面是貝塞爾二階公式:

圖 5:貝塞爾曲線示意圖

註釋:P0、P2 爲一排座位的左右端點(一排的第一個座位和最後一個座位)

看似套公式就可以搞定,非常簡單的樣子。但是這裏有一個難點:從圖中可以看出,t 爲比例值,處在線段 P0P2 不同的比例,所在的弧度位置也是不一樣的。

如果所有的座位都在 P0P2 線段上,很好算,但是如果座位之前就是一條弧線呢?中間所有的座位都不在 P0P2 線段上,要怎麼算出中間座位的每個比例?

我們通過弧線上的每個座位,做一條 P0P2 線段的垂線,垂線與線段 P0P2 的交點,就是這些座位所在這一排的原始位置,計算出這些原始位置的座標,根據這些原始位置,就可以算出中間所有座位的比例了。

這樣,弧度變形問題就通過貝塞爾二階曲線完美解決。

圖 6:弧形座位矩陣貝塞爾曲線變形原理圖

圖 7:弧度變形實際操作

圖 8:座位自由組合,隨意變形

3)打印順序計算

“打印順序”是個什麼鬼?

這得從大麥的業務特點說起,主辦有時候會批量出票並將票配發給相關人羣,有時整個看臺一起打印。在配票的時候,需要按照座位的物理位置關係排序,避免座位沒挨着、“2 個情侶”被“拆散”的情況發生。舉個例子:下圖中,主辦期望打印票的順序是“5-3-1-2-4-6”,而不是“1-2-3-4-5-6”,這樣他們就可以按打印順序配票,而不用擔心兩張票不挨着。那麼,在繪座過程中,我們就要計算出座位的順序,看似簡單,實現起來有難度很大,原因只有一個,場館形狀各異,座位排列多樣。

圖 9:北京奧體中心的某個看臺

如果說,上圖還能按照座位 Y 座標對比進行排序,那麼下面的幾個情形,就不那麼好處理了:

圖 10:各種特殊的座位排列場景

打印問題,我們通過場景彙總,對場館進行分區,最終找到了排序的規律,得以解決。打印問題技術方案原理:

第 1 步:將場館分成 8 個象限,象限內的座位,已標識出該如何排序(標識出了應該對比 X 座標還是 Y 座標來進行排序);

第 2 步:每一組座位矩陣,取出首排,求首尾座位連線的斜率,然後根據斜率將座位矩陣劃分到對應象限;

第 3 步:按照對應象限的排序標識,對比座位的 X 座標(或 Y 座標),進行座位排序。

圖 11:座位排序原理圖

4)小彩蛋之“沙發、角度”

效率、變形和打印 3 個主要問題根解之後,隨之出現了大量的產品優化需求,開始着眼於細微之處,小沙發和座位角度就是 2 個典型的功能。這兩個功能雖然難度不大,但卻在體驗上有了一大步的提升。

圖 12:圓點、沙發效果對比

5)小彩蛋之“撤回”

經過不斷優化和添磚加瓦,大麥的繪座系統,越來越像一款專業的繪圖工具。好的繪圖工具一定需要“前進 & 撤回”功能。

新繪座系統的撤回功能實現原理:設計一個“歷史數據”數組,數組裏的每個元素,記錄一個操作步驟對應的被編輯座位數據以及座位位置信息,回退時,找到對應操作步驟的數組元素,重繪座位位置,這樣就回退了整個操作。因爲無論座位相對位置如何變形,本質上,其實都是座標數據的改變,通過記錄和重繪歷史座標信息,就達到了撤回操作的目的。

三、在正確的路上繼續前行

到目前爲止,新繪座系統已能夠承接國內外任何大型場館的繪座工程,各種細節的優化也日臻完善,效率大幅提升。但產品和技術同學的努力,並沒有終止,而是在正確的道路上,繼續前行。

以下簡單列舉幾個很實用的功能,供大家參考:

  1. 區域編輯

自由繪製矩形、圓形、多邊形等各種形狀,並自由變形;

  1. 一鍵自動變形

全選看臺內的座位,點擊“一鍵變形按鈕”,座位瞬間適應看臺形狀,自動排列;

圖 13:一鍵變形效果圖
  1. 座位複製、鏡像

區用戶可以自由複製選中座位,並且支持鏡像、翻轉等多種複製模式,排號、座位號根據設置自動處理;

  1. 一鍵朝向舞臺

用戶選中一個看臺的數據,點擊“一鍵朝向舞臺”,系統會自動計算舞臺方向和座位角度,瞬間將整個看臺座位“擺正”。

作者簡介:

阿里文娛技術專家 莫那、阿里文娛高級工程師 土嚎

相關文章