Shock, Canvas text particle effect, only 100 lines of code, easy to understand.

Canvas uses JavaScript program to draw (dynamically generated). Compared with CSS, it can draw details more easily and conveniently. One of the most powerful features mo past pixel processing. Pixel by pixel to draw any desired display effect. Next, for the audience grandpa to introduce the text dynamic particle effect, of course, some relatively simple. If you are interested in grandpa, you can expand on this basis

How to draw text particle dynamic effects?

1. Learn about the basic Canvas Api, such as dot drawing, circle drawing and color filling, etc. 2. Break the text and record the position of each text on the canvas, the focus of this paper. 3. Generate random particles and set the trajectory of each particle. 4. Move to Step 2 and record the position. 5. Use requestAnimationFrame to draw the canvas for each frame. Stamp here)

It’s as simple as that, with 100 lines of code, you can learn simple text dynamics

The source code parsing

Master generated canvas

Understand the basic Canvas API, why so lazy !!!! And I need an address. Stamp here)

To obtain the text location information, but do not want the user to see, this needs to use two canvases, the following is to create the main canvas, set the size of the canvas.

   let WIDTH,HEIGHT,cxt,raf,points;
   window.onload = () => {
       WIDTH = document.body.clientWidth;
       HEIGHT = document.body.clientHeight;
       const canvas =  document.getElementById('canvas'); // Canvas. Width = width; canvas.height = HEIGHT; ctx = canvas.getContext('2d'); points = createViceCanvas(); // Create a subcanvas, write out the text you want to display, and get the text position information. init() }Copy the code

Generate secondary canvas

Create a subcanvas and write the text you want to display inside. Get the position of the text particle. Note that the size of the main canvas and the secondary canvas must be the same, so that the points in the secondary canvas can be correctly displayed in the main canvas. Once the secondary canvas is created, it does not need to be added to the DOM. So here WE have the word WWW,

function createViceCanvas() {
    const viceCanvas = document.createElement('canvas')
    viceCanvas.width = WIDTH;
    viceCanvas.height = HEIGHT;
    let viceCxt = viceCanvas.getContext('2d')
    initCanvas(viceCxt)
    returngetFontInfo(viceCxt); // Get the position of the text particle}functionInitCanvas (CTX){// CTX is a secondary canvas const font ='www'
    ctx.font = '200px Arial';
    const measure =  ctx.measureText(font)
    ctx.fillText(font, (WIDTH - measure.width) / 2, HEIGHT / 2);
}

Copy the code

The measureText method is used here to get the width of the text in order to be able to draw text in the middle of the canvas. High center, interested can try their own.

Get text position information

How do I get the position of text? Lesson begins. Highlight.

functionGetFontInfo (CTX) {// CTX is a subcanvas, and the text takes points to get the coordinates of each text in the canvas.letImageData = CTX. GetImageData (0, 0, WIDTH, HEIGHT). The data; const particles = [];for(let x = 0; x < WIDTH; x += 4) {
        for(let y=0; y < HEIGHT; y += 4) {
            const fontIndex = (x + y * WIDTH) * 4 + 3;
            if(imageData[fontIndex] > 0) {
                particles.push(new Particle({
                    x,
                    y,
                }))
            }
        }
    }
    return particles;
}
Copy the code

The data property returns a Uint8ClampedArray, which can be used to view initial pixel data. Each pixel uses four 1bytes values (in order of red, green, blue, and transparent values; This is the “RGBA” format) to represent. Part of each color value is represented by 0 to 255. Each portion is assigned a contiguous index in the array, with the red portion of the upper-left pixel at index 0. Pixels are processed from left to right, and then down, traversing the entire array

The size of the canvas I’m using here is 1080 by 768, represented in coordinates 1080 on the x axis, 768 on the y axis

In fact, RGBA(255,255,255,0) these four similar numbers represent a pixel, so the canvas 1080*768 is represented by the Uint8ClampedArray array, how many elements in total? It’s 1080 times 768 times 4 elements

A crude coordinate diagram is drawn below.

For example, the position of x axis (1,1) needs to be represented by the first four bits of the Uint8ClampedArray array, while the position of x axis (2,1) needs to be represented by the elements of the Uint8ClampedArray index 4-7. Uint8ClampedArray index is (1080*(2-1) + (1-1)) * 4-1. Width *(n-1) + m-1)) * 4 -1 If you don’t understand, grandpa can taste it slowly. ~~~~~

Here’s another trick, rGBA for color, fourth element for transparency, and fourth element bit 0 when we don’t draw anything on the canvas. Const fontIndex = (x + y * WIDTH) * 4 + 3; const fontIndex = (x + y * WIDTH) * 4 + 3;

The trajectory of each particle

The above step obtained the position of the text particle in the canvas. The effect we want is particle animation, so we need to randomly generate a particle and then move to the corresponding position of the obtained text.

class Particle { constructor(center) { this.x = center.x; // This. Y = center. Y; // This. Item = 0; // This. Vx = 20; // This. Vy = 16; This.initx = math.random () * WIDTH; this.initx = math.random () * WIDTH; // this. InitY = math.random () * HEIGHT; // Point random y coordinates in the canvas}draw(){// Draw the dot ctx.beginPath(); Const {x, y} = threeBezier(const {x, y} = threeBezier) This. Item, [this.x,this. Y], [this.x,this. Y]) ctx.arc(x, y, this. 2, 0, 2 * Math.PI,true);
           ctx.fillStyle="red"ctx.fill(); ctx.closePath(); this.speed(); // Next tick drawing coordinates}speed() {this.initx +=this.vx; this.initY +=this.vy; This. The item + = 0.005; }}Copy the code

Here, a random particle is needed to make the move and to form a text whose final position we have already obtained, which is the constructor parameter Center. So how does the particle move? I’m using bezier curves here and encapsulating them into a method.

const threeBezier = (t, p1, p2, cp1, cp2) => {
       const [startX,startY] = p1;
       const [endX,endY] = p2;
       const [cpX1,cpY1] = cp1;
       const [cpX2,cpY2] = cp2
       let x = startX * Math.pow(1-t,3) +
               3 * cpX1 * t * Math.pow(1-t,2) +
               3 * cpX2 * Math.pow(t,2) * (1-t) + 
               endX * Math.pow(t,3);
       let y = startY * Math.pow(1-t,3) +
               3 * cpY1 * Math.pow(1-t,2) * t + 
               3 * cpY2 *(1- t) * Math.pow(t,2) + 
               endY * Math.pow(t,3)
       return {
           x,
           y,
       }
   }
Copy the code

Simple description of parameters

T: Bezier curve coefficient, before 0-1. P1: Starting point of trajectory movement. P2: end point of trajectory movement. Cp1: the first control point. Cp2: The second control point. The fourth and fifth parameters can be passed blindly, mainly to control the trajectory of the motion, but the two parameters p1 and P2 should not be messed up, especially P2. P2 if blind chicken spread, still want to form a text?

What, don’t understand the Bezier curve? Not here?)

Extension: If you want the text to be colorful, you can get the text coordinates

particles.push(new Particle({
           x,
           y,
       }))
Copy the code

Add a color to the constructor at random, assigning the color passed in when the Draw method in Particle draws.

Start the animation

The text position and particle movement track have been determined. Now how to start animation? How do I pause animation?

function init() {
    ctx.clearRect(0,0,WIDTH,HEIGHT)
    points.forEach((value) => { //
        value.draw();
    })
    raf = window.requestAnimationFrame(init)
    if(points[0].item>=1){
        window.cancelAnimationFrame(raf)
    }
}
Copy the code

CancelAnimationFrame Cancels the animation after the requestAnimationFrame. Be sure to execute cancelAnimationFrame before recursively calling the init method. Don’t forget that requestAnimationFrame is asynchronous ~~~~

conclusion

This is the end of the canvas text particle effect for today’s introduction. If you have any questions, please leave a comment below.

❤️ if you see the officer see also, please give a thumbs-up, conveniently point a concern, is the biggest support for me

Oh, I forgot the source address. Stamp here