Canvas繪制浮動(dòng)球效果

最近關(guān)注區(qū)塊鏈方面的信息, 瞎轉(zhuǎn)悠, 偶然看到這個(gè)網(wǎng)站首頁(yè)的效果. 一堆浮動(dòng)的球, 球在距離較近的時(shí)候會(huì)有感應(yīng)線連接, 鼠標(biāo)也可以和球產(chǎn)生感應(yīng)線. 看了下是用canvas做的.

原效果 實(shí)現(xiàn)效果
expected.gif
demo.gif

之前對(duì)svg有過(guò)很多接觸, canvas知道也可以做到很強(qiáng)大的渲染效果, 但是一直沒(méi)有什么使用場(chǎng)景給我上手的機(jī)會(huì). 于是這次打算自己試著上手下.

另外, 之所以對(duì)這個(gè)感興趣, 一個(gè)是喜歡視覺(jué)效果類的東西, 二是喜歡類似游戲引擎那種模擬物理世界的感覺(jué), 試想一下這些球會(huì)相互碰撞, 或者相互之間有引力斥力, 或者加上重力因素. 這個(gè)動(dòng)畫(huà)還可以開(kāi)不少腦洞.

github repo見(jiàn)這里.

Canvas

Canvas的畫(huà)圖指令很類似SVG里面的指令, 很簡(jiǎn)單.

畫(huà)圓

ctx.beginPath();
ctx.arc(this.center.x, this.center.y, this.radius, 0, 2 * Math.PI);
ctx.fill();

beginPath開(kāi)始一段路徑, arc畫(huà)一個(gè)圓, 然后fill填充顏色.

畫(huà)線

ctx.beginPath();
ctx.moveTo(from.x, from.y);
ctx.lineTo(to.x, to.y);
ctx.stroke();

同樣是beginPath開(kāi)始一段路徑, moveTo移動(dòng)畫(huà)筆到起點(diǎn), lineTo繪制線到終點(diǎn), stroke描邊.

Canvas全屏

要保持canvas一直全屏, 只要在window onloadonresize的時(shí)候重置一下canvas的寬高即可.

var canvas = document.getElementById("canvas");
function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}
window.onload = window.onresize = resizeCanvas;

動(dòng)畫(huà)

Basic animations帶我上手.

基本步驟

做動(dòng)畫(huà)的四個(gè)步驟:

  1. 清除canvas內(nèi)容, 通常使用clearRect()
  2. 保存canvas狀態(tài)
  3. 繪制內(nèi)容
  4. 重置canvas狀態(tài)

我做的這個(gè)比較簡(jiǎn)單, 只用到了1和3, 就是不斷地清空canvas然后重繪.

window.onload = function () {
    resizeCanvas();
    window.requestAnimationFrame(draw);
};
function cleanCanvas() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function draw() {
    cleanCanvas();
    // draw stuffs.
    window.requestAnimationFrame(draw);
}

控制函數(shù)

三個(gè)可以用:

  1. window.setInterval() 如果完全不需要用戶交互, 只是不斷重繪, 用這個(gè)就夠了.
  2. window.setTimeout() 如果想要用戶操作, 如鍵盤鼠標(biāo), 影響動(dòng)畫(huà), 可以用這個(gè). (不懂, 不是requestAnimationFrame更好么?)
  3. window.requestAnimationFrame() 告知瀏覽器下次重繪之前要做的事情, 即你自己定制的繪制操作.

MDN里面的這個(gè)例子還挺酷的. CodePen. 可以動(dòng)起來(lái)的, 下面只是一個(gè)截圖.

Solar System

數(shù)據(jù)結(jié)構(gòu)

之前看過(guò)一點(diǎn)Game Engine Development, 有意識(shí)地做面向?qū)ο蟮姆庋b. 這里面用到的是非常簡(jiǎn)單的.

最基礎(chǔ)的是Vector代表二維空間上的點(diǎn)/向量, 成員只有x, y.

在此基礎(chǔ)上, Circle代表圓, 成員center: Vector代表圓心, radius: number代表半徑, speed: Vector代表速度.

然后封裝一些自用的成員函數(shù)即可.

開(kāi)發(fā)環(huán)境

TypeScript + Webpack + Webpack-dev-server 不復(fù)雜, 參考以下內(nèi)容即可:

  1. Webpack/Getting Started
  2. Webpack/Typescript
  3. Webpack/devServer
  4. webpack-dev-server

另外, 還試用了npx, 用來(lái)運(yùn)行npm的可執(zhí)行程序. 以前webpack什么的都是全局安裝的, 直接調(diào)用webpack xx即可. 如果本地安裝webpack的話, 就需要通過(guò)./node_modules/.bin/webpack來(lái)運(yùn)行本地的webpack, 現(xiàn)在可以npx webpack xxx.

更多見(jiàn)npx

一個(gè)小坑

在devServer的config里面, 加入了hot: true想開(kāi)啟熱更新, 結(jié)果網(wǎng)頁(yè)里面提示: [HMR] Hot Module Replacement is disabled.

發(fā)現(xiàn)是一個(gè)老坑, 需要調(diào)用的時(shí)候加上命令行參數(shù): webpack-dev-server --hot --inline

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末惰蜜,一起剝皮案震驚了整個(gè)濱河市业筏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異宏粤,居然都是意外死亡脚翘,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門绍哎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)来农,“玉大人,你說(shuō)我怎么就攤上這事崇堰∥钟冢” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵海诲,是天一觀的道長(zhǎng)繁莹。 經(jīng)常有香客問(wèn)我,道長(zhǎng)特幔,這世上最難降的妖魔是什么咨演? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮蚯斯,結(jié)果婚禮上薄风,老公的妹妹穿的比我還像新娘。我一直安慰自己拍嵌,他們只是感情好遭赂,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著横辆,像睡著了一般嵌牺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上龄糊,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天逆粹,我揣著相機(jī)與錄音,去河邊找鬼炫惩。 笑死僻弹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的他嚷。 我是一名探鬼主播蹋绽,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼筋蓖!你這毒婦竟也來(lái)了卸耘?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤粘咖,失蹤者是張志新(化名)和其女友劉穎蚣抗,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體瓮下,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡翰铡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年钝域,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锭魔。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡例证,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出迷捧,到底是詐尸還是另有隱情织咧,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布漠秋,位于F島的核電站笙蒙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏膛堤。R本人自食惡果不足惜手趣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一晌该、第九天 我趴在偏房一處隱蔽的房頂上張望肥荔。 院中可真熱鬧,春花似錦朝群、人聲如沸燕耿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)誉帅。三九已至,卻和暖如春右莱,著一層夾襖步出監(jiān)牢的瞬間蚜锨,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工慢蜓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亚再,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓晨抡,卻偏偏與公主長(zhǎng)得像氛悬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耘柱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

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

  • 無(wú)意中看到zhangwnag大佬分享的webpack教程感覺(jué)受益匪淺如捅,特此分享以備自己日后查看,也希望更多的人看到...
    小小字符閱讀 8,147評(píng)論 7 35
  • 構(gòu)建一個(gè)小項(xiàng)目——FlyBird调煎,學(xué)習(xí)webpack和react镜遣。(本文成文于2017/2/25) 從webpac...
    布蕾布蕾閱讀 16,809評(píng)論 31 98
  • 一:canvas簡(jiǎn)介 1.1什么是canvas? ①:canvas是HTML5提供的一種新標(biāo)簽 ②:HTML5 ...
    GreenHand1閱讀 4,674評(píng)論 2 32
  • 一士袄、圖形的組合方式 globalAlpha是一個(gè)介于0和1之間的值(包括0和1)烈涮,用于指定所有繪制的透明度朴肺。默認(rèn)值...
    空谷悠閱讀 1,256評(píng)論 0 0
  • 首先管控當(dāng)天對(duì)你來(lái)說(shuō)是緊急并重要的事務(wù),然后你就有機(jī)會(huì)去做重要不緊急的坚洽。 執(zhí)行有4個(gè)方案: 第一戈稿、你完成它; 第二...
    黃麗_47b5閱讀 298評(píng)論 0 0