使用原生js+canvas實(shí)現(xiàn)模擬心電圖的實(shí)例
從2015年2月轉(zhuǎn)行進(jìn)入IT行業(yè),到現(xiàn)在也有將近兩年的時間了,從最開始的java到現(xiàn)在的前端,前進(jìn)的路上一直靠自己摸索,一路走到現(xiàn)在,前端大神是絕對談不上的,最多算一只剛?cè)腴T的菜鳥。
從最開始的懵懵懂懂,到現(xiàn)在學(xué)著開始寫github、寫博客,其實(shí)技術(shù)上沒有太多可寫的,畢竟自己也才剛剛?cè)腴T,只能說是按照自己的興趣,寫點(diǎn)有意思的小項目,項目上存在的問題,也希望大神能夠予以指正,目前這個demo的功能已經(jīng)實(shí)現(xiàn),后期我會對樣式、代碼等方面進(jìn)行優(yōu)化。
項目運(yùn)行效果:
項目簡介:使用原生js+canvas制作的模擬心電圖的html頁面,因?yàn)楹晚椖恳黄鸫虬诺搅薵ithub上,所以使用了vue.js的單頁模式,實(shí)際上你不需要使用任何額外的框架和樣式,也可以完成這個demo,現(xiàn)在讓我們一起來拆解這個項目吧!
1:在頁面上創(chuàng)建一個canvas畫布,要讓心電圖的“線”在我們的頁面上動起來,canvas是必不可少的。因?yàn)轫椖勘容^簡單,到此為止頁面上的DOM元素已經(jīng)寫完了,主要的工作量集中在js部分
<div class="heartBeat"> <canvas id="can">Canvas畫板</canvas> </div>
2:定義幾個變量并賦值,運(yùn)行時會需要用到這些變量進(jìn)行計算
var can = document.getElementById('can'),//畫布對象 pan,//獲取2D圖像API接口 index = 0,//用來接收setinerval的值 flag = true,//用來控制心電圖折線的運(yùn)行方向 wid = document.body.clientWidth,//獲取瀏覽器寬度 hei = document.body.clientHeight,//獲取瀏覽器高度 x = 0,//心電圖的“點(diǎn)”在畫布上的x軸坐標(biāo),從0開始 y = hei/2;//心電圖的“點(diǎn)”在畫布上的y軸坐標(biāo),從頁面y軸居中位置開始
3:初始化畫布,給畫布設(shè)置各種屬性
function start(){ can.height = hei;//設(shè)置畫布高度 can.width = wid;//設(shè)置畫布寬度 pan = can.getContext("2d");//獲取2D圖像API接口 pan.strokeStyle = "#08b95a";//設(shè)置畫筆顏色 pan.lineJoin = "round";//設(shè)置畫筆軌跡基于圓點(diǎn)拼接 pan.lineWidth = 9;//設(shè)置畫筆粗細(xì) pan.beginPath();//開始一條畫筆的路徑 pan.moveTo(x,y);//定位我們的“落筆點(diǎn)” index = setInterval(move,1);//讓我們的畫筆動起來 };
可以看到,在這里我們還沒有涉及到“畫”的動作,僅僅只是初始化了畫布尺寸,使畫布充滿屏幕,同時定義了畫筆的顏色、粗細(xì)、落筆點(diǎn)等操作,然后使用setInterval方法讓畫筆不停地按照我們計算的路線運(yùn)動,如果你對setInterval方法不是很熟悉,建議你看下 setInterVal用法 ,這里不再敷述。因?yàn)槲覀兿胍屝碾妶D無限循環(huán)且自動執(zhí)行,所以在這里將它封裝為start()函數(shù),這樣當(dāng)心電圖運(yùn)動到屏幕最右方時,我們重新執(zhí)行這個start()函數(shù),就可以實(shí)現(xiàn)讓心電圖無限循環(huán)了
4.讓心電圖動起來!可以說,前面的步驟都沒有什么難度,真正的核心代碼在于讓我們的心電圖動起來,并且是按照我們希望的路線前進(jìn),下面我們就讓心電圖真正活過來
function move(){ x++;//x軸是始終運(yùn)動的,所以x一直自增 if(x < 100){ //前100px,我們不希望做垂直運(yùn)動,讓點(diǎn)只沿垂直方向運(yùn)動即可,所以不做任何操作 }else{ if(x >= wid - 100){ //最后的100px,同樣希望心電圖只做水平運(yùn)動,不會上下波動,所以不做任何操作 }else{ //為了讓心電圖看起來更加逼真,我們希望心電圖在運(yùn)動時每次的波峰和波谷都是隨機(jī)的,這樣更類似于人類的心跳,所以我們給它一個隨機(jī)值z var z = Math.random()*280; if(y <= z){ //畫布的坐標(biāo)是從左上角開始計算的,也就是最左上角的點(diǎn)的坐標(biāo)是(0,0),y是當(dāng)前畫筆所在坐標(biāo)的y軸,假如y小于z,就代表y已經(jīng)到達(dá)波峰位置,準(zhǔn)備開始向波谷運(yùn)動 flag = true } if((hei - y) <= z){ //假如當(dāng)前畫筆在y軸的坐標(biāo)y距離瀏覽器底部hei的差值已經(jīng)小于隨機(jī)值z,代表當(dāng)前的畫筆已經(jīng)運(yùn)行到波谷位置,準(zhǔn)備轉(zhuǎn)向波峰位置運(yùn)動 flag = false } if(flag){ //假如flag為true,代表畫筆仍然向波谷位置前進(jìn),需要花點(diǎn)功夫理解的是,因?yàn)楫嫴甲笊辖堑狞c(diǎn)的坐標(biāo)是(0,0),所以y的值越大,畫筆在y軸的位置越靠近瀏覽器底部,所以向波谷運(yùn)動時,y的值是不斷增加的,同時為了讓波峰波谷更陡峭,我這里設(shè)置y += 5, y+=5 }else{ //假如flag為false,表示向波峰運(yùn)動,y的值是不斷減小的 y-=5 } } } if(x == wid){ //當(dāng)畫筆運(yùn)動到瀏覽器右側(cè)邊緣,停止繪圖 pan.closePath(); //清除循環(huán) clearInterval(index); //將index置零,準(zhǔn)備下一次循環(huán) index = 0; //重新定位畫筆到屏幕左側(cè)上下居中的位置 x = 0; y = hei/2; flag = true; //重新進(jìn)行下一次心電圖的繪制 start(); } //lineTo和stroke函數(shù)負(fù)責(zé)描繪運(yùn)動軌跡 pan.lineTo(x,y); pan.stroke(); }
5:注意事項,到這里實(shí)際上心電圖已經(jīng)可以運(yùn)行起來了,但是要注意的是,設(shè)置你的body高度為100%,否則畫布可能無法撐滿整個頁面
html,body{ width: 100%; height: 100%; margin: 0; }
項目完整代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模擬心電圖</title> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <style> html,body{ width: 100%; height: 100%; margin: 0; } </style> </head> <body> <div id="canvas"> <canvas id="can">Canvas畫板</canvas> </div> <script src="js/vue.min.js"></script> <script> var can = document.getElementById('can'), pan, index = 0, flag = true, wid = document.body.clientWidth, hei = document.body.clientHeight, x = 0, y = hei/2; start(); function start(){ can.height = hei; can.width = wid; pan = can.getContext("2d");//獲取2D圖像API接口 pan.strokeStyle = "#08b95a";//設(shè)置畫筆顏色 pan.lineJoin = "round";//設(shè)置畫筆軌跡基于圓點(diǎn)拼接 pan.lineWidth = 9;//設(shè)置畫筆粗細(xì) pan.beginPath(); pan.moveTo(x,y); index = setInterval(move,1); }; function move(){ x++; if(x < 100){ }else{ if(x >= wid - 100){ }else{ var z = Math.random()*280; if(y <= z){ flag = true } if((hei - y) <= z){ flag = false } if(flag){ y+=5 }else{ y-=5 } } } if(x == wid){ pan.closePath(); clearInterval(index); index = 0; x = 0; y = hei/2; flag = true; start(); } pan.lineTo(x,y); pan.stroke(); } /* */ </script> </body> </html>
以上這篇使用原生js+canvas實(shí)現(xiàn)模擬心電圖的實(shí)例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
javascript實(shí)現(xiàn)html頁面之間參數(shù)傳遞的四種方法實(shí)例分析
這篇文章主要介紹了javascript實(shí)現(xiàn)html頁面之間參數(shù)傳遞的四種方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了JavaScript實(shí)現(xiàn)頁面之間參數(shù)傳遞的常用技巧,需要的朋友可以參考下2015-12-12JavaScript 組件之旅(二)編碼實(shí)現(xiàn)和算法
話說上期我們討論了隊列管理組件的設(shè)計,并且給它取了個響亮而獨(dú)特的名字:Smart Queue. 這次,我們要將之前的設(shè)計成果付諸實(shí)踐,用代碼來實(shí)現(xiàn)它。2009-10-10JavaScript純前端實(shí)現(xiàn)在線GIF壓縮
這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript純前端實(shí)現(xiàn)在線GIF壓縮工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03js判斷主流瀏覽器類型和版本號的簡單實(shí)現(xiàn)代碼
下面小編就為大家?guī)硪黄猨s判斷主流瀏覽器類型和版本號的簡單實(shí)現(xiàn)代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05基于 D3.js 繪制動態(tài)進(jìn)度條的實(shí)例詳解
D3是一個被數(shù)據(jù)驅(qū)動的文檔。這篇文章主要介紹了基于 D3.js 繪制動態(tài)進(jìn)度條的方法,需要的朋友可以參考下2018-02-02