preface
Hi, here is CSS and WebGL magic – Alphardex.
Recently I started playing p5.js and found that it is an interesting library to create all kinds of new and interesting effects. In this article, we will implement the mouse movement effects shown below.
Let’s get started!
The preparatory work
Click on the lower right corner of the author’s P5.js template to fork a copy
Creation began
Create a point class
To begin, let’s create the simplest point class with only two parameters: the x and y coordinates
class Point {
x: number; / / x coordinate
y: number; / / y
constructor(x: number, y: number) {
this.x = x;
this.y = y; }}Copy the code
A line of particles
We all know that two points make a line.
But what if there are more than two points? Can you determine a line? The answer, of course, is yes, as long as the points are evenly arranged in a line, will they soon look like a straight line? In fact, this partition idea is also the basic idea of many particle effects.
Create a PointLine class that represents a line made of particles
- with
dist
The delta function is going to find the distance between two pointsceil
I take the whole, that’s the number between two points - with
map
The function maps the point point to the xy coordinates of AB, yielding the coordinates of the point between two points - with
ellipse
The function represents all the points between two points
class PointLine {
s: p5;
p1: Point; / / point A
p2: Point; / / point B
thickness: number; // The thickness of the line segment
dotCount: number; // Total number of points
constructor(s: p5, p1: Point, p2: Point, thickness = 1) {
this.s = s;
this.p1 = p1;
this.p2 = p2;
this.thickness = thickness;
let dotCount = s.dist(p1.x, p1.y, p2.x, p2.y);
this.dotCount = s.ceil(dotCount);
}
draw() {
for (let i = 0; i < this.dotCount; i++) {
let x = this.s.map(i, 0.this.dotCount, this.p1.x, this.p2.x);
let y = this.s.map(i, 0.this.dotCount, this.p1.y, this.p2.y);
this.s.ellipse(x, y, this.thickness, this.thickness); }}}Copy the code
const sketch = (s: p5) = > {
const draw = () = >{... s.translate(s.width /2, s.height / 2);
const p1 = new Point(0.0);
const p2 = new Point(50.50);
const line = new PointLine(s, p1, p2, 6);
line.draw();
};
};
Copy the code
Any polygon consisting of lines
Create a PointShape class that represents any polygon consisting of lines
- Create a circle that accepts the xy coordinates and radius r
- Try to divide this circle into polygons
- The parametric equation of the circle is
X = a + rcos theta. Y = b + rsin theta.
Using this, we can calculate the coordinates of all points of the line segment
class PointShape extends PointLine {
x: number; / / x coordinate
y: number; / / y
r: number; / / radius
edgeCount: number; / / number of length
lines: PointLine[]; // Array of side lengths
constructor(
s: p5,
x: number,
y: number,
r: number,
edgeCount: number,
thickness = 1
) {
super(s, new Point(x, y), new Point(x, y), thickness);
this.x = x;
this.y = y;
this.r = r;
this.edgeCount = edgeCount;
this.lines = [];
for (let i = 0; i < this.edgeCount; i++) {
const x1 =
this.x + this.r * this.s.cos((this.s.TWO_PI * i) / this.edgeCount);
const y1 =
this.y + this.r * this.s.sin((this.s.TWO_PI * i) / this.edgeCount);
const x2 =
this.x +
this.r * this.s.cos((this.s.TWO_PI * (i + 1)) / this.edgeCount);
const y2 =
this.y +
this.r * this.s.sin((this.s.TWO_PI * (i + 1)) / this.edgeCount);
const p1 = new Point(x1, y1);
const p2 = new Point(x2, y2);
const line = new PointLine(this.s, p1, p2, thickness);
this.lines.push(line); }}draw() {
this.lines.forEach((line) = >{ line.draw(); }); }}Copy the code
const sketch = (s: p5) = > {
const draw = () = >{...const shape = new PointShape(s, 0.0.80.6.6);
shape.draw();
};
};
Copy the code
Gaussian random function
Since lines and graphs are composed of particles, we can try to make particles move. In P5. js, the commonly used random function is randomGaussian, which can add the offset generated by the function to the x and y of particles to produce the effect of random movement of particles
- Create a function that modifies the xy coordinates
- Creating a fuzzy function
blur
, add the number of points and thickness to the corresponding fuzzy value, and add the offset generated by the Gaussian random function to the X and y coordinates
class PointLine {...modifyFunc: Function; // Modify the function, which is used to modify the particle's xy coordinates
constructor(s: p5, p1: Point, p2: Point, thickness = 1){...const modifyFunc = (x: number, y: number) = > [x, y];
this.modifyFunc = modifyFunc;
}
draw() {
for (let i = 0; i < this.dotCount; i++) {
let x = this.s.map(i, 0.this.dotCount, this.p1.x, this.p2.x);
let y = this.s.map(i, 0.this.dotCount, this.p1.y, this.p2.y);
[x, y] = this.modifyFunc(x, y);
this.s.ellipse(x, y, this.thickness, this.thickness); }}blur(seed = 0, amount = 0) {
const blurPower = 1 + this.s.sq(amount);
this.dotCount *= blurPower;
const blurPower2 = 1 - amount;
this.thickness *= blurPower2;
this.modifyFunc = (x: number, y: number) = > {
x += seed * amount * this.s.randomGaussian(0.1);
y += seed * amount * this.s.randomGaussian(0.1);
return[x, y]; }; }}class PointShape extends PointLine {...blur(seed = 0, amount = 0) {
this.lines.forEach((line) = >{ line.blur(seed, amount); }); }}Copy the code
const sketch = (s: p5) = > {
const draw = () = >{...const shape = new PointShape(s, 0.0.80.6.6);
shape.blur(10.0.5);
shape.draw();
};
};
Copy the code
Follow the mouse
- Create an array to hold the coordinates of the mouse and set an upper limit (12 in this case).
- Each time you draw, you add the current mouse coordinates, and if you exceed the limit, you delete the previously added coordinates
- Draws the graph based on the current mouse coordinates
const sketch = (s: p5) = > {
let mousePositions: Point[] = [];
const maxPos = 12; .const draw = () = >{...// s.translate(s.width / 2, s.height / 2);
const mousePos = new Point(s.mouseX, s.mouseY);
mousePositions.unshift(mousePos);
if (mousePositions.length > maxPos) {
mousePositions.pop();
}
mousePositions.forEach((pos, i) = > {
const ratio = i / mousePositions.length;
const shape = new PointShape(s, pos.x, pos.y, 80.6.6);
shape.blur(10, ratio);
shape.draw();
});
};
};
Copy the code
Showing up!
- application
HSB
Color mode and fill each figure with a different color - application
ADD
Mix mode to create a dazzling effect
const sketch = (s: p5) = >{...const setup = () = >{... s.colorMode(s.HSB,1);
};
const draw = () = >{... mousePositions.forEach((pos, i) = > {
s.blendMode(s.ADD);
const ratio = i / mousePositions.length;
s.fill(0.5 + ratio, 0.7.0.25);
const shape = new PointShape(s, pos.x, pos.y, 80.6.6);
shape.blur(10, ratio);
shape.draw();
s.blendMode(s.BLEND);
});
};
};
Copy the code
The project address
Blur Particle Trail