Code files

Weekly canvas animation series has been updated 12 articles, today here to give you a benefit. We use canvas to create a small effect. This little effect is what I saw on codePen, and I made some modifications and enhancements to it, adding some new features. The UI should look something like this. We want to achieve the effect of operation as I was in the picture, enter text in the input box (no matter Chinese or English, or a variety of expression or) can be through many particles in the canvas canvas, there are a lot of control in the sidebar, they can control the particle’s properties, so as to form a variety of beautiful effect.

1. Directory structure

2. The UI interface

The COMPOSITION of UI interface is very simple, mainly consists of two parts: sidebar console and Canvas canvas

Copy the code

In the sidebar there are a series of control bars that control the various properties of the particle, including the text input field:

 Copy the code

Control bar

Copy the code

Particle choice

The circular square

Copy the code

In this I do not enumerate! The CSS style file mainly deals with the layout and style of the UI. For details, see the code file.

3. Sidebar swiping

When the menu button is clicked, the sidebar slides out and retracts again. Use classList to switch between sliding out and retracting classes in sidebar.js

var btn = document.getElementById("btn");
var control = document.getElementById("control");

btn.addEventListener('click', function(e){
}, false)Copy the code

So we have our basic interface built. This brings us to the core idea of our animation

4. Preparation

First, we define the variables we need in our index.js file

var canvas = document.getElementById('canvas'); context = canvas.getContext('2d'); W = canvas.width = window.innerWidth; H = canvas.height = window.innerHeight; gridY = 7, gridX = 7; type = "ball"; var message = document.getElementById('message'), gravity = document.getElementById('gra'), duration = document.getElementById('dur'), speed = document.getElementById('speed'), radius = document.getElementById('rad'), resolution = document.getElementById('res'); graVal = parseFloat(gravity.value); durVal = parseFloat(duration.value); spdVal = parseFloat(speed.value); radVal = parseFloat(radius.value); resVal = parseFloat(resolution.value); colors = [ '#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4CAF50', '#8BC34A', '#CDDC39', '#FFEB3B', '#FFC107', '#FF9800', '#FF5722' ]; Function change(){... } function changeV() {... } (function drawFrame(){ window.requestAnimationFrame(drawFrame, canvas); context.clearRect(0, 0, W, H); . } ())Copy the code

Notice the context, W, H, and so on that we’re defining global variables. There are two variables here that you probably don’t know what they are: gridX and gridY, and I’ll go into that later.

5. Shape. Js file

This file is at the heart of our entire animation effect, and only by understanding it can you understand how the effect works. Because it’s not very long, I’ll list the files in full here:

function Shape(x, y, texte){
        this.x = x;
        this.y = y;
        this.size = 200;
        this.text = texte;
        this.placement = [];
Shape.prototype.getValue = function(){
         context.textAlign = "center";
         context.font =  this.size + "px arial";
         context.fillText(this.text, this.x, this.y);

         var idata = context.getImageData(0, 0, W, H);
         var buffer32 = new Uint32Array(;

         for(var j=0; j < H; j += gridY){
             for(var i=0 ; i < W; i += gridX){
                 if(buffer32[j * W + i]){
                     var particle = new Particle(i, j, type);
         context.clearRect(0, 0, W, H);
}Copy the code

Next, I will solve the file code in detail! First we create a new constructor, Shape, which takes three arguments:

  • X, y: Position of text to draw

  • Texte: Text to draw

We set the text size to 200px and define a placement property, which is an array. so wired! What does it do? Don’t worry. Keep going down.

Next we define a method getValue on the prototype object. Here are a few lines:

 context.textAlign = "center";
 context.font =  this.size + "px arial";
 context.fillText(this.text, this.x, this.y);Copy the code

Very simple, set the text to its mode, font size, and draw text on the canvas using fillText(). If you enter text in the control bar, create a shape object in index.js, pass the text in, and then call getValue, you will see that you have drawn the text to the Canvas. Ignore the following code.

To get back to business, we then call context.getimageData (), which is the CANVAS drawing API interface to get the data content of the image to be drawn. You may ask, it is used to get the data content of the image drawn on the canvas, but we are not drawing the image.

In fact, the function of this method is not limited to the content of the image. As long as there is content on the canvas, it can get no matter the text or graph drawn, or even the blank canvas, but the data at this time is 0.

So what does the content look like through the API? First, we try to get the contents of an empty canvas

var canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d');
var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
         console.log(imgData); Copy the code

The results are as follows:

ImgData is an object. The first property of the object is data, which is a typed array of 8-bit unsigned integers in Uint8ClampedArray.

So let’s open up data and see what we have, and I’m just going to open up one of them, okay

Because canvas is empty. So, the data is zero.

Now, let’s switch and draw a blue rectangle on the canvas.

context.fillStyle = "#49f";
context.fillRect(0, 0, canvas.width,canvas.height);
var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
console.log(imgData);Copy the code

Let’s see if our data is not zero anymore!

OK! That’s all I’ve explained here, so let’s get back to it. Look at the next line of code

 var buffer32 = new Uint32Array(;Copy the code

Buffer, where we call the buffer property of the Uint8ClampedArray object to get the ArrayBuffer referenced by this array. It is then passed into the Uint32Array object (a typed array of 32-bit unsigned integer values)(… ,

At this point, let’s see what happens to the blue rectangle above. First, the array length becomes [160000], which is exactly one-fourth of the eight bits above

Content into

So we reduced the resolution of an image, 640,000 data, now we have 16,000 data. Of course, the content of the data is not our concern in this article. All we care about is where the data is.

So, the next step is to put our particles where the data is

for(var j=0; j < H; j += gridY){ for(var i=0 ; i < W; i += gridX){ if(buffer32[j * W + i]){ var particle = new Particle(i, j, type); this.placement.push(particle); } } } context.clearRect(0, 0, W, H); // Clear the drawingCopy the code

We walk through the canvas, buffer32[j * W + I] to determine whether the data at this position is empty, if not, then draw a particle here. The position of the particle is (I, j) and we pass it in as a parameter.

Here we use gridX and gridY, which are used to determine how many distances to take data at a time. Those of you who have taken signal sampling should understand very well that if you have a large interval, you get a small sample, whereas if you have a small interval, you get a large sample. In our effect, we are drawing text, similarly, small interval to obtain more data, more particles, the composition of text is complete. The bigger the interval, the less you get. The particle text is not so complete, and the values of the two variables are bound by the resolution control. To think or on a picture!

6. Particles. Js file

And that file is our particle file, so I’m not going to explain it too much. Don’t know how to welcome questions

7. Particle switching

The code for the particle switch is in slide.js, which simply binds two events

Var ball = document.getelementByid ("ball"); var rect = document.getElementById("rect"); function chose(particleName){ particleName.addEventListener('click', function(e){ = "orange";  (particleName == ball ? rect : ball).style.backgroundColor = "rgba(0, 0, 0, 0)"; type = (type === "ball" ? "rect" : "ball"); change(); }, false) } chose(ball); chose(rect);Copy the code

Ok! The key points of this effect are basically finished, have an interest in yourself to see it!!