In the drawing page of a mobile terminal before, the display window of the drawing results needed to be displayed in round broadcast. After stepping on some small pits before, I now summarize the realization method of the front barrage effect.

  • Css3 implements beggar version of the barrage
  • Css3 barrage performance optimization
  • Canvas implements barrage
  • Extension of canva barrage

Address of this article: address of this article

1. Css3 implements beggar’s version of the barrage

(1) How to realize barrage through CSS3

First let’s see how to implement the simplest barrage using CSS:

First, define a dom structure of the danmu in HTML:

<div class="block"> </div>Copy the code

The movement of the barrage can be realized by moving this block. Taking the barrage moving from right to left as an example, the initial position of the barrage is at the far left of the container and its edges are hidden (the far left of the barrage fits with the far right of the container), which can be achieved by absolute positioning plus transform:

.block{
   position:absolute;
}
Copy the code

Initial position:

from{
    left:100%;
    transform:translateX(0)
}
Copy the code

Move to the leftmost end position is (the leftmost part of the barrage fits the leftmost part of the container) :

to{
   left:0;
   transform:translateX(-100%)
}
Copy the code

The starting and ending positions are shown as follows:

A complete two-frame barrage animation can be defined according to the start and end positions:

@keyframes barrage{ from{ left:100%; transform:translateX(0); } to{ left:0; transform:translateX(-100%); }}Copy the code

Add this animation to the barrage element:

.block{
  position:absolute;
  /* other decorate style */
  animation:barrage 5s linear 0s;
}
Copy the code

This allows for a beggar’s version of the barrage effect:

(2) The defects of realizing barrage through absolute positioning and left

Let’s first clarify the CSS rendering process

  • I) Generate a DOM tree based on the HTML structure (DOM tree contains display: None nodes)
  • II) on the basis of the DOM tree, node based on geometric properties (margin/padding/width/height/left, etc.) to generate the render tree
  • III) Continue rendering color,font and other attributes on the basis of the Render tree

Reflow occurs if properties in I) and II) change, and repaint occurs only if properties in III) change. This is obvious from the CSS rendering process: reflow must be accompanied by redrawing.

Reflow: When part or all of the render tree changes due to size margins or other issues and needs to be rebuilt, it is called repaint

Reflow can affect the speed of CSS rendering in a browser, so reduce reflow when optimizing web page performance.

In the first section, we realized the effect of the barrage by using the left attribute. Left will change the layout of elements, so reflow will occur, which will cause the lag of the barrage animation on the mobile page.

2. Performance optimization of CSS3 barrage

We have until the first section of the bullet screen animation has a lag problem, let’s look at how to solve the animation lag.

(1) Enable hardware acceleration for the CSS

Enable hardware acceleration with the CSS in the browser and use the Graphics Processing Unit (GPU) to improve web page performance. In view of this, we can harness the power of the GPU to make our website or application behave more smoothly.

CSS animations, Transforms, and Transitions do not automatically turn on GPU acceleration, but are handled by the browser’s slow software rendering engine. How can we switch to GPU mode? Many browsers provide triggering CSS rules.

The most common way is that we can turn on hardware acceleration with a 3D change (translate3D property). For this reason, we modify the animation to:

@keyframes barrage{ from{ left:100%; The transform: translate3d (0, 0); } to{ left:0; The transform: translate3d (100%, 0, 0); }}Copy the code

This allows you to optimize web page performance by enabling hardware acceleration. However, this approach does not fundamentally solve the problem. Meanwhile, the use of GPU increases the use of memory, which will reduce the battery life of mobile devices and so on.

(2) Do not change the left attribute

The second method is to find a way to keep the value of the left property unchanged before and after the barrage animation so that reflow does not occur.

We want to determine the initial position of the bullet screen node only through translateX, but translateX(-100%) is relative to the bullet screen node itself, not to the parent element, so we couple JS and CSS to get the width of the parent element where the bullet screen node is located in JS. Then the initial position of the barrage node is defined according to its width.

For example, if the parent element is body:

//css .block{ position:absolute; left:0; visibility:hidden; /* other decorate style */ animation:barrage 5s linear 0s; } //js let style = document.createElement('style'); document.head.appendChild(style); let width = window.innerWidth; let from = `from { visibility: visible; -webkit-transform: translateX(${width}px); } `; let to = `to { visibility: visible; -webkit-transform: translateX(-100%); } `; style.sheet.insertRule(`@-webkit-keyframes barrage { ${from} ${to} }`, 0);Copy the code

In addition to calculating the width of the parent element by coupling JS to determine the initial position of the bullet-screen node, we add the attribute visibility:hidden in the bullet-screen node to prevent the initial position from being displayed. Prevents projectile barrage nodes from appearing in the parent container without determining their initial location. The barrage becomes visible only when it starts scrolling from its initial position.

However, this CSS implementation is more troublesome in realizing the extended functions of the barrage, such as how to control the suspension of the barrage and so on.

3. Canvas implements danmu

In addition to CSS, bullet barrage can also be implemented through Canvas.

The principle of realizing danmu through Canvas is to redraw text from time to time. The following steps will be implemented step by step.

  • Access to the canvas
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
Copy the code
  • Rendering text
    ctx.font = '20px Microsoft YaHei';          
    ctx.fillStyle = '# 000000';                
    ctx.fillText('Canvas drawn text', x, y);
Copy the code
The fillText above is the main API for realizing the bullet screen effect, where X represents the coordinate of the horizontal direction and Y represents the coordinate of the vertical direction. As long as x is changed from time to time and y is redrawn, dynamic bullet screen effect can be realized.Copy the code
  • Clear drawn content
    ctx.clearRect(0, 0, width, height);
Copy the code
  • The specific implementation

Change x and y regularly through the timer, advance clear the screen before each change, and then redraw according to the changed X and Y. When there are multiple bullets, the definition is as follows:

    letcolorArr=_this.getColor(color); The bullet screen array corresponds to the color arrayletnumArrL=_this.getLeft(); The x coordinate position array corresponding to the barrage arrayletnumArrT=_this.getTop(); The y coordinate position array corresponding to the barrage arrayletspeedArr=_this.getSpeed(); The movement speed array corresponding to the barrage arrayCopy the code

The redraw function of the timed barrage is:

_this. Timer = setInterval (function () {CTX. ClearRect (0, 0, canvas width, canvas. Height); ctx.save(); for(let j=0; j<barrageList.length; j++){ numArrL[j]-=speedArr[j]; ctx.fillStyle = colorArr[j] ctx.fillText(barrageList[j],numArrL[j],numArrT[j]); ctx.restore(); }, 16.7);Copy the code

The results are as follows:

4. Expansion of canva barrage

It is very convenient to use canvas to realize bullet screen, such as suspending the scrolling of bullet screen and other extended functions. In addition, it is also possible to add head pictures to the bullet screen, add borders to each bullet screen and other functions, which will be supplemented later.

Finally, give a simple React cartridge component; https://github.com/forthealllight/react-barrage