Step by step realization of nest particle effect

Time:2020-10-13

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

  this blog is imitation nest.js Implement ademoFrom simple to complex, step by step. Here is the preview of the effect. There are many other front-end ones in my GitHubdemoYou can order it if you likestarYour support is my motivation.

Start with an interview question

Realize a radius10pxThe ball of500px*500pxThe 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, settingxySpeed 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 usedcanvasBut the ideas are the same.

Try to implement

                     nest.js What about the effect. It’s not going to workDomIf you do it directly, it will cost too much performance and can’t do it. This will showcanvasThe power of.
In the same waycanvasGenerate 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 usecanvasOfgetImageDataAttribute, the image will be particle, made into a rotating map, click here to preview, the main idea is to usegetImageDataGet 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.

Recommended Today

Summary of recent use of gin

Recently, a new project is developed by using gin. Some problems are encountered in the process. To sum up, as a note, I hope it can help you. Cross domain problems Middleware: func Cors() gin.HandlerFunc { return func(c *gin.Context) { //Here you can use * or the domain name you specify c.Header(“Access-Control-Allow-Origin”, “*”) //Allow header […]