Home>

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

  • Previous JQuery to achieve picture carousel effect
  • Next HTML5 + canvas implementation of touch-screen signature plugin tutorial