1. Implementation principle of particle text
The implementation principle of particle text is: using two canvass, one is the user can not see canvas1, which is used to draw text; the other is the user can see canvas2, which is used to generate particles according to the text data drawn in canvas1.
First, in canvas1, use the following statement to draw the text to be displayed.
ctx1.font = ‘100px PingFang SC’;
ctx1.textAlign = ‘center’;
ctx1.baseline = ‘middle’;
ctx1.fillText(‘Happy New Year’,canvas1.width/2, canvas1.height/2);
Then, we use the getimagedata method of canvas API to obtain an imagedata object, which is used to describe the pixel data in the specified area of canvas. The statement is:
var imgData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height).data;
In this way, the RGBA values of all pixels in the region specified by canvas1 are stored in imgdata, which is an array. Since each pixel has four RGBA values, the length of the array is “number of pixels * 4”.
Finally, by traversing the imgdata array, we can determine which points are colored (in the middle of the text) and which points are colorless (not in the text) in canvas1, write down the positions of those colored pixels, and then generate particles and draw particles on the user visible canvas2. When traversing the imgdata array, we can judge whether the pixel is in the text according to the transparency, that is, whether the fourth element in RGBA is not 0.
In this class, each particle object has four attributes: coordinate position (x, y), radius and color; there is a method draw () to draw particles.
The HTML code is as follows.
var canvas1=document.getElementById(‘myCanvas1’);
ctx1= canvas1.getContext(‘2d’);
var canvas2=document.getElementById(‘myCanvas2’);
ctx2= canvas2.getContext(‘2d’);
canvas1.width = canvas2.width = window.innerWidth;
canvas1.height = canvas2.height = window.innerHeight;
ctx1.font = ‘100px PingFang SC’;
ctx1.textAlign = ‘center’;
ctx1.baseline = ‘middle’;
ctx1.fillText(‘Happy New Year’,canvas1.width/2, canvas1.height/2);
var imgData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height).data;
function Particle(x,y,radius,color)
{
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
}
Particle.prototype.draw= function()
{
ctx2.beginPath();
ctx2.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);
ctx2.fillStyle = this.color;
ctx2.fill();
ctx2.closePath();
}
var particles = [];
var skip =1;
for (var y = 0; y < canvas1.height; y +=skip)
{
for (var x = 0; x < canvas1.width; x += skip)
{
var opacityIndex = (x + y * canvas1.width) * 4 + 3;
if (imgData[opacityIndex] > 0)
{
var hue = Math.floor(Math.random() * 360);
var color=`hsl(${hue}, 100%, 50%)`;
particles.push(new Particle(x,y,2,color));
}
}
}
for (var particle of particles)
{
particle.draw();
}
Open the HTML file containing the HTML code in the browser, and you can see that the particle text as shown in Figure 1 is drawn in the browser window.
Figure 1 shows the particle text when skip = 1
It can be seen from Figure 1 that the particles of the text are very dense because the step skip = 1 in the program scans all the pixels in the area specified by canvas1. In fact, when the particle text is formed, it does not need to scan all the pixels pixel by pixel, and the skip value can be increased to make the final particles sparse.
For example, if the statement “skip = 1” in the program is changed to “skip = 4”, the particle text as shown in Figure 2 will be drawn in the browser window.
Figure 2 shows the particle text when skip = 4
2. Dynamic effect of particle text
After understanding the implementation principle of ordinary particle text, we can add some dynamic effects to the particles that piece together the text. From two aspects.
(1) Give the particles some random displacement to avoid looking too neat.
(2) The size of particles is generated randomly, and the initial radius of particles is randomly selected when creating particles. In addition, in order to make the radius of particles change dynamically, an attribute dynamicradius is added to represent the rendering radius of particles. It uses trigonometric function to smooth the change according to the initial radius radius of particles.
Write the following HTML code.
var canvas1=document.getElementById(‘myCanvas1’);
ctx1= canvas1.getContext(‘2d’);
var canvas2=document.getElementById(‘myCanvas2’);
ctx2= canvas2.getContext(‘2d’);
canvas1.width = canvas2.width = window.innerWidth;
canvas1.height = canvas2.height = window.innerHeight;
ctx1.font = ‘120px PingFang SC’;
ctx1.textAlign = ‘center’;
ctx1.baseline = ‘middle’;
ctx1.fillText(‘Happy New Year’,canvas1.width/2, canvas1.height/2);
var imgData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height).data;
function Particle(x,y,radius,color)
{
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.dynamicRadius = radius;
}
Particle.prototype.draw= function()
{
ctx2.beginPath();
ctx2.arc(this.x, this.y,this.dynamicRadius, 0, 2 * Math.PI, false);
ctx2.fillStyle = this.color;
ctx2.fill();
ctx2.closePath();
}
Particle.prototype.update= function()
{
this.dynamicRadius =3+2*Math.sin(new Date()/1000%1000*this.radius);
}
function random(min,max)
{
return Math.random() * ( max – min ) + min;
}
var particles = [];
var skip =4;
for (var y = 0; y < canvas1.height; y +=skip)
{
for (var x = 0; x < canvas1.width; x += skip)
{
var opacityIndex = (x + y * canvas1.width) * 4 + 3;
if (imgData[opacityIndex] > 0)
{
var hue = Math.floor(Math.random() * 360);
var color=`hsl(${hue}, 100%, 50%)`;
particles.push(new Particle(x+random(1,3),y+random(1,3),random(1,4),color));
}
}
}
for (var particle of particles)
{
particle.draw();
}
function loop()
{
requestAnimationFrame(loop);
ctx2.clearRect(0,0,canvas2.width,canvas2.height);
for (var particle of particles)
{
particle.update();
particle.draw();
}
}
loop();
Open the HTML file containing the HTML code in the browser, and you can see the dynamic effect of particle text in the browser window as shown in Figure 3.
Figure 3 – dynamic effect of particle text