先看一看效果: 先分析粒子連線的實現步驟: 1.初始化一張畫布 2.創建粒子 1)創建粒子即在畫布上畫一個個小圓 2)初始化粒子的屬性:數量:num 300;半徑:3;圓形為隨機排列且滿足:x:0<x<瀏覽器的寬度;y:0<y<瀏覽器的高度; 3.粒子運動 這裡要理解粒子運動的本質並不是粒子在運動, ...
先看一看效果:
先分析粒子連線的實現步驟:
1.初始化一張畫布
2.創建粒子
1)創建粒子即在畫布上畫一個個小圓
2)初始化粒子的屬性:數量:num 300;半徑:3;圓形為隨機排列且滿足:x:0<x<瀏覽器的寬度;y:0<y<瀏覽器的高度;
3.粒子運動
這裡要理解粒子運動的本質並不是粒子在運動,而是不斷地重新繪畫粒子,擦除之前的粒子;
4.粒子連線
1)是否構成連線的條件
2)構成條件的粒子之間連接成線
(接下來說一下一些步驟的實現,沒按標準格式,文末有源碼!)
先初始化一張畫布
1 <canvas id="canvas"></canvas>
設置一下樣式
1 body{ 2 margin:0; 3 } 4 #canvas{ 5 display: block; 6 background-color: black; 7 }
具體的畫布大小我們在js代碼中實現
1 var cxt=document.getElementById("canvas").getContext('2d');//創建畫筆 2 var canvas=document.getElementById("canvas"); 3 canvas.width=window.innerWidth;//設置畫布寬高 4 canvas.height=window.innerHeight;
粒子的屬性
1 var num=300; 2 var data=[];//儲存粒子的屬性數據 3 function init(){ 4 for(var i=0;i<num;i++){ 5 data[i]={ 6 x1: Math.random() * window.innerWidth,//隨機的粒子圓心坐標 7 y1: Math.random() * window.innerHeight, 8 sX: Math.random() * 0.6 - 0.3,//取值範圍0.3-0.3,是粒子運動的偏移量 9 sY: Math.random() * 0.6 - 0.3 10 }; 11 createArc(data[i].x1,data[i].y1);//調用創建粒子的函數 12 } 13 } 14 init();
創建粒子的函數
1 function createArc(x,y){ 2 cxt.save(); 3 cxt.beginPath(); 4 cxt.fillStyle='greenyellow';//粒子的顏色 5 cxt.arc(x,y,2,0,Math.PI*2,false); 6 cxt.closePath(); 7 cxt.fill(); 8 cxt.restore(); 9 }
粒子運動
1 function drawPath(){ 2 cxt.clearRect(0,0,window.innerWidth,window.innerHeight);//先清除之前的圓 3 for(var i=0;i<num;i++){ 4 data[i].x1+=data[i].sX; 5 data[i].y1+=data[i].sY; 6 //邊界值檢測,如果坐標跑出視窗則坐標的偏移量變為負使得它反向 7 if(data[i].x1<0||data[i].x1>window.innerWidth) data[i].sX=-data[i].sX; 8 if(data[i].y1<0||data[i].y1>window.innerHeight) data[i].sY=-data[i].sY; 9 createArc(data[i].x1,data[i].y1); 10 //利用勾股定理判斷是否連線,如果兩點之間的距離小於某一值則調用createLine函數創建線條 11 for(var j=i+1;j<num;j++){//下一個點/下下一個點... 12 if(Math.pow(data[i].x1-data[j].x1,2)+Math.pow(data[i].y1-data[j].y1,2)<100*80)createLine(data[i].x1,data[i].y1,data[j].x1,data[j].y1); 13 } 14 } 15 } 16 setInterval(function(){ //利用定時器,沒1毫秒調用一次該函數,使得粒子不斷地擦除舊圓繪畫新圓 17 drawPath()},1);
以下是創建線條地createLine函數
1 function createLine(x1,y1,x2,y2){ 2 cxt.save(); 3 var lin=cxt.createLinearGradient(x1,y1,x2,y2); 4 lin.addColorStop(0,'blue'); 5 lin.addColorStop(1,'green'); 6 cxt.lineWidth=1.5; 7 cxt.strokeStyle=lin; 8 cxt.beginPath(); 9 //連線 10 cxt.moveTo(x1,y1); 11 cxt.closePath(); 12 cxt.lineTo(x2,y2); 13 cxt.stroke(); 14 cxt.restore(); 15 }
至此代碼就結束了,以下是源碼
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>粒子連線</title> 6 <style> 7 body{ 8 margin:0; 9 } 10 #canvas{ 11 display: block; 12 background-color: black; 13 } 14 </style> 15 </head> 16 <canvas id="canvas"></canvas> 17 <script> 18 //初始化畫布屬性 19 var cxt=document.getElementById("canvas").getContext('2d'); 20 var canvas=document.getElementById("canvas"); 21 canvas.width=window.innerWidth; 22 canvas.height=window.innerHeight; 23 var num=300; 24 var data=[];//儲存粒子的屬性數據 25 function init(){ 26 for(var i=0;i<num;i++){ 27 data[i]={ 28 x1: Math.random() * window.innerWidth, 29 y1: Math.random() * window.innerHeight, 30 sX: Math.random() * 0.6 - 0.3,//取值範圍0.3-0.3 31 sY: Math.random() * 0.6 - 0.3 32 }; 33 createArc(data[i].x1,data[i].y1); 34 } 35 } 36 init(); 37 38 //創建粒子 39 function createArc(x,y){ 40 cxt.save(); 41 cxt.beginPath(); 42 cxt.fillStyle='greenyellow'; 43 cxt.arc(x,y,2,0,Math.PI*2,false); 44 cxt.closePath(); 45 cxt.fill(); 46 cxt.restore(); 47 } 48 49 //創建線條 50 function createLine(x1,y1,x2,y2){ 51 cxt.save(); 52 var lin=cxt.createLinearGradient(x1,y1,x2,y2); 53 lin.addColorStop(0,'blue'); 54 lin.addColorStop(1,'green'); 55 cxt.lineWidth=1.5; 56 cxt.strokeStyle=lin; 57 cxt.beginPath(); 58 //連線 59 cxt.moveTo(x1,y1); 60 cxt.closePath(); 61 cxt.lineTo(x2,y2); 62 cxt.stroke(); 63 cxt.restore(); 64 } 65 66 //粒子運動 67 function drawPath(){ 68 cxt.clearRect(0,0,window.innerWidth,window.innerHeight);//先清除之前的圓 69 for(var i=0;i<num;i++){ 70 data[i].x1+=data[i].sX; 71 data[i].y1+=data[i].sY; 72 //邊界值檢測 73 if(data[i].x1<0||data[i].x1>window.innerWidth) data[i].sX=-data[i].sX; 74 if(data[i].y1<0||data[i].y1>window.innerHeight) data[i].sY=-data[i].sY; 75 createArc(data[i].x1,data[i].y1); 76 //利用勾股定理判斷是否連線 77 for(var j=i+1;j<num;j++){//下一個點/下下一個點... 78 if(Math.pow(data[i].x1-data[j].x1,2)+Math.pow(data[i].y1-data[j].y1,2)<100*80)createLine(data[i].x1,data[i].y1,data[j].x1,data[j].y1); 79 } 80 } 81 } 82 setInterval(function(){ 83 drawPath() 84 },1); 85 </script> 86 <body> 87 </body> 88 </html>