国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

canvas簡單快速的實現知乎登錄頁背景效果

2019-11-19 16:38:34
字體:
來源:轉載
供稿:網友

前言

打開知乎的登錄頁,就可以看到其背景有一個動效,看起來好像蠻不錯的樣子:

這個效果使用canvas是不難實現的,接下來就一步一步地講解并實現這個效果。

分析

在動工之前先分析這個效果到底是如何運動的。首先要理解的是雖然看起來好像所有線和圓都在運動,但實際上只有圓才是在運動的,而線只不過是把滿足一定條件的任意兩個圓連接在一起。那么接下來就分析圓是怎么運動的,從效果看,每個圓都是在做勻速直線運動,而且運動方向不一,通過物理相關知識可以得知,每一個圓在水平方向和垂直方向都有一個速度。最后是當圓運動出畫布任一邊界的時候,這個圓會從出邊界的這條邊的對邊再次進入畫布。把這三個關鍵點理解清楚了就清晰很多了。

實踐

先創建一個canvas畫布:

// 這里就簡單地設置下背景色<body style="background:#f7fafc;"> <canvas id="canvas" style="width: 100%; height: 100%;"></canvas></body>

接著先獲取canvas的上下文環境并設置一些共用的屬性

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");canvas.width = document.documentElement.clientWidth;canvas.height = document.documentElement.clientHeight;context.fillStyle = "rgba(0, 0, 0, 0.08)";context.strokeStyle = "rgba(0, 0, 0, 0.05)";context.lineWidth = 0.5;

接下來繪制圓,那么繪制圓需要圓的圓心坐標,半徑,水平方向的速度,垂直方向的速度,并且這些信息要滿足一定的條件,通過一個函數來創建:

// 存放所有圓的數組,這里用ballsvar balls = [];function createBall() { // x坐標 var _x = Math.random() * canvas.width; // y坐標 var _y = Math.random() * canvas.height; // 半徑 [0.01, 15.01] var _r = Math.random() * 15 + 0.01; // 水平速度 [±0.0, ±0.5] var _vx = Math.random() * 0.5 * Math.pow( -1, Math.floor(Math.random() * 2 + 1) ); // 垂直速度 [±0.0, ±0.5] var _vy = Math.random() * 0.5 * Math.pow( -1, Math.floor(Math.random() * 2 + 1) ); // 把每一個圓的信息存放到數組中 balls.push({ x: _x, y: _y, r: _r, vx: _vx, vy: _vy });}

然后根據自己的情況選擇需要繪制多少個圓,這里我假設有20個,看起來舒服一點:

// 圓的數量var num = 20;for(var i = 0; i < num; i++) { createBall();}

現在圓的信息都有了,下一步就是繪制每一幀的圓和線,創建一個render函數,然后在函數內先繪制所有的圓出來:

for(var k = 0; k < num; k++) { context.save(); context.beginPath(); context.arc( balls[k].x, balls[k].y, balls[k].r, 0, Math.PI*2 ); context.fill(); context.restore();}

接著要遍歷每兩個圓的圓心之間的距離是否小于某個臨界值(比如500),滿足則將這兩個圓的圓心連接起來:

for(var i = 0; i < num; i++) { for(var j = i + 1; j < num; j++) { if( distance( balls[i], balls[j] ) < 500 ) {  context.beginPath();  context.moveTo( balls[i].x, balls[i].y );  context.lineTo( balls[j].x, balls[j].y );  context.stroke(); } }}

這里的 distance 函數就是計算兩點之間的距離:

function distance(point1, point2) { return Math.sqrt( Math.pow( (point1.x - point2.x), 2 ) + Math.pow( (point1.y - point2.y), 2 ) );}

還有一步就是判斷圓是否超出了邊界值,若滿足條件則從對邊再次進來:

for(var k = 0; k < num; k++) { balls[k].x += balls[k].vx; balls[k].y += balls[k].vy; if( balls[k].x - balls[k].r > canvas.width ) { balls[k].x = 0 - balls[k].r; } if( balls[k].x + balls[k].r < 0 ) { balls[k].x = canvas.width + balls[k].r; } if( balls[k].y - balls[k].r > canvas.height ) { balls[k].y = 0 - balls[k].r; } if( balls[k].y + balls[k].r < 0 ) { balls[k].y = canvas.height + balls[k].r; }}

當然如果想簡單點,只要圓超出就移除并重新生成一個圓即可:

if( balls[k].x - balls[k].r > canvas.width ||  balls[k].x + balls[k].r < 0 ||  balls[k].y - balls[k].r > canvas.height ||  balls[k].y + balls[k].r < 0) { balls.splice(k, 1); createBall();}

這樣每一幀繪制的細節就完成了,最后一步就是讓圓都運動起來:

(function loop(){ render(); requestAnimationFrame(loop);})();

到此,整個效果就出來了。當然這里面有很多細節可以自己琢磨琢磨,讓這個效果變得更加細膩多彩。希望對新手有所幫助。

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鄂温| 南木林县| 和顺县| 巢湖市| 德化县| 天门市| 闸北区| 宝清县| 邹平县| 全椒县| 阆中市| 周宁县| 文水县| 抚州市| 安义县| 丰镇市| 炉霍县| 明水县| 忻城县| 外汇| 巩义市| 澎湖县| 九寨沟县| 张家口市| 苗栗市| 中宁县| 桑植县| 京山县| 腾冲县| 天全县| 修文县| 德惠市| 屏边| 乃东县| 南岸区| 武川县| 三江| 涞源县| 汉沽区| 沙田区| 楚雄市|