在七牛云校園黑客馬拉松中,一款設計優秀、邏輯清晰的白板作品脫穎而出,獲得第二名的好成績,這就是來自鄭州大學Since團隊的White Rose白板,以下是他們的設計和架構分享,

一、前言
White Rose是參加七牛云hackathon比賽的作品,賽題的主要內容是開發一個「多人協作白板」,旨在鼓勵在校大學生用編程創造價值,
賽題核心需求包含三個:
- 多人可以加入一個房間,同時進行繪畫(盡可能多的形狀隨意繪制)
- 所有操作可以撤銷和恢復
- 可以創建不同頁面,支持只讀模式(頁面鎖定后,所有人不可編輯)
二、產品設計
(1)愿景
基于hackathon的比賽要求,我調研了一些白板軟體,這些軟體不乏有一些「操作困難」「功能繁雜」等問題,所以,我定下一個產品愿景:「做一款從兩歲到八十歲都能用的白板」
(2)追求
基于以上愿景我也設立了幾條產品追求:「功能一鍵即達」「界面極致簡潔」「內容高度自由」
作為喬布斯的粉絲,印象中喬布斯當年設計iphone時,要求工程師所有的功能操作不能超過3步,而對于白板一個單獨的軟體來說「進入」一步,「功能選擇」一步,所以留給我的只有一步了,
(3)界面
為了讓界面足夠簡潔,我將所有「擴展」功能全部放到了「上下左右」四個隱藏選單里,從而讓整個頁面除了四個「必要資料」外,就只有一塊“純粹的白板”,
- 對于兩歲的小朋友來說進入就可以直接隨意的涂鴉,
- 對于八十歲老教授來說,這用起來跟教室的黑板一樣,
下面分別是整體的界面效果,

無論多大的螢屏,什么形狀的螢屏,都會無失真的自動擴張,因為它本質是一個高寬100%的矢量圖,
因為不同螢屏的大小限制,這樣的設計可能回導致小螢屏的人看到的內容沒有大螢屏的「完整」,
對于有些軟體的處理可能會有利用「拖拽頁面」功能來確保每個人所能接收到的資料一致,這將意味著,用戶的每次觸屏操作,軟體都要區分用戶是想「拖拽頁面」還是想「繪畫」,而用戶也需要在兩個功能間頻繁切換,
而我的理解:“白板”本質是一個大號的草稿紙,當我們給一群人講一些內容的時候,「演講者」可能隨手會在白板上寫下他講的關鍵詞「power point」,一般作為「演講者」會寫在一個大家都能看到的地方,這對「演講者」不會增加太大負擔,而對于「聽眾」一邊聽內容,還要一邊還要拖拽頁面去確認演講者寫在那里,這個負擔更大,
回想一下我們在教室上課的時候,老師會盡量把內容寫在中間靠上的位置,而不是底部,因為前排同學會擋到內容,
所以我摒棄了「拖拽頁面」的功能,
當然「縮放」也不乏是另外一種解決方案,但是也會徒增操作者(縮放)的使用負擔,并且還會引入另外一個問題就是「失真」,
關于顏色:
其實在選擇白板的底色的時候,可能就是一個白色,但是其實白色也是五彩斑斕的,該用什么呢?
我想到一個詞「青紅皂白」,索性我就用「青紅」和「皂白」調制了一個對眼睛更加柔和的 「青紅皂白色」作為白板的底色,
(4)拓展功能
設計好了整個頁面,接下來就是功能設計,我在設計界面的時候,預留了4個隱藏選單欄來放拓展白板功能,為了讓所有功能「一鍵即達」,并且更簡單的使用,我采用了icon + 文字描述的方式,讓用戶更易理解,
整體展開如下圖所示:

為什么是這樣的擺放呢?
1、功能分類
根據賽題要求的功能,我將所有功能分為了四類,
- 形狀拓展:用戶可以選擇圓、長方形、菱形、三角形、直線等形狀,
- 顏色拓展:用戶可以修改所有形狀軌跡的顏色,
- 大小拓展:圖形的大小和線條的粗細可以切換,
- 頁面拓展:頁面可以添加洗掉和切換,另外頁面的內容支持撤銷和恢復,
2、何處安放
我在想這個問題的時候,想象了在一張紙上作畫的場景,
- 一般我們習慣在桌子右側放上各式各樣的水彩筆,方便我們切換顏色,所以我將「顏色拓展」放在了右側,
- 我們習慣在桌子的上方和左側放尺子、圓規之類的用來拓展圖形和豐富繪畫形狀的工具,所以我將「形狀拓展」「大小拓展」放在了左側和上側,
- 當我們要做翻書、撕頁等頁面操作時,一般會從右下角開始,所以我將所有的「頁面拓展」放置到了下側,同時右下角有一個對應頁面的頁碼,也因為大多數書的頁碼在這個位置,
(5)自由布局
上面講到,我根據我個人的想法將各個功能進行了分類,并且按照我所理解的「更方便的布局」進行了排放,但在實際操作程序可能并不符合一些其他用戶的操作習慣,比如:左撇子,
因此我將每個功能做了集成,并且可以隨意的改變不同功能所在的位置,也就是所有的功能布局,用戶可以根據自己的想法進行布局上的DIY,
三、架構設計
因為本次開發的周期只有21天,另外作業日的白天還需要上班,非常緊迫,所以需要采用非常簡單且高效的架構設計,當然也需要考慮一些后續擴展的可能,
(1)整體架構
為了更好的「持續集成」我們采用自建的gitlab管理代理,并使用gitlab-runner完成自動化部署,
整體架構圖如下圖所示:

(2)互動模型
對于后端來說,為了更加高效的溝通,我將整個互動模型,定義為一個群聊,群內所有人的訊息統一發給服務端,然后服務端再統一轉發給其他人,
后端只需要確認三點:1.誰發的訊息,2.發到那個群里的,3.訊息型別,
整體互動結構如下:
{
"type": 1234, // 操作型別
"fromId": 123, // 發送人id
"roomId": 1234,// 所在房間
"time": 152150025421564 //時間戳,前端不需要發送
"data": {} // 操作內容
}
這樣做的兩個好處:
- 所有訊息有一個統一的時序(即服務端時間)
- 后端完全無需關注「data」的具體內容,只根據type區分「接收」「分發」「存盤」操作,
(3)data模型
data模型主要是前端所發送的和接收到的message里的data結構,
data里面該放什么?我將用戶的所有操作定義為option,將用戶的所有option放到data里面完成用戶操作的轉發,option的結構如下:
interface Op {
type: number // 頁面操作or圖形操作
graph?: {
op: number // 添加、旋轉、縮放、平移
type?: string // 圖形類別
key?: string // 圖形所對應的key
page?: number // 圖形所對應的頁面
content?: any // 圖形內容
}
page?: {
op: number //添加、洗掉、切換頁面
key?: number // 頁面對應的key
content?: any // 頁面對應的內容
}
}
這樣的每個option,我們都會存放到操作堆疊里面,結合另外一個快取堆疊,即可實作撤銷和恢復,
(4)多人協同
對于多人的操作,其實是多個人對多個圖形的操作,人與當前所操作的圖形是一一對應的,
所以我通過一個令牌集的概念,來存放「所有的用戶id」,以及每個用戶當前「所操作的圖形id」,這樣就確定下來個每個用戶正在操作什么,
不同用戶的操作通過以下流程完成:
- 操作者設定當前所操作圖形的id,并更新令牌集,
- 接收者同步更新令牌集,
- 操作者發送操作資料(option),
- 接收者根據用戶資訊從令牌集中確定所操作的圖形,再根據option修改具體的svg資料,
整體白板從產品的設計到架構的設計就結束了,
歡迎體驗:http://whiterose.cf.since88.cn
前端代碼:https://lab.since88.cn/whiterose/frontend
后端代碼:https://lab.since88.cn/whiteros
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/540317.html
標籤:其他
上一篇:JS中的相等性判斷
