使用原生js+canvas實現模擬心電圖


從2016年2月轉行進入IT行業,到現在也有將近兩年的時間了,從最開始的java到現在的前端,前進的路上一直靠自己摸索,一路走到現在,前端大神是絕對談不上的,最多算一只剛入門的菜鳥。

從最開始的懵懵懂懂,到現在學着開始寫github、寫博客,其實技術上沒有太多可寫的,畢竟自己也才剛剛入門,只能說是按照自己的興趣,寫點有意思的小項目,項目上存在的問題,也希望大神能夠予以指正,目前這個demo的功能已經實現,后期我會對樣式、代碼等方面進行優化。

項目githu地址: https://qq597367462.github.io/ttmusic/#/heartBeat

項目運行效果:

 

項目簡介:使用原生js+canvas制作的模擬心電圖的html頁面,因為和項目一起打包放到了github上,所以使用了vue.js的單頁模式,實際上你不需要使用任何額外的框架和樣式,也可以完成這個demo,現在讓我們一起來拆解這個項目吧!

1:在頁面上創建一個canvas畫布,要讓心電圖的“線”在我們的頁面上動起來,canvas是必不可少的。因為項目比較簡單,到此為止頁面上的DOM元素已經寫完了,主要的工作量集中在js部分

1 <div class="heartBeat">
2   <canvas id="can">Canvas畫板</canvas>
3 </div>

 

2:定義幾個變量並賦值,運行時會需要用到這些變量進行計算

1  var can = document.getElementById('can'),//畫布對象
2         pan,//獲取2D圖像API接口
3         index = 0,//用來接收setinerval的值
4         flag = true,//用來控制心電圖折線的運行方向
5         wid = document.body.clientWidth,//獲取瀏覽器寬度
6         hei = document.body.clientHeight,//獲取瀏覽器高度
7         x = 0,//心電圖的“點”在畫布上的x軸坐標,從0開始
8         y = hei/2;//心電圖的“點”在畫布上的y軸坐標,從頁面y軸居中位置開始

 

3:初始化畫布,給畫布設置各種屬性

 1 function start(){  2         can.height = hei;//設置畫布高度
 3         can.width  = wid;//設置畫布寬度
 4         pan = can.getContext("2d");//獲取2D圖像API接口
 5         pan.strokeStyle = "#08b95a";//設置畫筆顏色
 6         pan.lineJoin = "round";//設置畫筆軌跡基於圓點拼接
 7         pan.lineWidth = 9;//設置畫筆粗細
 8         pan.beginPath();//開始一條畫筆的路徑
 9         pan.moveTo(x,y);//定位我們的“落筆點”
10         index = setInterval(move,1);//讓我們的畫筆動起來
11     };

可以看到,在這里我們還沒有涉及到“畫”的動作,僅僅只是初始化了畫布尺寸,使畫布充滿屏幕,同時定義了畫筆的顏色、粗細、落筆點等操作,然后使用setInterval方法讓畫筆不停地按照我們計算的路線運動,如果你對setInterval方法不是很熟悉,建議你看下  setInterVal用法 ,這里不再敷述。因為我們想要讓心電圖無限循環且自動執行,所以在這里將它封裝為start()函數,這樣當心電圖運動到屏幕最右方時,我們重新執行這個start()函數,就可以實現讓心電圖無限循環了

4.讓心電圖動起來!可以說,前面的步驟都沒有什么難度,真正的核心代碼在於讓我們的心電圖動起來,並且是按照我們希望的路線前進,下面我們就讓心電圖真正活過來

 1 function move(){  2         x++;//x軸是始終運動的,所以x一直自增
 3         if(x < 100){  4             //前100px,我們不希望做垂直運動,讓點只沿垂直方向運動即可,所以不做任何操作
 5         }else{  6             if(x >= wid - 100){  7             //最后的100px,同樣希望心電圖只做水平運動,不會上下波動,所以不做任何操作
 8             }else{  9                 //為了讓心電圖看起來更加逼真,我們希望心電圖在運動時每次的波峰和波谷都是隨機的,這樣更類似於人類的心跳,所以我們給它一個隨機值z
10                 var z = Math.random()*280; 11 
12                 if(y <= z){ 13                     //畫布的坐標是從左上角開始計算的,也就是最左上角的點的坐標是(0,0),y是當前畫筆所在坐標的y軸,假如y小於z,就代表y已經到達波峰位置,准備開始向波谷運動
14                     flag = true
15  } 16                 if((hei - y) <= z){ 17                     //假如當前畫筆在y軸的坐標y距離瀏覽器底部hei的差值已經小於隨機值z,代表當前的畫筆已經運行到波谷位置,准備轉向波峰位置運動
18                     flag = false
19  } 20                 if(flag){ 21                     //假如flag為true,代表畫筆仍然向波谷位置前進,需要花點功夫理解的是,因為畫布左上角的點的坐標是(0,0),所以y的值越大,畫筆在y軸的位置越靠近瀏覽器底部,所以向波谷運動時,y的值是不斷增加的,同時為了讓波峰波谷更陡峭,我這里設置y += 5,
22                     y+=5
23                 }else{ 24                     //假如flag為false,表示向波峰運動,y的值是不斷減小的
25                     y-=5
26  } 27  } 28  } 29         if(x == wid){ 30             //當畫筆運動到瀏覽器右側邊緣,停止繪圖
31  pan.closePath(); 32             //清除循環
33  clearInterval(index); 34             //將index置零,准備下一次循環
35             index = 0; 36             //重新定位畫筆到屏幕左側上下居中的位置
37             x = 0; 38             y = hei/2;
39             flag = true; 40             //重新進行下一次心電圖的繪制
41  start(); 42  } 43         //lineTo和stroke函數負責描繪運動軌跡
44  pan.lineTo(x,y); 45  pan.stroke(); 46     }        

5:注意事項,到這里實際上心電圖已經可以運行起來了,但是要注意的是,設置你的body高度為100%,否則畫布可能無法撐滿整個頁面

1 html,body{ 2      width: 100%; 3      height: 100%; 4      margin: 0; 5     }

項目完整代碼:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>模擬心電圖</title>
 6     <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
 7     <style>
 8  html,body{  9             width: 100%; 10             height: 100%; 11             margin: 0; 12  } 13     </style>
14 </head>
15 <body>
16 <div id="canvas">
17     <canvas id="can">Canvas畫板</canvas>
18 </div>
19 
20 <script src="js/vue.min.js"></script>
21 <script>
22     var can = document.getElementById('can'), 23  pan, 24         index = 0, 25         flag = true, 26         wid = document.body.clientWidth, 27         hei = document.body.clientHeight, 28         x = 0, 29         y = hei/2;
30  start(); 31     function start(){ 32         can.height = hei; 33         can.width  = wid; 34         pan = can.getContext("2d");//獲取2D圖像API接口
35         pan.strokeStyle = "#08b95a";//設置畫筆顏色
36         pan.lineJoin = "round";//設置畫筆軌跡基於圓點拼接
37         pan.lineWidth = 9;//設置畫筆粗細
38  pan.beginPath(); 39  pan.moveTo(x,y); 40         index = setInterval(move,1); 41  }; 42     function move(){ 43         x++; 44         if(x < 100){ 45 
46         }else{ 47             if(x >= wid - 100){ 48 
49             }else{ 50                 var z = Math.random()*280; 51                 if(y <= z){ 52                     flag = true
53  } 54                 if((hei - y) <= z){ 55                     flag = false
56  } 57                 if(flag){ 58                     y+=5
59                 }else{ 60                     y-=5
61  } 62  } 63  } 64         if(x == wid){ 65  pan.closePath(); 66  clearInterval(index); 67             index = 0; 68             x = 0; 69             y = hei/2;
70             flag = true; 71  start(); 72  } 73  pan.lineTo(x,y); 74  pan.stroke(); 75  } 76 
77  /*  */
78 
79 </script>
80 </body>
81 </html>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM