不含連線效果:
有連線的效果:
教學要實現這樣的效果其實很簡單,大概分成這麼幾個步驟:
創建canvas首先需要在需要展示粒子背景的父元素中創建一個canvas標籤, 指定width和height , 在我們產生隨機點座標的時候需要用width和height來做參照。 width和height等於父元素的寬和高。
// 假如父元素是bodyconst ele = document.body;const canvas = document.createElement('canvas');canvas.width = ele.clientWidth;canvas.height = ele.clientHeight;// 將canvasChild標籤插入ele.appendChild. (canvas);隨機產生一定數量的點座標訊息以width和height做參照隨機產生一定數量的點座標信息,包含x , y , rateX (點在X軸的移動速率), rateY (點在Y軸移動的速率), rateX和rateY決定了點的運動軌跡。
const points = [];// 隨機產生點的座標,需指定radius的最大值function getPoint(radius) { const x = Math.ceil(Math.random() * this.width), // 粒子的x座標y = Math.ceil(Math.random() * this.height), // 粒子的y座標r = +(Math.random() * this.radius).toFixed(4), // 粒子的半徑rateX = +(Math.random() * 2 - 1).toFixed(4), // 粒子在x方向運動的速率rateY = +(Math. random() * 2 - 1).toFixed(4); // 粒子在y方向運動的速率return { x, y, r, rateX, rateY };}//隨機產生100個點的座標資訊for (let i = 0; i < 100; i++) { points.push(this.getPoint());}將產生的點數組畫到canvas上
function drawPoints() { points.forEach((item, i) => { ctx.beginPath(); ctx.arc(item.x, item.y, item.r, 0, Math.PI*2, false); ctx.fillStyle = '#fff'; ctx.fill(); // 根據rateX和rateY移動點的座標if(item.x > 0 && item.x < width && item.y > 0 && item.y < height) { item.x += item.rateX * rate; item.y += item.rateY * rate; } else { // 如果粒子運動超出了邊界,將這個粒子去除,同時重新產生一個新點。 points.push(getPoint(radius)); } });}畫線遍歷點數組,兩兩比較點座標,如果兩點之間距離小於某個值,在兩點之間畫一條直線, lineWidth隨兩點之間距離改變,距離越大,線越細。
// 計算兩點之間的距離function dis(x1, y1, x2, y2) { var disX = Math.abs(x1 - x2), disY = Math.abs(y1 - y2); return Math.sqrt(disX * disX + disY * disY);}function drawLines() { const len = points.length; //對圓心座標進行兩兩判斷for(let i = 0; i < len; i++) { for(let j = len - 1; j >= 0; j--) { const x1 = points[i]. x, y1 = points[i].y, x2 = points[j].x, y2 = points[j].y, disPoint = dis(x1, y1, x2, y2); // 若兩點之間距離小於150,畫線if(disPoint <= 150) { ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx. strokeStyle = '#fff'; //兩點之間距離越大,線越細,反之亦然ctx.lineWidth = 1 - disPoint / distance; ctx.stroke(); } } }}動畫使用requestAnimationFrame循環呼叫draw方法(draw方法裡包含畫點和畫線),同時在draw的時候根據rateX和rateY來改變點的位置。
// 呼叫 draw函數開啟動畫(function draw() { ctx.clearRect(0, 0, width, height); drawPoints(); // 如果不需要畫線,請取消下面這行程式碼即可。drawLines(); window.requestAnimationFrame(draw);}());完整程式碼請看:https://github.com/PengJiyuan/particle-bg
我的Github:https://github.com/PengJiyuan
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。