用 Canvas 繪制飛線

2016-05-12

用 Canvas 繪制飛線

背景

上一周完成了地圖與飛線的實現(xiàn),使用的是 d3.js + svg榜晦,后發(fā)現(xiàn)可能存在性能隱患冠蒋。

當飛線數(shù)量多的時候,頁面上則有多個 svg <path> 結點乾胶,并且每條飛線有頭部抖剿、結束圓圈朽寞、蒙板等效果,則頁面上的結點數(shù)是 飛線數(shù)*其他部件數(shù)斩郎。將會是一個較大的值脑融。

Canvas 飛線動畫

動畫飛線

畫布罩在整個 HTML 上,共兩層 Canvas 畫布缩宜,底層繪制世界地圖肘迎,表層繪制飛線。

layer

與 SVG 飛線 對比

  • SVG 飛線:
    1. 一條飛線是一個 SVG <path> 結點锻煌;
    2. 使用 d3.js 中 .transition() 下的子方法 .attrTween()妓布,對于中間幀每一個狀態(tài),改變其 <path> 結點里的 d 屬性宋梧;
  • Canvas 飛線:
    1. 底下的地圖繪制在一張畫布中匣沼,而飛線繪制在另一張畫布中;
    2. 每一幀都重新清除掉飛線畫布捂龄,重新繪制每一條飛線肛著;

兩者共同點:

  1. 通過不斷計算飛線 p 點(起、終點之間的任一點)的位置跺讯,一次次繪制從起點到 p 的二次貝塞爾曲線枢贿;
  2. 飛線的起點不變,p 點坐標不斷改變

二次貝塞爾曲線公式

二次貝塞爾曲線公式

(其中 起始點 p0, 控制點 p1, 終點 p2)

t 從 0 變到 1刀脏,每個 t 的變化時局荚,就繪制一幀;
飛線的速度就取決于增量變化的大小愈污,增量越小耀态,動畫就越細致。

如何表現(xiàn) t 暂雹?
給每一個飛線對象單獨一個 t 屬性首装,每繪制完一幀,t = t + 增量(固定值)杭跪;

requestAnimationFrame 動畫

飛線取數(shù)設計

  • 總數(shù)據(jù)池: -不斷輪詢服務端仙逻,增加要繪制飛線的數(shù)據(jù);
  • 飛線數(shù)據(jù): 存放的是每一幀要繪制在頁面上的飛線涧尿。 只要有值系奉,就用 requestAnimationFrame 不斷調用動畫;

飛線樣式

與 SVG 飛線 相比:

  • SVG 飛線:

    • 使用蒙板跟隨飛線尾部的方式
  • Canvas 飛線

    • 使用漸變填充色姑廉,對每一條飛線缺亮,都重新生成該飛線起點到 p 點的線性漸變;
漸變色

漸變消失: ctx.globalAlpha

另一種飛線動畫的實現(xiàn)方式

使用 globalAlpha 和 臨時 Canvas桥言;

但有兩個弊端:

  1. 無法做停留:飛線飛完之后萌踱,想停留個幾毫秒再消失
  2. 尾巴長度難控制葵礼,太長的話有明顯的間隔。

飛線性能測試

一并鸵、同等情況下章咧,svg 飛線與 canvas飛線的性能比較。

模擬數(shù)據(jù)來源于B2B 外貿(mào)單日詢盤量能真,總數(shù)共 596 條赁严, 單次同時繪制 50 條 飛線情況下:

動畫幀數(shù) fps cpu 占用率 JS Heap 內(nèi)存情況 說明
svg 12 fps ~ 43 fps 高于 100% 11 mb 左右 視覺上仔細看略有卡頓
canvas 42 fps ~ 60 fps 20% ~ 30% 浮動 9.3 mb 左右 動畫流暢

具體如下:

1. 動畫幀數(shù)

Canvas

動畫幀數(shù)保持在 42-60 左右,動畫流暢粉铐;

fps-canvas

fps-chrome-canvas

SVG

動畫幀數(shù)保持在 12-43 左右疼约,視覺上仔細看略有卡頓;

fps-svg

fps-chrome-svg

2. CPU 占用率

Canvas

CPU 占用率在 20%-30% 浮動

cpu-canvas

SVG

CPU 占用率高于 100%

cpu-svg

3. JS Heap 快照

皆無內(nèi)存泄漏問題蝙泼。 SVG 飛線的 JS heap 總大小略高于 Canvas 飛線程剥。

Canvas

js heap

SVG

js heap

二、Canvas飛線峰值測試

canvas飛線峰值測試

測試了 Canvas 飛線汤踏,在同時繪 50 條织鲸、100 條、200 條溪胶、300 條搂擦、400 條 時的動畫流暢度。

峰值幀數(shù)
  • 在50-100 時候動畫流暢
  • 200 時哗脖, fps 低瀑踢,視覺上勉強可接受
  • 300 時,有卡頓才避,有明顯漏幀行為橱夭;
  • 400 時,卡頓非常嚴重桑逝,幾乎無法完整看到飛線動畫

參考資料:

  1. HTML 5 Canvas 參考手冊
  2. stackoverflow: I want to do animation of an object along a particular path
  3. paulirish:requestAnimationFrame for Smart Animating
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末棘劣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子楞遏,更是在濱河造成了極大的恐慌茬暇,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件橱健,死亡現(xiàn)場離奇詭異而钞,居然都是意外死亡,警方通過查閱死者的電腦和手機拘荡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撬陵,“玉大人珊皿,你說我怎么就攤上這事网缝。” “怎么了蟋定?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵粉臊,是天一觀的道長。 經(jīng)常有香客問我驶兜,道長扼仲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任抄淑,我火速辦了婚禮屠凶,結果婚禮上,老公的妹妹穿的比我還像新娘肆资。我一直安慰自己矗愧,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布郑原。 她就那樣靜靜地躺著唉韭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪犯犁。 梳的紋絲不亂的頭發(fā)上属愤,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音酸役,去河邊找鬼春塌。 笑死,一個胖子當著我的面吹牛簇捍,可吹牛的內(nèi)容都是我干的只壳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼暑塑,長吁一口氣:“原來是場噩夢啊……” “哼吼句!你這毒婦竟也來了?” 一聲冷哼從身側響起事格,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤惕艳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后驹愚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體远搪,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年逢捺,在試婚紗的時候發(fā)現(xiàn)自己被綠了谁鳍。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖倘潜,靈堂內(nèi)的尸體忽然破棺而出绷柒,到底是詐尸還是另有隱情,我是刑警寧澤涮因,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布废睦,位于F島的核電站,受9級特大地震影響养泡,放射性物質發(fā)生泄漏嗜湃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一澜掩、第九天 我趴在偏房一處隱蔽的房頂上張望购披。 院中可真熱鬧,春花似錦输硝、人聲如沸今瀑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽橘荠。三九已至,卻和暖如春郎逃,著一層夾襖步出監(jiān)牢的瞬間哥童,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工褒翰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留贮懈,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓优训,卻偏偏與公主長得像朵你,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子揣非,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容