preface

Text is the most basic element in the web page, generally we are displayed on the web page static text, but in terms of the effect, or rather boring. Fading in and out of text animation is very useful in projects, if there are some key text, this dynamic effect can be used to remind the user to read.

Dynamic rendering

This Demo repeatedly set the text size and transparency, these English letters are also drawn by ME using HT vector, in general, the effect is good.

Code implementation

There are about 100 lines of code in total, which is relatively simple. As MENTIONED earlier, I use vector to draw my English letters. Using vector to draw graphics has many advantages, such as image scaling is not distorted, so I don’t need to provide different sizes of images on different Retina displays. There is a JSON way to describe the vector, the format is more concise and so on.

Vector images

Next, draw these vector images (just take out the first H here for illustration) :

{
    "width": 10,// Set the width of vector"height": 10,// Set the vector height"comps"Each Array object is an independent component type. The order of the Array objects is the order in which the components are drawn."type": "text"// Text type"text": "H"// Text content"color": "RGB (69,69,69)"// Text color"align": "center"// The alignment of the text in the vector"opacity": {// Text transparency"func": "[email protected]"// Set the business properties to transparently bind the text"value"If func is empty or undefined, use the value},"clipDirection": "bottom",// The cutting direction is "from top to bottom""rect": [// specifies that the component is drawn in the vector with the rectangle boundary 0,// represents the upper-left coordinate x 0,// represents the upper-left coordinate y 10,// represents the component width 10// represents the component height]}]}Copy the code

Vector graphics are written in JSON format with three main parameters: width, height and comps. All three parameters must be specified, where width is the width of the vector graph, height is the height of the vector graph, comps is an Array, Array is a separate object, you can set some predefined parameters for this object, and some optional parameter information.

Here I store all the text information in an array for easy call:

arr = [
    {label: 'H', image: 'symbols/H.json'},
    {label: 'T', image: 'symbols/T.json'},
    {label: 'f', image: 'symbols/f.json'},
    {label: 'o', image: 'symbols/o.json'},
    {label: 'r', image: 'symbols/r.json'},
    {label: 'W', image: 'symbols/W.json'},
    {label: 'e', image: 'symbols/e.json'},
    {label: 'b', image: 'symbols/b.json'},];Copy the code

The first label object is the name of the vector graphic, and the second image object we set is a JSON-formatted image, but can actually be an IMG, canvas object, or an image URL, or a Base64 string.

Creating a node object

Now that the image of the object has been generated, it is time to create the object. There are 8 letters in the object.

var s = 80;
  arr.forEach(function(obj, index) {
      var text = obj.label;
      name = 't' + text;
      window[name] = createNode(obj.image, 100+s*index, 100);
  });

functionCreateNode (image, x, y) {var node = new ht.node (); // This class is for the node defined in ht node.setsize (0, 0); // Set the node sizeif(image) node.setImage(image); // Set the node imageif(x && y) node.setPosition(x, y); Dm.add (node); // Add the node to the data container datamodelreturn node;
}
Copy the code

As for the hT. Node generation above, this is just an HT-wrapped class with a lot of handy apis. This generated node is then added to the data container DM, which in turn is the data container for the entire topology gV.

Topology generation

Take a look at how to generate this topology:

dm = new ht.DataModel(); // Gv = new ht.graph.graphView (dm); GetView () to get the bottom div of the topology, gv.addtodom (); // Add gV to the bodyCopy the code

In fact, the principle of HT is to draw graphics on a canvas in a div, that is to say, the GV is a canvas.

We then use getView to get the canvas’s underlying div, so we can add it anywhere on the HTML page. AddToDOM is defined as follows:

addToDOM = function(){var self = this, view = self.getView(), // get the bottom div style = view.style; document.body.appendChild(view); // Add the underlying div to the body style.left ='0'; // Set style.right = because HT sets the component's position to absolute by default'0';
    style.top = '0';
    style.bottom = '0';      
    window.addEventListener('resize'.function () { self.iv(); }, false); // A window size change triggers an event that calls the invalidate (iv) function of the outermost component to update. }Copy the code

Now refresh the page and you’ll see a blank. Why? Because the size of the node is set to 0, how can it be displayed? The effect of this Demo is to create from nothing, and from nothing to nothing. Here’s how to start from scratch.

The text animation

As I just said, in order to make the node display, it must be set to the size of the node visible to the naked eye, but my goal is not only to start from nothing, but also from small to large, can this be done in one go? It seems that the code content is simple, but the amount of code is not small. I define a function to grow the node from nothing to large:

function setSize(node) {
    if(node) { var s = 80, size = node.getSize().width; Var sw = s-size; var sw = s-size; Duration: 1000,// Animation cycle milliseconds easing:function(t) { returnT *t},// action:function(v, t) {// The first argument v represents the value of easing(t), and t represents the current progress of the animation [0~1]. Node. setSize(// Set the node size (there is a slow process through sw*v) size + sw*v, size + sw*v); }}); }}Copy the code

The process of going from big to small, from something to nothing is similar, and I won’t go into it.

To make these letters appear and disappear in the order of time, it is necessary to use the setTimeout method. It is very easy to achieve a display disappearance, but I fell into a trap of setTimeout in the process of implementation. I can only say that I am not good at learning it. Since we need to set different appearance and disappearance times for different letters, it is usually easier to set a fixed value and multiply it by the corresponding node-specific index:

function animateIn() {
    for(let i = 0; i < arr.length; i++) {
        var name = 't'+ arr[i]; animateLetterIn(window[name], i); // This section sets the animation}}Copy the code

However, if I set setTimeout to a dynamic value in the for loop, then the dynamic value must be the last value of the for loop, so I extract the setTimeout method as a separate function:

function animateLetterIn(node, i) {
    setTimeout(function() {
        setSize(node); }, i * 200); // Then the I is the node's I instead of the last valueif(I === arr.length-1) {// When the node is the last node, set the node to fade to animationsetTimeout(function() { animateOut(); }, (arr. Length + 3) * 200); }}Copy the code

The node fade-out animation works similarly, except that these animation functions need to be called in a loop so that the size of the letters can be controlled in an infinite loop.