SoFunction
Updated on 2025-02-28

Detailed explanation of the construction of the canvas particle system

The previous words

This article will explain the theoretical knowledge of the most basic imageData object, and introduce in detail the construction of the canvas particle system.

imageData

There are 3 methods about imageData, including getImageData(), putImageData(), and createImageData().

【getImageData()】

The 2D context can obtain the original image data through getImageData(). This method receives 4 parameters: the x and y coordinates of the picture area and the pixel width and height of the area

For example, to obtain image data of an area with a coordinate of (10,5) in the upper left corner and a size of 50*50 pixels, you can use the following code:

var imageData = (10,5,50,50);

The returned object is an instance of ImageData. Each ImageData object has 3 properties: width\height\data

1. width: represents the width of the diagonal of imageData

2. height: represents the height of the imageData object

3. Data is an array that stores the data of each pixel in the image. In the data array, each pixel is saved with 4 elements, indicating red, green, blue, and transparency, respectively

[Note] How many pixels are there in the image, the length of data is equal to the number of pixels multiplied by 4

//The first pixel is as followsvar data = ;
var red = data[0];
var green = data[1]; 
var blue = data[2];
var alpha = data[3];

The value of each element in the array is between 0 and 255. You can directly access the original image data and operate this data in various ways.

[Note] If the canvas you want to use getImageData() to include the drawImage() method, the URL in the method cannot cross-domain

【createImageData()】

The createImageData(width,height) method creates a new blank ImageData object. The default pixel value of the new object is transparent black, equivalent to rgba(0,0,0,0)

var imgData = (100,100);

【putImageData()】

putImageData() method puts image data back on the canvas from the specified ImageData object. This method has the following parameters

imgData:To be put back to the canvasImageDataObject(must)
x:imageDataObject的左上角的xcoordinate(must)
y:imageDataObject的左上角的ycoordinate(must)
dirtyX:Horizontal position of placing an image on the canvas(Optional)
dirtyY:Vertical position of placing an image on the canvas(Optional)
dirtyWidth:The width used to draw an image on the canvas(Optional)
dirtyHeight:The height used to draw an image on the canvas(Optional)

[Note] Parameters 3 to 7 are either none or they all exist

(imgData,0,0);
(imgData,0,0,50,50,200,200);

Particle writing

Particle refers to each pixel point in the image data imageData. The following is a simple example to illustrate complete write and particle write

【Full write】

The text 'Little Match' exists in canvas1 of 200*200, and the entire canvas1 is written as image data into canvas2 of the same size

<canvas  style="border:1px solid black"></canvas>
<canvas  style="border:1px solid black"></canvas>
<script>
var drawing1 = ('drawing1');
var drawing2 = ('drawing2');
if(){
 var cxt = ('2d');
 var cxt2 = ('2d');
 var W =  =  = 200;
 var H =  =  = 200;
 var str = 'Little Match';
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 (str,(W - sw)/2,(H - sh)/2,W);
 //Get imageData var imageData = (0,0,W,H); 
 //Write into drawing2 (imageData,0,0);
</script>

【Particle writing】

For full write, it is equivalent to just a simple copy-paste. If you want to finely control each pixel, you need to use particle writing. There are a large number of blank areas in canvas1, and only the three words "Little Match" are valid. Therefore, particles can be screened according to the transparency in image data imageData, and only particles with transparency greater than 0 can be screened out.

<canvas  style="border:1px solid black"></canvas>
<canvas  style="border:1px solid black"></canvas>
<script>
var drawing1 = ('drawing1');
var drawing2 = ('drawing2');
if(){
 var cxt = ('2d');
 var cxt2 = ('2d');
 var W =  =  = 200;
 var H =  =  = 200;
 var str = 'Little Match';
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 (str,(W - sw)/2,(H - sh)/2,W);
 //Get imageData var imageData = (0,0,W,H); 
 //Write into drawing2 (setData(imageData),0,0);
 function setData(imageData){
 //Get particles from imageData object and store them in dots array var dots = [];
 for(var i = 0; i < W; i++){
  for(var j = 0; j < H ;j++){
  //The red value in the data value  var k = 4*(i + j*W);
  //Transparency in data value  if([k+3] > 0){
   //Save the red value in data with transparency greater than 0 to the dots array   (k);
  }
  }
 }
 //40000 2336
 (i*j,);
 // Create a new imageData and save the filtered particle information to the newly created imageData var oNewImage = (W,H);
 for(var i = 0; i < ; i++){
  [dots[i]+0] = [dots[i]+0];
  [dots[i]+1] = [dots[i]+1];
  [dots[i]+2] = [dots[i]+2];
  [dots[i]+3] = [dots[i]+3];
 }
 return oNewImage;
 }
}
</script>

Although the results look the same, canvas2 uses only 2336 of the 40,000 particles in canvas1

Particle screening

When particles are fully written, the same effect as canvas copy-paste. And when particles are screened, some wonderful effects will appear

【Filter in order】

Since when obtaining particles, a double cycle of width value*height value is used, and they are all incremented by adding 1. If you do not add 1, but add n, you can achieve the effect of orderly filtering

<canvas  style="border:1px solid black"></canvas>
<canvas  style="border:1px solid black"></canvas>
<div >
 <button>1</button>
 <button>2</button>
 <button>3</button>
 <button>4</button>
 <button>5</button>
</div>
<script>
var oCon = ('con');
 = function(e){
 e = e || event;
 var tempN = ;
 if(tempN){
 (0,0,W,H);
 (setData(imageData,Number(tempN)),0,0);
 }
}
var drawing1 = ('drawing1');
var drawing2 = ('drawing2');
if(){
 var cxt = ('2d');
 var cxt2 = ('2d');
 var W =  =  = 200;
 var H =  =  = 200;
 var str = 'Little Match';
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 (str,(W - sw)/2,(H - sh)/2,W);
 //Get imageData var imageData = (0,0,W,H); 
 //Write into drawing2 (setData(imageData,1),0,0);
 function setData(imageData,n){
 //Get particles from imageData object and store them in dots array var dots = [];
 for(var i = 0; i < W; i+=n){
  for(var j = 0; j < H ;j+=n){
  //The red value in the data value  var k = 4*(i + j*W);
  //Transparency in data value  if([k+3] > 0){
   //Save the red value in data with transparency greater than 0 to the dots array   (k);
  }
  }
 }
 // Create a new imageData and save the filtered particle information to the newly created imageData var oNewImage = (W,H);
 for(var i = 0; i < ; i++){
  [dots[i]+0] = [dots[i]+0];
  [dots[i]+1] = [dots[i]+1];
  [dots[i]+2] = [dots[i]+2];
  [dots[i]+3] = [dots[i]+3];
 }
 return oNewImage;
 }
}
</script>

【Random Filter】

In addition to using orderly filtering, you can also use random filtering. The position information of the particles obtained through double loop is placed in the dots array. Filter through the splice() method, put the filtered location information into the newly created newDots array, and then use createImageData() to create a new image data object and return

<canvas  style="border:1px solid black"></canvas>
<canvas  style="border:1px solid black"></canvas>
<div >
 <button>1000</button>
 <button>2000</button>
 <button>3000</button>
 <button>4000</button>
</div>
<script>
var oCon = ('con');
 = function(e){
 e = e || event;
 var tempN = ;
 if(tempN){
 (0,0,W,H);
 (setData(imageData,1,Number(tempN)),0,0);
 }
}
var drawing1 = ('drawing1');
var drawing2 = ('drawing2');
if(){
 var cxt = ('2d');
 var cxt2 = ('2d');
 var W =  =  = 200;
 var H =  =  = 200;
 var str = 'Little Match';
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 (str,(W - sw)/2,(H - sh)/2,W);
 //Get imageData var imageData = (0,0,W,H); 
 //Write into drawing2 (setData(imageData,1),0,0);
 function setData(imageData,n,m){
 //Get particles from imageData object and store them in dots array var dots = [];
 for(var i = 0; i < W; i+=n){
  for(var j = 0; j < H ;j+=n){
  //The red value in the data value  var k = 4*(i + j*W);
  //Transparency in data value  if([k+3] > 0){
   //Save the red value in data with transparency greater than 0 to the dots array   (k);
  }
  }
 } 
 //Filter particles and save only m into the newDots array.  If m is not passed, no filtering is performed var newDots = [];
 if(m && ( > m)){
  for(var i = 0; i < m; i++){
  (Number(((()*),1)));
  }
 }else{
  newDots = dots;
 } 
 // Create a new imageData and save the filtered particle information to the newly created imageData var oNewImage = (W,H);
 for(var i = 0; i < ; i++){
  [newDots[i]+0] = [newDots[i]+0];
  [newDots[i]+1] = [newDots[i]+1];
  [newDots[i]+2] = [newDots[i]+2];
  [newDots[i]+3] = [newDots[i]+3];
 }
 return oNewImage;
 }
}
</script>

Pixel word display

The following is to use particle filtering to achieve the effect of displaying words in a pixel. Pixel word display means gradually transitioning from unclear effects to full display

【Show words in order pixels】

The implementation principle of word display in sequence is very simple. For example, there are 2,000 particles in total, and there are 10 degree transition effects. Then use 10 arrays to save 200, 400, 600, 800, 100, 1200, 1400, 1600, 1800 and 2000 particles respectively. Then use the timer to display it step by step

<canvas  style="border:1px solid black"></canvas>
<button >Start showing the words</button>
<script>
var drawing1 = ('drawing1');
if(){
 var cxt = ('2d');
 var W =  = 200;
 var H =  = 200;
 var str = 'Little Match';
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 (str,(W - sw)/2,(H - sh)/2,W);
 //Get imageData var imageData = (0,0,W,H); 
 (0,0,W,H);
 //Get 10 groups of particles var imageDataArr = [];
 var n = 10;
 var index = 0;
 for(var i = n; i > 0; i--){
 (setData(imageData,i));
 }
 var oTimer = null;
  = function(){
 clearTimeout(oTimer);
 showData();
 }
 function showData(){
 oTimer = setTimeout(function(){
  (0,0,W,H);
  //Write to draw1  (imageDataArr[index++],0,0); 
  //Iteration function  showData();  
  if(index == 10){
  index = 0;
  clearTimeout(oTimer);
  }  

 },100);  
 } 
 function setData(imageData,n,m){
 //Get particles from imageData object and store them in dots array var dots = [];
 for(var i = 0; i < W; i+=n){
  for(var j = 0; j < H ;j+=n){
  //The red value in the data value  var k = 4*(i + j*W);
  //Transparency in data value  if([k+3] > 0){
   //Save the red value in data with transparency greater than 0 to the dots array   (k);
  }
  }
 } 
 //Filter particles and save only m into the newDots array.  If m is not passed, no filtering is performed var newDots = [];
 if(m && ( > m)){
  for(var i = 0; i < m; i++){
  (Number(((()*),1)));
  }
 }else{
  newDots = dots;
 } 
 // Create a new imageData and save the filtered particle information to the newly created imageData var oNewImage = (W,H);
 for(var i = 0; i < ; i++){
  [newDots[i]+0] = [newDots[i]+0];
  [newDots[i]+1] = [newDots[i]+1];
  [newDots[i]+2] = [newDots[i]+2];
  [newDots[i]+3] = [newDots[i]+3];
 }
 return oNewImage;
 }
}
</script>

【Random pixels to display words】

The principle of random pixel word display is similar. Just save multiple arrays of different numbers of random pixels.

<canvas  style="border:1px solid black"></canvas>
<button >Start showing the words</button>
<script>
var drawing1 = ('drawing1');
if(){
 var cxt = ('2d');
 var W =  = 200;
 var H =  = 200;
 var str = 'Little Match';
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 (str,(W - sw)/2,(H - sh)/2,W);
 //Get imageData var imageData = (0,0,W,H); 
 (0,0,W,H);
 //Get 10 groups of particles var imageDataArr = [];
 var n = 10;
 var index = 0;
 for(var i = n; i > 0; i--){
 (setData(imageData,1,i));
 }
 var oTimer = null;
  = function(){
 clearTimeout(oTimer);
 showData();
 }
 function showData(){
 oTimer = setTimeout(function(){
  (0,0,W,H);
  //Write to draw1  (imageDataArr[index++],0,0); 
  //Iteration function  showData();  
  if(index == 10){
  clearTimeout(oTimer);
  index = 0;
  }  
 },100);  
 } 
 function setData(imageData,n,m){
 //Get particles from imageData object and store them in dots array var dots = [];
 for(var i = 0; i < W; i+=n){
  for(var j = 0; j < H ;j+=n){
  //The red value in the data value  var k = 4*(i + j*W);
  //Transparency in data value  if([k+3] > 0){
   //Save the red value in data with transparency greater than 0 to the dots array   (k);
  }
  }
 } 
 //Filter particles and save only /m into newDots array var newDots = [];
 var len = (/m);
 for(var i = 0; i < len; i++){
  (Number(((()*),1)));
 }
 // Create a new imageData and save the filtered particle information to the newly created imageData var oNewImage = (W,H);
 for(var i = 0; i < ; i++){
  [newDots[i]+0] = [newDots[i]+0];
  [newDots[i]+1] = [newDots[i]+1];
  [newDots[i]+2] = [newDots[i]+2];
  [newDots[i]+3] = [newDots[i]+3];
 }
 return oNewImage;
 }
}
</script>

Particle animation

Particle animation is not animating particles, but the small squares drawn by fillRect() are moving after obtaining the random coordinates and final coordinates of the particles through the getImageData() method. Use timers to continuously draw small squares with changing coordinates to produce the effect of motion

【Random Position】

<canvas  style="border:1px solid black"></canvas>
<button >Start showing the words</button>
<button >Re-chaos</button>
<script>
var drawing1 = ('drawing1');
if(){
 var cxt = ('2d');
 var W =  = 200;
 var H =  = 200;
 var str = 'Little Match';
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 (str,(W - sw)/2,(H - sh)/2,W);
 //Get imageData var imageData = (0,0,W,H); 
 (0,0,W,H);
 function setData(imageData,n,m){
 //Get particles from imageData object and store them in dots array var dots = [];
 //dots index var index = 0;
 for(var i = 0; i < W; i+=n){
  for(var j = 0; j < H ;j+=n){
  //The red value in the data value  var k = 4*(i + j*W);
  //Transparency in data value  if([k+3] > 0){
   //Save the red value in data with transparency greater than 0 to the dots array   (k);
   dots[index++] = {
   'index':index,
   'x':i,
   'y':j,
   'red':k,
   'randomX':()*W,
   'randomY':()*H,
   }
  }
  }
 } 
 //Filter particles and save only /m into newDots array var newDots = [];
 var len = (/m);
 for(var i = 0; i < len; i++){
  (((()*),1)[0]);
 }
 return newDots;
 }
 //Get the particle array var dataArr = setData(imageData,1,1);
 var oTimer1 = null;
 var oTimer2 = null;
  = function(){
 clearTimeout(oTimer1);
 showData(10);
 } 
  = function(){
 clearTimeout(oTimer2);
 showRandom(10);
 } 
 function showData(n){
 oTimer1 = setTimeout(function(){
  (0,0,W,H);
  for(var i = 0; i < ; i++){
  var temp = dataArr[i];
  var x0 = ;
  var y0 = ;
  var disX =  - ;
  var disY =  - ;
  (x0 + disX/n,y0 + disY/n,1,1); 
  } 
  showData(n-1); 
  if(n === 1){
  clearTimeout(oTimer1);
  }  
 },60); 
 } 
 function showRandom(n){
 oTimer2 = setTimeout(function fn(){
  (0,0,W,H);
  for(var i = 0; i < ; i++){
  var temp = dataArr[i];
  var x0 = ;
  var y0 = ;
  var disX =  - ;
  var disY =  - ;
  (x0 + disX/n,y0 + disY/n,1,1);    
  }  
  showRandom(n-1); 
  if(n === 1){
  clearTimeout(oTimer2);
  }  
 },60); 
 } 
}
</script>

【Floating in effect】

The floating effect is similar to the principle of randomly showing characters, so I won't go into details

<canvas  style="border:1px solid black"></canvas>
<button >Floating into the upper left corner</button>
<script>
var drawing1 = ('drawing1');
if(){
 var cxt = ('2d');
 var W =  = 200;
 var H =  = 200;
 var str = 'Little Match';
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 (str,(W - sw)/2,(H - sh)/2,W);
 //Get imageData var imageData = (0,0,W,H); 
 (0,0,W,H);
 function setData(imageData,n,m){
 //Get particles from imageData object and store them in dots array var dots = [];
 //dots index var index = 0;
 for(var i = 0; i < W; i+=n){
  for(var j = 0; j < H ;j+=n){
  //The red value in the data value  var k = 4*(i + j*W);
  //Transparency in data value  if([k+3] > 0){
   //Save the red value in data with transparency greater than 0 to the dots array   (k);
   dots[index++] = {
   'index':index,
   'x':i,
   'y':j,
   'red':k,
   'randomX':()*W,
   'randomY':()*H,
   }
  }
  }
 } 
 //Filter particles and save only /m into newDots array var newDots = [];
 var len = (/m);
 for(var i = 0; i < len; i++){
  (((()*),1)[0]);
 }
 return newDots;
 }
 //Get the particle array var dataArr = setData(imageData,1,1);
 var oTimer1 = null;
  = function(){
 clearTimeout(oTimer1);
 showData(10);
 } 
 function showData(n){
 oTimer1 = setTimeout(function(){
  (0,0,W,H);
  for(var i = 0; i < ; i++){
  var temp = dataArr[i];
  var x0 = 0;
  var y0 = 0;
  var disX =  - 0;
  var disY =  - 0;
  (x0 + disX/n,y0 + disY/n,1,1); 
  } 
  showData(n-1); 
  if(n === 1){
  clearTimeout(oTimer1);
  }  
 },60); 
 } 
}
</script>

Mouse interaction

Generally, the mouse interaction of particles is related to the isPointInPath(x,y) method

【Move in and change color】

When the mouse approaches the particle, the particle turns red. The implementation principle is very simple. When the mouse moves, it isPointInPath(x,y) method to detect which particles are within the current pointer range. If in, draw a 1-pixel red rectangle

<canvas  style="border:1px solid black"></canvas>
<script>
var drawing1 = ('drawing1');
if(){
 var cxt = ('2d');
 var W =  = 200;
 var H =  = 200;
 var str = 'Little Match';
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 (str,(W - sw)/2,(H - sh)/2,W);
 //Get imageData var imageData = (0,0,W,H); 
 function setData(imageData,n,m){
 //Get particles from imageData object and store them in dots array var dots = [];
 //dots index var index = 0;
 for(var i = 0; i < W; i+=n){
  for(var j = 0; j < H ;j+=n){
  //The red value in the data value  var k = 4*(i + j*W);
  //Transparency in data value  if([k+3] > 0){
   //Save the red value in data with transparency greater than 0 to the dots array   (k);
   dots[index++] = {
   'index':index,
   'x':i,
   'y':j,
   'red':k,
   'randomX':()*W,
   'randomY':()*H,
   }
  }
  }
 } 
 //Filter particles and save only /m into newDots array var newDots = [];
 var len = (/m);
 for(var i = 0; i < len; i++){
  (((()*),1)[0]);
 }
 return newDots;
 }
 //Get the particle array var dataArr = setData(imageData,1,1); 
 //When the mouse moves, when the particle distance from the mouse pointer is less than 10, the relevant operation will be performed  = function(e){
 e = e || event;
 var x =  - ().left;
 var y =  - ().top;
 ();
 (x,y,10,0,*2);
 for(var i = 0; i < ; i++){
  var temp = dataArr[i];
  if((,)){ 
   = 'red';
  (,,1,1);
  }  
 } 
 }
}
</script>

【stay away from the mouse】

When clicking the mouse, particles within a certain range with the mouse pointer as the center of the circle need to move outside this range. After a while, the particles return to their original position

The implementation principle is not complicated. Use isPointInPath(x,y) method. If the particle is in the current path, move to the edge of the path along the straight line composed of the mouse pointer and the particle coordinates.

<canvas  style="border:1px solid black"></canvas>
<script>
var drawing1 = ('drawing1');
if(){
 var cxt = ('2d');
 var W =  = 200;
 var H =  = 200;
 var str = 'Little Match';
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 // Render text (str,(W - sw)/2,(H - sh)/2,W);
 //Get imageData var imageData = (0,0,W,H); 
 (0,0,W,H);
 function setData(imageData,n,m){
 //Get particles from imageData object and store them in dots array var dots = [];
 //dots index var index = 0;
 for(var i = 0; i < W; i+=n){
  for(var j = 0; j < H ;j+=n){
  //The red value in the data value  var k = 4*(i + j*W);
  //Transparency in data value  if([k+3] > 0){
   //Save the red value in data with transparency greater than 0 to the dots array   (k);
   dots[index++] = {
   'index':index,
   'x':i,
   'y':j,
   'red':k,
   'randomX':()*W,
   'randomY':()*H,
   'mark':false
   }
  }
  }
 } 
 //Filter particles and save only /m into newDots array var newDots = [];
 var len = (/m);
 for(var i = 0; i < len; i++){
  (((()*),1)[0]);
 }
 return newDots;
 }
 //Get the particle array var dataArr = setData(imageData,2,1); 
 //Save the filtered particle information to the newly created imageData var oNewImage = (W,H);
 for(var i = 0; i < ; i++){
 for(var j = 0; j < 4; j++){
  [dataArr[i].red+j] = [dataArr[i].red+j];
 }
 } 
 //Write into canvas (oNewImage,0,0);
 //Set the mouse detection radius to r var r = 20;
 //When the mouse moves, when the particle distance from the mouse pointer is less than 20, the relevant operation will be performed  = function(e){
 e = e || event;
 var x =  - ().left;
 var y =  - ().top;
 ();
 (x,y,r,0,*2);
 for(var i = 0; i < ; i++){
  var temp = dataArr[i];
  if((,)){ 
   = true;
  var angle = Math.atan2(( - y),( - x));
   = x - r*(angle);
   = y - r*(angle);
  var disX =  - ;
  var disY =  - ;
   = '#fff';
  (,,1,1);
   = '#000';
  (,,1,1); 
  dataRecovery(10);
  }else{
   = false;
  }  
 }
 var oTimer = null;
 function dataRecovery(n){
  clearTimeout(oTimer);
  oTimer = setTimeout(function(){
  (0,0,W,H);
  for(var i = 0; i < ; i++){
   var temp = dataArr[i];
   if(){
   var x0 = ;
   var y0 = ;
   var disX =  - x0;
   var disY =  - y0;
   (x0 + disX/n,y0 + disY/n,1,1); 
   }else{
   (,,1,1);
   }
  } 
  dataRecovery(n-1); 
  if(n === 1){
   clearTimeout(oTimer);
  }  
  },17);
 } 
 } 
}
</script>

Comprehensive examples

The above effect is made as an editable comprehensive example

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
</head>
<body>
<canvas  style="border:1px solid black"></canvas>
<br>
<div style="margin-bottom:10px">
 <span>Particle settings:</span>
 <input type="text"  value="Little Match's Blue Ideal"> 
 <button >Text settings confirmation</button>
 <button >Filter in order</button>
 <button >Random filtering</button>
 <button >No filtering</button> 
</div>
<div style="margin-bottom:10px">
 <span>Particle effect:</span>
 <button >Show words in order</button>
 <button >Randomly displayed words</button> 
 <button >Chaotic aggregation</button>
 <button >Re-chaos</button>
</div>
<div>
 <span>Mouse effect:</span>
 <span>1、When the mouse is moved to the text,Text color turns red;</span>
 <span>2、When the mouse clicks on the text,Particles away from mouse pointer</span>
</div>
<script>
if(){
 var cxt = ('2d');
 var W =  = 300;
 var H =  = 200; 
 var imageData;
 var dataArr;
  = function(){
 fnSetText();
 } 
 function fnSetText(str){
 (0,0,W,H);
  = 'top';
 var sh = 60;
  = sh + 'px singular'
 var sw = (str).width;
 if(sw > W){
  sw = W;
 }
 (str,(W - sw)/2,(H - sh)/2,W); 
 imageData = (0,0,W,H); 
 dataArr = setData(imageData,1,1); 
 }
 fnSetText('Little Match');
  = function(){
 dataArr = setData(imageData,1,1);
 saveData(dataArr); 
 }
  = function(){
 dataArr = setData(imageData,2,1);
 saveData(dataArr); 
 }
  = function(){
 dataArr = setData(imageData,1,2);
 saveData(dataArr); 
 } 
 //Filter particles function setData(imageData,n,m){
 //Get particles from imageData object and store them in dots array var dots = [];
 //dots index var index = 0;
 for(var i = 0; i < W; i+=n){
  for(var j = 0; j < H ;j+=n){
  //The red value in the data value  var k = 4*(i + j*W);
  //Transparency in data value  if([k+3] > 0){
   //Save the red value in data with transparency greater than 0 to the dots array   (k);
   dots[index++] = {
   'index':index,
   'x':i,
   'y':j,
   'red':k,
   'green':k+1,
   'blue':k+2,
   'randomX':()*W,
   'randomY':()*H,
   'mark':false
   }
  }
  }
 } 
 //Filter particles and save only /m into newDots array var newDots = [];
 var len = (/m);
 for(var i = 0; i < len; i++){
  (((()*),1)[0]);
 }
 return newDots;
 }
 function saveData(dataArr){
 //Save the filtered particle information to the newly created imageData var oNewImage = (W,H);
 for(var i = 0; i < ; i++){
  for(var j = 0; j < 4; j++){
  [dataArr[i].red+j] = [dataArr[i].red+j];
  }
 }
 //Write into canvas (oNewImage,0,0);  
 }
 //Show particles function showData(arr,oTimer,index,n){
 oTimer = setTimeout(function(){
  (0,0,W,H);
  //Write into canvas  saveData(arr[index++]); 
  if(index == n){
  clearTimeout(oTimer);
  }else{
  //Iteration function  showData(arr,oTimer,index,n);   
  }      
 },60);  
 } 
 //Regain chaos function showDataToRandom(dataArr,oTimer,n){
 oTimer = setTimeout(function fn(){
  (0,0,W,H);
  for(var i = 0; i < ; i++){
  var temp = dataArr[i];
  var x0 = ;
  var y0 = ;
  var disX =  - ;
  var disY =  - ;
  (x0 + disX/n,y0 + disY/n,1,1);    
  } 
  n--;
  if(n === 0){
  clearTimeout(oTimer);
  }else{
  showDataToRandom(dataArr,oTimer,n); 
  }    
 },60); 
 } 
 //Chaos Aggregation function showRandomToData(dataArr,oTimer,n){
 oTimer = setTimeout(function(){
  (0,0,W,H);
  for(var i = 0; i < ; i++){
  var temp = dataArr[i];
  var x0 = ;
  var y0 = ;
  var disX =  - ;
  var disY =  - ;
  (x0 + disX/n,y0 + disY/n,1,1); 
  } 
  n--;
  if(n === 0){
  clearTimeout(oTimer);
  }else{
  showRandomToData(dataArr,oTimer,n); 
  }  
 },60); 
 }
  = function(){
  = [];
 for(var i = 10; i > 1; i--){
  (setData(imageData,i,1));
 }
 showData(,,0,9);
 }
  = function(){
  = [];
 for(var i = 10; i > 0; i--){
  (setData(imageData,2,i));
 }
 showData(,,0,10);
 } 
  = function(){
 clearTimeout();
 showRandomToData(dataArr,,10);
 }
  = function(){
 clearTimeout();
 showDataToRandom(dataArr,,10);
 } 
 //Mouse Move  = function(e){
 e = e || event;
 var x =  - ().left;
 var y =  - ().top;
 ();
 (x,y,10,0,*2);
 for(var i = 0; i < ; i++){
  var temp = dataArr[i];
  if((,)){ 
   = 'red';
  (,,1,1);
  }  
 }
  = 'black'; 
 } 
 //Mouse click  = function(e){
 var r = 20;
 e = e || event;
 var x =  - ().left;
 var y =  - ().top;
 ();
 (x,y,r,0,*2);
 for(var i = 0; i < ; i++){
  var temp = dataArr[i];
  if((,)){ 
   = true;
  var angle = Math.atan2(( - y),( - x));
   = x - r*(angle);
   = y - r*(angle);
  var disX =  - ;
  var disY =  - ;
   = '#fff';
  (,,1,1);
   = '#f00';
  (,,1,1); 
  ="#000";
  dataRecovery(10);
  }else{
   = false;
  }  
 }
 var oTimer = null;
 function dataRecovery(n){
  clearTimeout(oTimer);
  oTimer = setTimeout(function(){
  (0,0,W,H);
  for(var i = 0; i < ; i++){
   var temp = dataArr[i];
   if(){
   var x0 = ;
   var y0 = ;
   var disX =  - x0;
   var disY =  - y0;
   (x0 + disX/n,y0 + disY/n,1,1); 
   }else{
   (,,1,1);
   }
  } 
  dataRecovery(n-1); 
  if(n === 1){
   clearTimeout(oTimer);
  }  
  },17);
 } 
 } 
}
</script> 
</body>
</html>

The above detailed explanation of the construction of the canvas particle system is all the content I share with you. I hope you can give you a reference and I hope you can support me more.