This article first appeared on my blog. This is my GitHub. Welcome to star.

this blog is imitation nest.js Implement a`demo`

From simple to complex, step by step. Here is the preview of the effect. There are many other front-end ones in my GitHub`demo`

You can order it if you like`star`

Your support is my motivation.

## Start with an interview question

Realize a radius

`10px`

The ball of`500px*500px`

The initial direction is random, the speed remains unchanged, and it rebounds after hitting the wall.

take a look at the effect, the idea is very simple, positioning the ball in the box, setting`xy`

Speed in the direction, each frame of animation to the ball positioning value plus the corresponding direction of the speed value, in the detection of the ball collision wall, the corresponding direction of the speed can be set to the opposite direction. Here is the implementation of the code, not used`canvas`

But the ideas are the same.

## Try to implement

nest.js What about the effect. It’s not going to work`Dom`

If you do it directly, it will cost too much performance and can’t do it. This will show`canvas`

The power of.

In the same way`canvas`

Generate multiple bouncing balls. First of all, do not care how the mouse adsorption of these small dots, only do the line between the small balls. Before each drawing of the ball, judge whether the distance between it and the previous ball is less than the limit distance. If it is less than, draw a line with both of them as the endpoints. The code is as follows, and the ideas are all written in the comments:

```
const theCanvas = document.getElementById('theCanvas'),
ctx = theCanvas.getContext('2d'),
Mix = 6000; // generates the square of the limit distance of the line
//Flooding browsers with canvas
let canvas_width = theCanvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
canvas_height = theCanvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
points = [];
theCanvas.style = "position: fixed; top: 0px; left: 0px;";
//Drawing function, using requestanimationframe call to achieve animation
function draw() {
//Clear the screen
ctx.clearRect(0, 0, canvas_width, canvas_height);
let i,pi,x_dist,y_dist;
//Traversing the collection of points to draw lines
points.forEach((p, index) => {
p. X + = p.xa, // moves at the specified speed
p.y += p.ya,
p.xa *= p.x > canvas_width || p.x < 0 ? -1 : 1,
p.ya *= p.y > canvas_height || p.y < 0 ? -1 : 1,
ctx.fillRect (p.x - 0.5, p.y - 0.5, 1, 1); // draw a point, which is actually a small square
//Similar to the handshake problem, a line is drawn only once between two points
for(i = index + 1; i < points.length; i++) {
pi = points[i];
x_dist = p.x - pi.x;
y_dist = p.y - pi.y;
dist = x_dist * x_dist + y_dist * y_dist;
//Judge whether the distance between points is less than the limit distance
if(dist < mix) {
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.lineTo(pi.x, pi.y);
ctx.stroke();
}
}
}),requestAnimationFrame(draw);
}
//Randomly generate 100 points
for(let i = 0; i < 100; i++ ) {
let x = Math.random () * canvas_ Width, // initial coordinates
y = Math.random() * canvas_height,
xa = 2 * Math.random () - 1, // X speed
ya = 2 * Math.random () - 1; // y speed
points[i] = {x, y, xa, ya};
}
draw();
```

Look at the effect, ugly, different from others, very stiff. Because the line does not suddenly appear and suddenly disappear, the line between points gradually appears and then disappears. Add dynamic attributes to the line, and calculate the thickness and transparency of the line by the distance between the points. When the distance between the two points is relatively far, the line will become lighter, so it looks more comfortable.

```
for(i = index + 1; i < points.length; i++) {
pi = points[i];
x_dist = p.x - pi.x;
y_dist = p.y - pi.y;
dist = x_dist * x_dist + y_dist * y_dist;
//A parameter W is obtained from the distance between two points
w = (mix - dist) / mix;
//Judge whether the distance between points is less than the limit distance
if(dist < mix) {
ctx.beginPath();
//Set the line width and transparency according to the parameter W
ctx.lineWidth = w / 2;
ctx.strokeStyle = `rgba(110,110,110,${w + 0.2})`;
ctx.moveTo(p.x, p.y);
ctx.lineTo(pi.x, pi.y);
ctx.stroke();
}
}
```

## Add mouse event

First, add the response to the mouse. Add the mouse point when the mouse enters the browser, otherwise remove it.

```
window.onmousemove = e => {
e = e || window.event;
current_point.x = e.clientX;
current_point.y = e.clientY;
};
window.onmouseout = () => {
current_point.x = null;
current_point.y = null;
};
//Adds the mouse point to the point collection
all_points = [...random_points,current_point];
```

To achieve the effect of a mouse adsorbing particles, the idea is that when the distance between the particles and the mouse is within a certain range, add a speed towards the mouse to the particles, and the result is like the particles are adsorbed by the mouse. This is the core code of mouse adsorption effect:

```
//When the distance between the two points is less than the limit distance, a line will be generated. When the second point is the point generated by the mouse, if the particle is within the range, it will generate the speed to the mouse point to achieve the adsorption effect
dist < pi.max && (pi === current_point && dist >= pi.max / 2 && (p.x -= 0.03 * x_dist, p.y -= 0.03 * y_dist));
```

Add the mouse point and then make some adjustments to get the final code.

## Other particle effects

You can also use`canvas`

Of`getImageData`

Attribute, the image will be particle, made into a rotating map, click here to preview, the main idea is to use`getImageData`

Get the image pixel information, take a sample every other segment, draw particles with this sample, draw a picture similar to mosaic, and then add motion effect to the particles. Here is the specific code implementation.

This is the end of this blog. This is my GitHub. Welcome to visit, welcome to star.