**Foreword**

Open Zhihu's login page,You can see a dynamic effect in its background,It looks pretty good:

This effect is not difficult to achieve using canvas,The next step is to explain and achieve this effect step by step.

**analysis**

Analyze how this effect moves before starting work.The first thing to understand is that although it looks as if all lines and circles are moving,But in fact, only circles are moving,A line is nothing more than connecting any two circles that meet certain conditions.Then analyze how the circle moves,From the effect,Each circle is moving at a constant linear speed.And the direction of movement is different,It can be learned from physics-related knowledge,Each circle has a speed in the horizontal and vertical directions.Finally, when the circle moves out of any boundary of the canvas,The circle re-enters the canvas from the opposite side of the edge that is out of the border.Understanding these three key points is much clearer.

**practice**

First create a canvas:

```
//Here we simply set the background color
<body>
<canvas></canvas>
</body>
```

Then first get the context of the canvas and set some common properties

```
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;
```

Next draw the circle,Then the circle center coordinates are needed to draw the circle,Radius, speed in the horizontal direction,Speed in the vertical direction,And this information must meet certain conditions,Created by a function:

```
//Array of all circles,Use balls here
var balls=[];
function createball () {
//x coordinate
var _x=math.random () * canvas.width;
//y coordinate
var _y=math.random () * canvas.height;
//radius [0.01, 15.01]
var _r=math.random () * 15 + 0.01;
//Horizontal speed [± 0.0, ± 0.5]
var _vx=math.random () * 0.5 * math.pow (-1, math.floor (math.random () * 2 + 1));
//vertical speed [± 0.0, ± 0.5]
var _vy=math.random () * 0.5 * math.pow (-1, math.floor (math.random () * 2 + 1));
//Store the information of each circle in the array
balls.push ({
x:_x, y:_y, r:_r, vx:_vx, vy:_vy
});
}
```

Then choose how many circles you need to draw according to your situation,Here I assume there are 20 and it looks a bit more comfortable:

```
//number of circles
var num=20;
for (var i=0;i<num;i ++) {
createball ();
}
```

Now the circle of information is all there,The next step is to draw circles and lines for each frame,Create a render function, and then draw all the circles inside the function:

```
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 ();
}
```

Next, it is necessary to traverse whether the distance between the centers of each two circles is less than a certain critical value (such as 500), and meet the two centers of the circles:

```
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 ();
}
}
}
```

Here the distance function calculates the distance between two points:

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

Another step is to determine whether the circle exceeds the boundary value.If the conditions are met, come in again from the opposite side:

```
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;
}
}
```

Of course, if i want to keep it simple,Remove and regenerate a circle whenever the circle exceeds:

```
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 ();
}
```

This completes the details of each frame drawing,The last step is to make the circles move:

```
(function loop () {
render ();
requestanimationframe (loop);
}) ();
```

### Related articles

- python - you may need to restart the kernel to use updated packages error
- php - coincheck api authentication doesn't work
- php - i would like to introduce the coincheck api so that i can make payments with bitcoin on my ec site
- [php] i want to get account information using coincheck api
- the emulator process for avd pixel_2_api_29 was killed occurred when the android studio emulator was started, so i would like to
- javascript - how to check if an element exists in puppeteer
- python 3x - typeerror: 'method' object is not subscriptable
- i want to call a child component method from a parent in vuejs
- xcode - pod install [!] no `podfile 'found in the project directory
- sh - 'apt-get' is not recognized as an internal or external command, operable program or batch file