├── README.md ├── index.html └── main.js /README.md: -------------------------------------------------------------------------------- 1 | canvas画图(仿知乎登录页面动画) 2 | -------- 3 | [演示链接](https://sunweiling.github.io/zhihu-canvas/) 4 | ------- 5 | 主要知识点 6 | 7 | - canvas画图 8 | - es6 class 语法应用 9 | 10 | 总体思路 11 | -------- 12 | - 创建 canvas 对象 13 | - canvas 画圆和画直线 14 | - 圆圈移动 15 | - 鼠标点画圆闪烁变动,以及连线其他原点 16 | - requestAnimationFrame 更新画面 17 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | canvas 6 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | class Circle{ 2 | 3 | constructor(x, y) { 4 | this.x = x; 5 | this.y = y; 6 | this.r = Math.random() * 14 + 1; 7 | this._mx = Math.random() * 2 - 1; 8 | this._my = Math.random() * 2 - 1; 9 | } 10 | 11 | drawCircle(ctx) { 12 | ctx.beginPath(); 13 | ctx.arc(this.x, this.y, this.r, 0, 360); 14 | ctx.closePath(); 15 | ctx.fillStyle = 'rgba(204, 204, 204, 0.2)'; 16 | ctx.fill(); 17 | } 18 | 19 | drawLine(ctx, _circle) { 20 | let dx = this.x - _circle.x; 21 | let dy = this.y - _circle.y; 22 | let d = Math.sqrt(dx * dx + dy * dy); 23 | if(d < 150) { 24 | ctx.beginPath(); 25 | ctx.moveTo(this.x, this.y);//起始点 26 | ctx.lineTo(_circle.x, _circle.y);//终点 27 | ctx.closePath(); 28 | ctx.strokeStyle = 'rgba(204, 204, 204, 0.1)'; 29 | ctx.stroke(); 30 | } 31 | } 32 | 33 | move(w, h) { 34 | this._mx = (this.x < w && this.x > 0) ? this._mx: ( - this._mx); 35 | this._my = (this.y < h && this.y > 0) ? this._my: ( - this._my); 36 | this.x += this._mx/2; 37 | this.y += this._my/2; 38 | } 39 | } 40 | 41 | 42 | class currentCircle extends Circle { 43 | constructor(x, y) { 44 | super(x, y); 45 | } 46 | drawCircle(ctx) { 47 | ctx.beginPath(); 48 | this.r = (this.r < 14 && this.r > 1)? this.r + (Math.random() * 2 - 1): 2; 49 | ctx.arc(this.x, this.y, this.r, 0, 360); 50 | ctx.closePath(); 51 | ctx.fillStyle = 'rgba(45, 120, 244, ' + (parseInt(Math.random()*100)/100) + ')'; 52 | ctx.fill(); 53 | } 54 | } 55 | 56 | 57 | 58 | window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; 59 | let canvas = document.querySelector("#canvas"); 60 | let ctx = canvas.getContext("2d"); 61 | let w = canvas.width = canvas.offsetWidth; 62 | let h = canvas.height = canvas.offsetHeight; 63 | let circles = []; 64 | let current_circle = new currentCircle(0, 0); 65 | 66 | 67 | 68 | let draw = function(){ 69 | ctx.clearRect(0, 0, w, h); 70 | for(let i = 0; i < circles.length; i++) { 71 | circles[i].move(w, h); 72 | circles[i].drawCircle(ctx); 73 | for(j = i + 1; j < circles.length; j++) { 74 | circles[i].drawLine(ctx, circles[j]) 75 | } 76 | } 77 | if(current_circle.x){ 78 | current_circle.drawCircle(ctx); 79 | for(var k = 1; k < circles.length; k++) { 80 | current_circle.drawLine(ctx, circles[k]); 81 | } 82 | } 83 | requestAnimationFrame(draw); 84 | } 85 | 86 | let init = function(num){ 87 | for(var i = 0; i < num; i ++){ 88 | circles.push(new Circle(Math.random() * w, Math.random() * h)); 89 | } 90 | draw(); 91 | } 92 | 93 | window.addEventListener('load', init(80)); 94 | window.onmousemove = function(e) { 95 | e = e || window.event; 96 | current_circle.x = e.clientX; 97 | current_circle.y = e.clientY; 98 | }, window.onmouseout = function() { 99 | current_circle.x = null; 100 | current_circle.y = null; 101 | }; 102 | --------------------------------------------------------------------------------