This blog is to imitate the nest. Js implementation of a demo, from simple to complex, step by step to achieve it. Here is the preview. This is my Github, there are many other front-end demo, if you like, you can click a star, your support is my motivation.

Start with an interview question

Create a ball with a radius of 10px that moves in a straight line in a 500px by 500px square, starting in a random direction at constant speed, bouncing off a wall.

Take a look at the effect, the idea is very simple, position the ball in the square, set the speed in the xy direction, add the value of positioning the ball to the speed value in the corresponding direction for each frame of animation, when the ball is detected hitting the wall, set the speed in the corresponding direction to the opposite direction. Here is the implementation code, no canvas, but the same idea.

Try to achieve

It’s easy to draw one bouncing ball, so how do you achieve nest.js with multiple balls? Such special effects cannot be made directly with Dom, which is too performance consuming and cannot be made. At this point, the power of Canvas is revealed. Similarly, canvas is used to generate multiple bouncing balls. First of all, don’t worry about how the mouse absorbs the dots. Just connect the dots between the balls. Before each ball is drawn, determine whether the distance between it and the previous ball is less than the limit distance. If it is less than the limit distance, draw a line between the two ends. The code is as follows, and the idea is written in the comments:

const theCanvas = document.getElementById('theCanvas'), ctx = theCanvas.getContext('2d'), mix = 6000; / / will produce attachment limit distance square / / will canvas covered browser let canvas_width = theCanvas. Width = window. The 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;" ; Function draw() {// clear the screen ctx.clearRect(0, 0, canvas_width, canvas_height); let i,pi,x_dist,y_dist; / / draw lines traverse points set points. The forEach ((p, index) = > {p.x + = p.x a, / / specified speed mobile p.y + = p.y. A, p.x a * = 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); For (I = index + 1; 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; Dist < mix) {ctx.beginPath(); dist < mix; 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, y = math.random () * canvas_height, xa = 2 * math.random () -1, Math.random() - 1; Points [I] = {x, y, xa, ya}; } draw();Copy the code

Look at the effect, ugly, and other people’s different, very stiff. Because the connections don’t suddenly appear and disappear, the connections between the dots gradually appear and then gradually disappear. Add dynamic attributes to the line, using the distance between the points to calculate the thickness of the line, transparency, when the distance between the two points is relatively far the line will be lighter, so that 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; W = (mix-dist)/mix; Dist < mix) {ctx.beginPath(); dist < mix; CTX. LineWidth = w / 2; CTX. StrokeStyle = ` rgba (110110110, ${w} + 0.2) `; ctx.moveTo(p.x, p.y); ctx.lineTo(pi.x, pi.y); ctx.stroke(); }}Copy the code

Add mouse events

First add a response to the mouse. Add the mouse dot 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; }; All_points = [...random_points,current_point];Copy the code

To achieve a mouse particle adsorption effect, the idea is to add a speed to the particle towards the mouse when the distance between the particle and the mouse is within a certain range. The result is as if the particle is adsorbed by the mouse. This is a section of mouse adsorption effect of the core code:

// When the distance between two points is less than the limit distance, the line will be generated. When the second point is the mouse point, the particle will generate the speed towards the mouse point if it is within the range. Dist < pi.max && (PI === current_point && Dist >= pi.max / 2 && (p.x -= 0.03 * X_dist, P.y -= 0.03 * y_dist));Copy the code

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

Other particle effects

Click here to preview. The main idea is to use getImageData to get the information of image pixels, take a sample every other section, draw particles with this sample, and draw pictures similar to Mosaic. Then add the effect of motion to the particle can be, here is the specific code implementation.

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