Canvas particle wire dynamic effect
This effect itself is an effect I wrote two years ago in a boring way, the effect is ok, these two days on a whim, continue to learn canvas, posted to share.
Effects and front-end code: www.jq22.com/webqd5641
Wasm implementation: github.com/kiliaosi/wa…
The WASM implementation uses the Rust language, which is very slippery
Brief description of main logic
The so-called particle line dynamic effect, after understanding the general idea, the realization process is actually very simple. Can be decomposed into the following steps to achieve
-
Prepare a blank canvas.
-
Distribute a number of circular shapes to random locations on the canvas.
-
Give the ball the initial direction of movement (x and Y) and the speed in the axis (for simplicity, the speed here does not change throughout the program cycle).
-
Use setInterval or requestAnimationFrame (recommended) for animation.
-
Collision detection on the four sides of the browser (after the collision, the ball needs to change the direction of movement to prevent the ball from moving out of the canvas).
After the above steps, the reader should be able to implement a simple wireless bar particle dynamic effect.
-
Particles in the attachment
- The realization of the line logic is also relatively simple, is to calculate the current ball and other balls in the rectangular coordinate system of a distance (need to use trigonometric function), the distance within the limit of the ball line, line color using RGBA color, so that will achieve the distance of the line transparency is different.
The first stage prepares a canvas and initializes it
-
Create a directory and create index.html and canvas.js files
-
HTML original source code
All you need for the HTML section is the following code and there will be no further changes
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
<title>Document</title>
</head>
<body>
<canvas id="myCanvas" width=""></canvas>
<script src="./canvas.js"></script>
</body>
</html>
Copy the code
- js
Js initial source code is as follows
- Get canvas tag
- Initialize the width and height of the canvas
- Get canvas Context (brush)
// Get the canvas tag
let canvas = document.getElementById("myCanvas");
// Initialize the width of the canvas according to the width of the browser window, and save the width of the browser (mainly for later use in collision detection on the browser edge)
let width = (canvas.width = window.innerWidth);
let height = (canvas.height = window.innerHeight);
// Get canvas context (brush)
let ctx = canvas.getContext("2d");
Copy the code
Tool function
Because you need to generate random positions and speeds in the canvas, you need some utility functions, which are implemented using math.ramdom.
- The main function of ramdom is to generate a random number in a given range of functions.
- The main function of the randomColor function is to use the random function to generate a random color.
function random(min, max) {
let num = Math.floor(Math.random() * (max - min) + min);
if (num === 0) {
num = 1;
}
return num;
}
// Generate color randomly (RGB)
function randomColor() {
return `rgb(${random(0.255)}.${random(0.255)}.${random(0.255)}) `;
}
Copy the code
Implement small ball
/ * * *@param {number} X star@param {number} Y star@param {number} The velocity of vx along the horizontal axis (can be negative) *@param {number} Vy the velocity along the vertical axis (can be negative) *@param {number} Size Radius of the ball *@param {string} * color color@param {string} Line Line color * */
function Ball(x, y, vx, vy, size, color, line) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.size = size;
(this.color = color), (this.lineColor = line);
}
Copy the code
Method to draw the current ball object
The following API is the standard CANVAS API, which will not be described here. The main work of this method is to draw a Ball on the canvas according to the parameters passed in by the Ball constructor
Ball.prototype.draw = function () {
// Start drawing (path)
ctx.beginPath();
// Set the fill color of the brush
ctx.fillStyle = this.color;
// Draw the ball according to the coordinates
ctx.arc(this.x, this.y, this.size, 0.2 * Math.PI);
/ / fill
ctx.fill();
};
Copy the code
Update the state of the ball and get it moving
After setting the ball’s initial position and speed in both directions, the ball’s position needs to be periodically updated and redrawn.
Ball.prototype.update = function () {
// Check whether the current ball's X coordinate plus the current ball radius is larger than the browser width (right edge collision detection)
// Check whether the current ball's X coordinate plus the current ball radius is less than 0 (left edge collision detection)
// If either of the above two conditions is met, the direction should be reversed (X-axis speed vx is set to the negative of the current vx).
if (this.x + this.size >= width || this.x - this.size <= 0) {
this.vx = -this.vx;
}
// Check whether the current ball's Y coordinate plus the current ball radius is greater than the browser height (bottom edge collision detection)
// Check whether the current ball's Y coordinate plus the current ball radius is less than 0 (upper edge collision detection)
// If either of the above two conditions is met, the direction should be reversed (Y velocity vy is set to the negative of vy).
if (this.y + this.size >= height || this.y - this.size <= 0) {
this.vy = -this.vy;
}
// Change the coordinates of the ball according to the speed value
this.x += this.vx;
this.y += this.vy;
};
Copy the code
Generates a list of ball objects
Generate a certain number of balls, coordinates randomly generated, line color randomly generated (rGBA string here is incomplete, the rest of the calculation is completed later)
The number of balls here is hard-coded at 90, and the reader is free to change
let list = [];
for (let i = 0; i <= 90; i++) {
let circle = new Ball(
random(0, width),
random(0, height),
random(-6.6) * (1 / 3.0),
random(-6.6) * (1 / 3.0),
3."RGB (255255255)".`rgba(${random(0.255)}.${random(0.255)}.${random(0.255)}`
);
list.push(circle);
}
Copy the code
Circulation function
The above steps only generate a series of balls in the array, not on the canvas, so we need a utility function to draw many balls, and periodically call draw and update methods to make the balls move. And at the same time we need to draw lines
function loopCircle() {
// Refresh the canvas
ctx.fillStyle = "Rgba (0,0,0,0.6)";
ctx.fillRect(0.0, width, height);
// Double loop
// This is mainly used to calculate a two-dimensional space distance between the balls, the performance is not high, there is a large space for optimization, readers can be interested in their own optimization
for (let i = 0; i < list.length; i++) {
for (let j = 0; j < list.length; j++) {
// Calculate the current ball distance
let lx = list[j].x - list[i].x;
let ly = list[j].y - list[i].y;
let LL = Math.sqrt(Math.pow(lx, 2) + Math.pow(ly, 2));
// Comparison: When the distance is satisfied, draw a line, using RGBA to achieve the transition
if (LL <= 180) {
ctx.beginPath();
// Here to complement the front half of the RGBA line color
ctx.strokeStyle = `${list[i].lineColor}.The ${(180 - LL) / 180}) `;
// Draw lines
ctx.moveTo(list[i].x, list[i].y);
ctx.lineWidth = 1; ctx.lineTo(list[j].x, list[j].y); ctx.stroke(); }}// Draw the ball
list[i].draw();
// Update the coordinates
list[i].update();
}
// Execute the animation (once the function itself is passed here, the callback will be executed again before the browser's next redraw)
requestAnimationFrame(loopCircle);
}
Copy the code
Began to run
Manually call loopCircle once
loopCircle();
Copy the code
conclusion
After the above steps, you can see the following screen:
This is just a simple effect, the Canvas API itself is relatively simple, but through these simple apis we can draw a lot of complex animation, very interesting!
Other works
Another simple effect I’ve implemented before is to follow the mouse over; I won’t go into details here;
Effect address: www.jq22.com/webqd5694
Wasm implementation: github.com/kiliaosi/wa…