├── 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 |
--------------------------------------------------------------------------------